diff --git a/substrate/demo/primitives/src/transaction.rs b/substrate/demo/primitives/src/transaction.rs
index 6f4feab790e4e5e7bde262052d77c6a57d7c124b..090b64b27d60203135464bfd3238d456c8fe9cec 100644
--- a/substrate/demo/primitives/src/transaction.rs
+++ b/substrate/demo/primitives/src/transaction.rs
@@ -44,10 +44,6 @@ enum InternalFunctionId {
 	StakingSetValidatorCount = 0x22,
 	/// Force a new staking era.
 	StakingForceNewEra = 0x23,
-
-	/// Set the per-mille of validator approval required for governance changes.
-	GovernanceSetApprovalPpmRequired = 0x30,
-
 }
 
 impl InternalFunctionId {
@@ -61,7 +57,6 @@ impl InternalFunctionId {
 			InternalFunctionId::StakingSetBondingDuration,
 			InternalFunctionId::StakingSetValidatorCount,
 			InternalFunctionId::StakingForceNewEra,
-			InternalFunctionId::GovernanceSetApprovalPpmRequired,
 		];
 		functions.iter().map(|&f| f).find(|&f| value == f as u8)
 	}
@@ -85,9 +80,6 @@ pub enum Proposal {
 	StakingSetValidatorCount(u32),
 	/// Force a new staking era.
 	StakingForceNewEra,
-	/// Set the per-mille of validator approval required for governance changes.
-	GovernanceSetApprovalPpmRequired(u32),
-
 }
 
 impl Slicable for Proposal {
@@ -106,8 +98,6 @@ impl Slicable for Proposal {
 			InternalFunctionId::StakingSetValidatorCount =>
 				Proposal::StakingSetValidatorCount(try_opt!(Slicable::decode(input))),
 			InternalFunctionId::StakingForceNewEra => Proposal::StakingForceNewEra,
-			InternalFunctionId::GovernanceSetApprovalPpmRequired =>
-				Proposal::GovernanceSetApprovalPpmRequired(try_opt!(Slicable::decode(input))),
 		};
 
 		Some(function)
@@ -142,10 +132,6 @@ impl Slicable for Proposal {
 			Proposal::StakingForceNewEra => {
 				(InternalFunctionId::StakingForceNewEra as u8).using_encoded(|s| v.extend(s));
 			}
-			Proposal::GovernanceSetApprovalPpmRequired(ref data) => {
-				(InternalFunctionId::GovernanceSetApprovalPpmRequired as u8).using_encoded(|s| v.extend(s));
-				data.using_encoded(|s| v.extend(s));
-			}
 		}
 
 		v
@@ -167,10 +153,6 @@ enum FunctionId {
 	StakingUnstake = 0x21,
 	/// Staking subsystem: transfer stake.
 	StakingTransfer = 0x22,
-	/// Make a proposal for the governance system.
-	GovernancePropose = 0x30,
-	/// Approve a proposal for the governance system.
-	GovernanceApprove = 0x31,
 }
 
 impl FunctionId {
@@ -179,7 +161,7 @@ impl FunctionId {
 		use self::*;
 		let functions = [FunctionId::StakingStake, FunctionId::StakingUnstake,
 			FunctionId::StakingTransfer, FunctionId::SessionSetKey, FunctionId::TimestampSet,
-			FunctionId::GovernancePropose, FunctionId::GovernanceApprove];
+			];
 		functions.iter().map(|&f| f).find(|&f| value == f as u8)
 	}
 }
@@ -198,10 +180,6 @@ pub enum Function {
 	StakingUnstake,
 	/// Staking subsystem: transfer stake.
 	StakingTransfer(::AccountId, u64),
-	/// Make a proposal for the governance system.
-	GovernancePropose(Proposal),
-	/// Approve a proposal for the governance system.
-	GovernanceApprove(BlockNumber),
 }
 
 impl Slicable for Function {
@@ -220,10 +198,6 @@ impl Slicable for Function {
 
 				Function::StakingTransfer(to, amount)
 			}
-			FunctionId::GovernancePropose =>
-				Function::GovernancePropose(try_opt!(Slicable::decode(input))),
-			FunctionId::GovernanceApprove =>
-				Function::GovernanceApprove(try_opt!(Slicable::decode(input))),
 		})
 	}
 
@@ -249,14 +223,6 @@ impl Slicable for Function {
 				to.using_encoded(|s| v.extend(s));
 				amount.using_encoded(|s| v.extend(s));
 			}
-			Function::GovernancePropose(ref data) => {
-				(FunctionId::GovernancePropose as u8).using_encoded(|s| v.extend(s));
-				data.using_encoded(|s| v.extend(s));
-			}
-			Function::GovernanceApprove(ref data) => {
-				(FunctionId::GovernanceApprove as u8).using_encoded(|s| v.extend(s));
-				data.using_encoded(|s| v.extend(s));
-			}
 		}
 
 		v
diff --git a/substrate/demo/runtime/src/dispatch.rs b/substrate/demo/runtime/src/dispatch.rs
index 6b03667ff909b030e28debb1e69774a7343c27d3..b473a6a8781541402c7ef3500d36264f0674f521 100644
--- a/substrate/demo/runtime/src/dispatch.rs
+++ b/substrate/demo/runtime/src/dispatch.rs
@@ -17,7 +17,7 @@
 //! Democratic system: Handles administration of general stakeholder voting.
 
 use demo_primitives::Proposal;
-use runtime::{staking, system, session, governance};
+use runtime::{staking, system, session};
 
 pub fn enact_proposal(proposal: Proposal) {
 	match proposal {
@@ -42,8 +42,5 @@ pub fn enact_proposal(proposal: Proposal) {
 		Proposal::StakingForceNewEra => {
 			staking::privileged::force_new_era()
 		}
-		Proposal::GovernanceSetApprovalPpmRequired(value) => {
-			governance::privileged::set_approval_ppm_required(value);
-		}
 	}
 }
diff --git a/substrate/demo/runtime/src/runtime/council_vote.rs b/substrate/demo/runtime/src/runtime/council_vote.rs
new file mode 100644
index 0000000000000000000000000000000000000000..394316a66ea0b3e2df1d0e8bd89fb7451bc10985
--- /dev/null
+++ b/substrate/demo/runtime/src/runtime/council_vote.rs
@@ -0,0 +1,169 @@
+// Copyright 2017 Parity Technologies (UK) Ltd.
+// This file is part of Substrate Demo.
+
+// Substrate Demo is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate Demo is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Substrate Demo.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Council voting system.
+
+use rstd::prelude::*;
+use codec::{KeyedVec, Slicable, Input, NonTrivialSlicable};
+use runtime_support::Hashable;
+use runtime_support::storage;
+use demo_primitives::{Proposal, AccountId, Hash, BlockNumber};
+use runtime::{system, democracy, council};
+use runtime::staking::Balance;
+
+type ProposalHash = [u8; 32];
+
+pub const COOLOFF_PERIOD: &[u8] = b"cov:cooloff";		// BlockNumber
+pub const VOTING_PERIOD: &[u8] = b"cov:period";			// BlockNumber
+
+pub const PROPOSALS: &[u8] = b"cov:prs";				// Vec<(expiry: BlockNumber, ProposalHash)> ordered by expiry.
+pub const PROPOSAL_OF: &[u8] = b"cov:pro";				// ProposalHash -> Proposal
+pub const PROPOSAL_VOTERS: &[u8] = b"cov:voters:";		// ProposalHash -> Vec<AccountId>
+pub const COUNCIL_VOTE_OF: &[u8] = b"cov:vote:";		// (ProposalHash, AccountId) -> bool
+pub const VETOED_PROPOSAL: &[u8] = b"cov:veto:";		// ProposalHash -> (BlockNumber, Vec<AccountId>)
+
+pub fn cooloff_period() -> BlockNumber {
+	storage::get(COOLOFF_PERIOD).expect("all parameters must be defined")
+}
+
+pub fn voting_period() -> BlockNumber {
+	storage::get(VOTING_PERIOD).expect("all parameters must be defined")
+}
+
+pub fn proposals() -> Vec<(BlockNumber, ProposalHash)> {
+	storage::get_or_default(PROPOSALS)
+}
+
+pub fn was_vetoed(proposal: &ProposalHash) -> bool {
+	storage::exists(&proposal.to_keyed_vec(VETOED_PROPOSAL))
+}
+
+pub fn will_still_be_councillor_at(who: &AccountId, n: BlockNumber) -> bool {
+	council::active_council().iter()
+		.find(|&&(ref a, _)| a == who)
+		.map(|&(_, expires)| expires > n)
+		.unwrap_or(false)
+}
+
+pub fn vote_of(who: &AccountId, proposal: &ProposalHash) -> Option<bool> {
+	storage::get(&(*who, *proposal).to_keyed_vec(COUNCIL_VOTE_OF))
+}
+
+pub fn take_vote_of(who: &AccountId, proposal: &ProposalHash) -> Option<bool> {
+	storage::get(&(*who, *proposal).to_keyed_vec(COUNCIL_VOTE_OF))
+}
+
+pub fn tally(proposal_hash: &ProposalHash) -> (u32, u32, u32) {
+	generic_tally(proposal_hash, vote_of)
+}
+
+fn take_tally(proposal_hash: &ProposalHash) -> (u32, u32, u32) {
+	generic_tally(proposal_hash, take_vote_of)
+}
+
+fn generic_tally<F: Fn(&AccountId, &ProposalHash) -> Option<bool>>(proposal_hash: &ProposalHash, vote_of: F) -> (u32, u32, u32) {
+	let c = council::active_council();
+	let (approve, reject) = c.iter()
+		.filter_map(|&(ref a, _)| vote_of(a, proposal_hash))
+		.map(|approve| if approve { (1, 0) } else { (0, 1) })
+		.fold((0, 0), |(a, b), (c, d)| (a + c, b + d));
+	(approve, reject, c.len() as u32 - approve - reject)
+}
+
+fn set_proposals(p: &Vec<(BlockNumber, ProposalHash)>) {
+	storage::put(PROPOSALS, p)
+}
+
+fn take_proposal_if_expiring_at(n: BlockNumber) -> Option<(Proposal, ProposalHash)> {
+	let mut proposals = proposals();
+	match proposals.first() {
+		Some(&(expiry, hash)) if expiry == n => {
+			// yes this is horrible, but fixing it will need substantial work in storage.
+			set_proposals(&proposals[1..].to_vec());
+			let proposal = storage::take(&hash.to_keyed_vec(PROPOSAL_OF)).expect("all queued proposal hashes must have associated proposals");
+			Some((proposal, hash))
+		}
+		_ => None,
+	}
+}
+
+pub mod public {
+	use super::*;
+
+	pub fn propose(signed: &AccountId, proposal: &Proposal) {
+		let expiry = system::block_number() + voting_period();
+		assert!(will_still_be_councillor_at(signed, expiry));
+
+		let proposal_hash = proposal.blake2_256();
+		assert!(!was_vetoed(&proposal_hash));
+
+		let mut proposals = proposals();
+		proposals.push((expiry, proposal_hash));
+		proposals.sort_by_key(|&(expiry, _)| expiry);
+		set_proposals(&proposals);
+
+		storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_OF), proposal);
+		storage::put(&proposal_hash.to_keyed_vec(PROPOSAL_VOTERS), &vec![*signed]);
+		storage::put(&(proposal_hash, *signed).to_keyed_vec(COUNCIL_VOTE_OF), &true);
+	}
+
+	pub fn vote(signed: AccountId, proposal: &ProposalHash, approve: bool) {
+
+	}
+
+	pub fn veto(signed: AccountId, proposal: &ProposalHash) {
+
+	}
+
+	pub fn repropose(signed: AccountId, proposal: &Proposal) {
+
+	}
+}
+
+pub mod privileged {
+	use super::*;
+
+	pub fn set_cooloff_period(blocks: BlockNumber) {
+		storage::put(COOLOFF_PERIOD, &blocks);
+	}
+
+	pub fn set_voting_period(blocks: BlockNumber) {
+		storage::put(VOTING_PERIOD, &blocks);
+	}
+}
+
+pub mod internal {
+	use super::*;
+	use runtime::democracy::VoteThreshold;
+	use runtime::democracy::privileged::start_referendum;
+
+	pub fn end_block(now: BlockNumber) {
+		while let Some((proposal, proposal_hash)) = take_proposal_if_expiring_at(now) {
+			let tally = take_tally(&proposal_hash);
+			let vote_threshold = match tally.0 {
+				x if x == tally.2 => VoteThreshold::SuperMajorityAgainst,
+				x if x > tally.2 / 2 => VoteThreshold::SimpleMajority,
+				_ => VoteThreshold::SuperMajorityApprove,
+			};
+			start_referendum(proposal, vote_threshold);
+		}
+	}
+}
+
+#[cfg(test)]
+mod tests {
+
+}
diff --git a/substrate/demo/runtime/src/runtime/democracy.rs b/substrate/demo/runtime/src/runtime/democracy.rs
index 36965153498923cb257ffb245dcc1f9c0cc94e91..cbc82f458dfc4d7f8ade6d1befb6a624953c677d 100644
--- a/substrate/demo/runtime/src/runtime/democracy.rs
+++ b/substrate/demo/runtime/src/runtime/democracy.rs
@@ -76,11 +76,6 @@ pub const DEPOSIT_OF: &[u8] = b"dem:dep:";			// PropIndex -> (Balance, Vec<Accou
 pub const LAUNCH_PERIOD: &[u8] = b"dem:lau";		// BlockNumber
 pub const MINIMUM_DEPOSIT: &[u8] = b"dem:min";		// Balance
 
-// council proposals
-pub const COUNCIL_PROPOSAL: &[u8] = b"dem:cou:pro";	// (BlockNumber, Proposal)
-pub const COUNCIL_VOTE_OF: &[u8] = b"dem:cou:vot:";	// AccountId -> CouncilVote
-pub const COUNCIL_VOTERS: &[u8] = b"dem:cou:vts";	// Vec<AccountId>
-
 // referenda
 pub const VOTING_PERIOD: &[u8] = b"dem:per";		// BlockNumber
 pub const REFERENDUM_COUNT: &[u8] = b"dem:rco";		// ReferendumIndex
diff --git a/substrate/demo/runtime/src/runtime/governance.rs b/substrate/demo/runtime/src/runtime/governance.rs
deleted file mode 100644
index 4689941de4c40a5bf005c2f8196371cdc980fa14..0000000000000000000000000000000000000000
--- a/substrate/demo/runtime/src/runtime/governance.rs
+++ /dev/null
@@ -1,339 +0,0 @@
-// Copyright 2017 Parity Technologies (UK) Ltd.
-// This file is part of Substrate Demo.
-
-// Substrate Demo is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate Demo is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Substrate Demo.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Governance system: Handles administration and dispatch of sensitive operations including
-//! setting new code, minting new tokens and changing parameters.
-//!
-//! For now this is limited to a simple qualified majority vote (whose parameter is retrieved from
-//! storage) between validators. A single vote may be proposed per era, and at most one approval
-//! vote may be cast by each validator. The tally is maintained through a simple tag in storage for
-//! each validator that has approved.
-//!
-//! At the end of the era, all validators approvals are tallied and if there are sufficient to pass
-//! the proposal then it is enacted. All items in storage concerning the proposal are reset.
-
-use rstd::prelude::*;
-use codec::KeyedVec;
-use runtime_support::storage;
-use demo_primitives::{Proposal, AccountId, Hash, BlockNumber};
-use runtime::{staking, system, session};
-use dispatch::enact_proposal;
-
-pub const APPROVALS_REQUIRED: &[u8] = b"gov:apr";
-pub const CURRENT_PROPOSAL: &[u8] = b"gov:pro";
-pub const APPROVAL_OF: &[u8] = b"gov:app:";
-
-/// The proportion of validators required for a propsal to be approved measured as the number out
-/// of 1000.
-pub fn approval_ppm_required() -> u32 {
-	storage::get_or(APPROVALS_REQUIRED, 1000)
-}
-
-/// The number of concrete validator approvals required for a proposal to pass.
-pub fn approvals_required() -> u32 {
-	approval_ppm_required() * session::validator_count() / 1000
-}
-
-pub mod public {
-	use super::*;
-
-	/// Propose a sensitive action to be taken. Any action that is enactable by `Proposal` is valid.
-	/// Proposal is by the `transactor` and will automatically count as an approval. Transactor must
-	/// be a current validator. It is illegal to propose when there is already a proposal in effect.
-	pub fn propose(validator: &AccountId, proposal: &Proposal) {
-		if storage::exists(CURRENT_PROPOSAL) {
-			panic!("there may only be one proposal per era.");
-		}
-		storage::put(CURRENT_PROPOSAL, proposal);
-		approve(validator, staking::current_era());
-	}
-
-	/// Approve the current era's proposal. Transactor must be a validator. This may not be done more
-	/// than once for any validator in an era.
-	pub fn approve(validator: &AccountId, era_index: BlockNumber) {
-		if era_index != staking::current_era() {
-			panic!("approval vote applied on non-current era.")
-		}
-		if !storage::exists(CURRENT_PROPOSAL) {
-			panic!("there must be a proposal in order to approve.");
-		}
-		if session::validators().into_iter().position(|v| &v == validator).is_none() {
-			panic!("transactor must be a validator to approve.");
-		}
-		let key = validator.to_keyed_vec(APPROVAL_OF);
-		if storage::exists(&key) {
-			panic!("transactor may not approve a proposal twice in one era.");
-		}
-		storage::put(&key, &true);
-	}
-}
-
-pub mod privileged {
-	use super::*;
-
-	/// Set the proportion of validators that must approve for a proposal to be enacted at the end of
-	/// its era. The value, `ppm`, is measured as a fraction of 1000 rounded down to the nearest whole
-	/// validator. `1000` would require the approval of all validators; `667` would require two-thirds
-	/// (or there abouts) of validators.
-	pub fn set_approval_ppm_required(ppm: u32) {
-		storage::put(APPROVALS_REQUIRED, &ppm);
-	}
-}
-
-pub mod internal {
-	use super::*;
-	use demo_primitives::Proposal;
-
-	/// Current era is ending; we should finish up any proposals.
-	pub fn end_of_an_era() {
-		// tally up votes for the current proposal, if any. enact if there are sufficient approvals.
-		if let Some(proposal) = storage::take::<Proposal>(CURRENT_PROPOSAL) {
-			let approvals_required = approvals_required();
-			let approved = session::validators().into_iter()
-				.filter_map(|v| storage::take::<bool>(&v.to_keyed_vec(APPROVAL_OF)))
-				.take(approvals_required as usize)
-				.count() as u32;
-			if approved == approvals_required {
-				enact_proposal(proposal);
-			}
-		}
-	}
-}
-
-#[cfg(test)]
-pub mod testing {
-	use super::*;
-	use runtime_io::{twox_128, TestExternalities};
-	use codec::Joiner;
-
-	pub fn externalities(session_length: u64, sessions_per_era: u64, current_era: u64) -> TestExternalities {
-		let extras: TestExternalities = map![
-			twox_128(APPROVALS_REQUIRED).to_vec() => vec![].and(&667u32)
-		];
-		staking::testing::externalities(session_length, sessions_per_era, current_era)
-			.into_iter().chain(extras.into_iter()).collect()
-	}
-}
-
-#[cfg(test)]
-mod tests {
-	use super::*;
-	use runtime_io::{with_externalities, twox_128, TestExternalities};
-	use codec::{KeyedVec, Joiner};
-	use keyring::Keyring;
-	use environment::with_env;
-	use demo_primitives::{AccountId, Proposal};
-	use runtime::{staking, session};
-
-	fn new_test_ext() -> TestExternalities {
-		testing::externalities(1, 1, 1)
-	}
-
-	#[test]
-	fn majority_voting_should_work() {
-		let one = Keyring::One.to_raw_public();
-		let two = Keyring::Two.to_raw_public();
-		let three = [3u8; 32];
-		let mut t = new_test_ext();
-
-		with_externalities(&mut t, || {
-			assert_eq!(staking::era_length(), 1u64);
-			assert_eq!(staking::current_era(), 1u64);
-			assert_eq!(session::validator_count(), 3u32);
-			assert_eq!(session::validators(), vec![one.clone(), two.clone(), three.clone()]);
-			assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
-
-			// Block 1: Make proposal. Approve it. Era length changes.
-			with_env(|e| e.block_number = 1);
-			public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
-			public::approve(&two, 1);
-			staking::internal::check_new_era();
-			assert_eq!(staking::era_length(), 2);
-		});
-	}
-
-	#[test]
-	fn majority_voting_should_work_after_unsuccessful_previous() {
-		let one = Keyring::One.to_raw_public();
-		let two = Keyring::Two.to_raw_public();
-		let three = [3u8; 32];
-		let mut t = new_test_ext();
-
-		with_externalities(&mut t, || {
-			assert_eq!(staking::era_length(), 1u64);
-			assert_eq!(staking::current_era(), 1u64);
-			assert_eq!(session::validator_count(), 3u32);
-			assert_eq!(session::validators(), vec![one.clone(), two.clone(), three.clone()]);
-			assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
-
-			// Block 1: Make proposal. Fail it.
-			with_env(|e| e.block_number = 1);
-			public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
-			staking::internal::check_new_era();
-			assert_eq!(staking::era_length(), 1);
-
-			// Block 2: Make proposal. Approve it. It should change era length.
-			with_env(|e| e.block_number = 2);
-			public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
-			public::approve(&two, 2);
-			staking::internal::check_new_era();
-			assert_eq!(staking::era_length(), 2);
-		});
-	}
-
-	#[test]
-	fn minority_voting_should_not_succeed() {
-		let one = Keyring::One.to_raw_public();
-		let two = Keyring::Two.to_raw_public();
-		let three = [3u8; 32];
-		let mut t = new_test_ext();
-
-		with_externalities(&mut t, || {
-			assert_eq!(staking::era_length(), 1u64);
-			assert_eq!(staking::current_era(), 1u64);
-			assert_eq!(session::validator_count(), 3u32);
-			assert_eq!(session::validators(), vec![one.clone(), two.clone(), three.clone()]);
-			assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
-
-			// Block 1: Make proposal. Will have only 1 vote. No change.
-			with_env(|e| e.block_number = 1);
-			public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
-			staking::internal::check_new_era();
-			assert_eq!(staking::era_length(), 1);
-		});
-	}
-
-	#[test]
-	#[should_panic]
-	fn old_voting_should_be_illegal() {
-		let one = Keyring::One.to_raw_public();
-		let two = Keyring::Two.to_raw_public();
-		let three = [3u8; 32];
-		let mut t = new_test_ext();
-
-		with_externalities(&mut t, || {
-			assert_eq!(staking::era_length(), 1u64);
-			assert_eq!(staking::current_era(), 1u64);
-			assert_eq!(session::validator_count(), 3u32);
-			assert_eq!(session::validators(), vec![one.clone(), two.clone(), three.clone()]);
-			assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
-
-			// Block 1: Make proposal. Will have only 1 vote. No change.
-			with_env(|e| e.block_number = 1);
-			public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
-			public::approve(&two, 0);
-			staking::internal::check_new_era();
-			assert_eq!(staking::era_length(), 1);
-		});
-	}
-
-	#[test]
-	#[should_panic]
-	fn double_voting_should_be_illegal() {
-		let one = Keyring::One.to_raw_public();
-		let two = Keyring::Two.to_raw_public();
-		let three = [3u8; 32];
-		let mut t = new_test_ext();
-
-		with_externalities(&mut t, || {
-			assert_eq!(staking::era_length(), 1u64);
-			assert_eq!(staking::current_era(), 1u64);
-			assert_eq!(session::validator_count(), 3u32);
-			assert_eq!(session::validators(), vec![one.clone(), two.clone(), three.clone()]);
-			assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
-
-			// Block 1: Make proposal. Will have only 1 vote. No change.
-			with_env(|e| e.block_number = 1);
-			public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
-			public::approve(&two, 1);
-			public::approve(&two, 1);
-			staking::internal::check_new_era();
-			assert_eq!(staking::era_length(), 1);
-		});
-	}
-
-	#[test]
-	#[should_panic]
-	fn over_proposing_should_be_illegal() {
-		let one = Keyring::One.to_raw_public();
-		let two = Keyring::Two.to_raw_public();
-		let three = [3u8; 32];
-		let mut t = new_test_ext();
-
-		with_externalities(&mut t, || {
-			assert_eq!(staking::era_length(), 1u64);
-			assert_eq!(staking::current_era(), 1u64);
-			assert_eq!(session::validator_count(), 3u32);
-			assert_eq!(session::validators(), vec![one.clone(), two.clone(), three.clone()]);
-			assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
-
-			// Block 1: Make proposal. Will have only 1 vote. No change.
-			with_env(|e| e.block_number = 1);
-			public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
-			public::propose(&two, &Proposal::StakingSetSessionsPerEra(2));
-			staking::internal::check_new_era();
-			assert_eq!(staking::era_length(), 1);
-		});
-	}
-
-	#[test]
-	#[should_panic]
-	fn approving_without_proposal_should_be_illegal() {
-		let one = Keyring::One.to_raw_public();
-		let two = Keyring::Two.to_raw_public();
-		let three = [3u8; 32];
-		let mut t = new_test_ext();
-
-		with_externalities(&mut t, || {
-			assert_eq!(staking::era_length(), 1u64);
-			assert_eq!(staking::current_era(), 1u64);
-			assert_eq!(session::validator_count(), 3u32);
-			assert_eq!(session::validators(), vec![one.clone(), two.clone(), three.clone()]);
-			assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
-
-			// Block 1: Make proposal. Will have only 1 vote. No change.
-			with_env(|e| e.block_number = 1);
-			public::approve(&two, 1);
-			staking::internal::check_new_era();
-			assert_eq!(staking::era_length(), 1);
-		});
-	}
-
-	#[test]
-	#[should_panic]
-	fn non_validator_approving_should_be_illegal() {
-		let one = Keyring::One.to_raw_public();
-		let two = Keyring::Two.to_raw_public();
-		let three = [3u8; 32];
-		let four = [4u8; 32];
-		let mut t = new_test_ext();
-
-		with_externalities(&mut t, || {
-			assert_eq!(staking::era_length(), 1u64);
-			assert_eq!(staking::current_era(), 1u64);
-			assert_eq!(session::validator_count(), 3u32);
-			assert_eq!(session::validators(), vec![one.clone(), two.clone(), three.clone()]);
-			assert!(!session::validators().into_iter().position(|v| &v == &one).is_none());
-
-			// Block 1: Make proposal. Will have only 1 vote. No change.
-			with_env(|e| e.block_number = 1);
-			public::propose(&one, &Proposal::StakingSetSessionsPerEra(2));
-			public::approve(&four, 1);
-			staking::internal::check_new_era();
-			assert_eq!(staking::era_length(), 1);
-		});
-	}
-}
diff --git a/substrate/demo/runtime/src/runtime/mod.rs b/substrate/demo/runtime/src/runtime/mod.rs
index 092b4eca2386cfc1b78aafdb6a939df399ccc3b1..e52e49c8aa13bd7c4e9697ed7244f9309760cbf6 100644
--- a/substrate/demo/runtime/src/runtime/mod.rs
+++ b/substrate/demo/runtime/src/runtime/mod.rs
@@ -27,11 +27,8 @@ pub mod timestamp;
 #[allow(unused)]
 pub mod session;
 #[allow(unused)]
-pub mod governance;
-#[allow(unused)]
 pub mod democracy;
 #[allow(unused)]
 pub mod council;
-
-
-// TODO: polkadao
+#[allow(unused)]
+pub mod council_vote;
diff --git a/substrate/demo/runtime/src/runtime/staking.rs b/substrate/demo/runtime/src/runtime/staking.rs
index 6d357a52dac05ea697c5f9285ecdf15eef45d288..29b6ab793b296febd103aacb4d9620cf28fdb898 100644
--- a/substrate/demo/runtime/src/runtime/staking.rs
+++ b/substrate/demo/runtime/src/runtime/staking.rs
@@ -23,7 +23,7 @@ use runtime_io::{print, blake2_256};
 use codec::KeyedVec;
 use runtime_support::{storage, StorageVec};
 use demo_primitives::{BlockNumber, AccountId};
-use runtime::{system, session, governance};
+use runtime::{system, session};
 
 /// The balance of an account.
 pub type Balance = u64;
@@ -406,9 +406,6 @@ pub mod internal {
 /// NOTE: This always happens immediately before a session change to ensure that new validators
 /// get a chance to set their session keys.
 fn new_era() {
-	// Inform governance module that it's the end of an era
-	governance::internal::end_of_an_era();
-
 	// Increment current era.
 	storage::put(CURRENT_ERA, &(current_era() + 1));
 
diff --git a/substrate/demo/runtime/src/runtime/system.rs b/substrate/demo/runtime/src/runtime/system.rs
index 009dac823902d57e6c15f18be732eeea74c8a29e..765e29e01ec5bb2facb5f3adf3f86abc7edef75c 100644
--- a/substrate/demo/runtime/src/runtime/system.rs
+++ b/substrate/demo/runtime/src/runtime/system.rs
@@ -144,12 +144,6 @@ pub mod internal {
 			Function::TimestampSet(t) => {
 				::runtime::timestamp::public::set(t);
 			}
-			Function::GovernancePropose(ref proposal) => {
-				::runtime::governance::public::propose(transactor, proposal);
-			}
-			Function::GovernanceApprove(era_index) => {
-				::runtime::governance::public::approve(transactor, era_index);
-			}
 		}
 	}
 }
@@ -253,7 +247,7 @@ mod tests {
 	use environment::with_env;
 	use primitives::hexdisplay::HexDisplay;
 	use demo_primitives::{Header, Digest, UncheckedTransaction, Transaction, Function};
-	use runtime::{governance, staking};
+	use runtime::staking;
 
 	#[test]
 	fn staking_balance_transfer_dispatch_works() {
@@ -281,7 +275,7 @@ mod tests {
 	}
 
 	fn new_test_ext() -> TestExternalities {
-		governance::testing::externalities(2, 2, 0)
+		staking::testing::externalities(2, 2, 0)
 	}
 
 	#[test]
@@ -294,7 +288,7 @@ mod tests {
 		let h = Header {
 			parent_hash: [69u8; 32].into(),
 			number: 1,
-			state_root: hex!("1ab2dbb7d4868a670b181327b0b6a58dc64b10cfb9876f737a5aa014b8da31e0").into(),
+			state_root: hex!("52eb24906a4110a605d29d4e2f01b43cb169d375d709b138cc8ce50ad5f7ce85").into(),
 			transaction_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(),
 			digest: Digest { logs: vec![], },
 		};
diff --git a/substrate/substrate/codec/src/slicable.rs b/substrate/substrate/codec/src/slicable.rs
index 0304b51003765d70956b17b323b61d692e086b78..eb2b01db52fc841fb12febfdaf9957c0d67fa96d 100644
--- a/substrate/substrate/codec/src/slicable.rs
+++ b/substrate/substrate/codec/src/slicable.rs
@@ -89,6 +89,26 @@ impl<T: EndianSensitive> Slicable for T {
 	}
 }
 
+impl Slicable for Option<bool> {
+	fn decode<I: Input>(input: &mut I) -> Option<Self> {
+		u8::decode(input).and_then(|v| match v {
+			0 => Some(Some(false)),
+			1 => Some(Some(true)),
+			2 => Some(None),
+			_ => None,
+		})
+	}
+
+	fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
+		match *self {
+			Some(false) => 0u8,
+			Some(true) => 1u8,
+			None => 2u8,
+		}.using_encoded(f)
+	}
+}
+impl NonTrivialSlicable for Option<bool> {}
+
 impl Slicable for Vec<u8> {
 	fn decode<I: Input>(input: &mut I) -> Option<Self> {
 		u32::decode(input).and_then(move |len| {