diff --git a/substrate/core/primitives/src/u32_trait.rs b/substrate/core/primitives/src/u32_trait.rs
index 3fcdceac4cbbfacea532c498648ccee980a0e36c..d8fac34c301ab4ee78417c1d8c8755e89b53795a 100644
--- a/substrate/core/primitives/src/u32_trait.rs
+++ b/substrate/core/primitives/src/u32_trait.rs
@@ -21,6 +21,7 @@ pub trait Value {
 	/// The actual value represented by the impl'ing type.
 	const VALUE: u32;
 }
+
 /// Type representing the value 0 for the `Value` trait.
 pub struct _0; impl Value for _0 { const VALUE: u32 = 0; }
 /// Type representing the value 1 for the `Value` trait.
@@ -55,22 +56,174 @@ pub struct _14; impl Value for _14 { const VALUE: u32 = 14; }
 pub struct _15; impl Value for _15 { const VALUE: u32 = 15; }
 /// Type representing the value 16 for the `Value` trait.
 pub struct _16; impl Value for _16 { const VALUE: u32 = 16; }
+/// Type representing the value 17 for the `Value` trait.
+pub struct _17; impl Value for _17 { const VALUE: u32 = 17; }
+/// Type representing the value 18 for the `Value` trait.
+pub struct _18; impl Value for _18 { const VALUE: u32 = 18; }
+/// Type representing the value 19 for the `Value` trait.
+pub struct _19; impl Value for _19 { const VALUE: u32 = 19; }
+/// Type representing the value 20 for the `Value` trait.
+pub struct _20; impl Value for _20 { const VALUE: u32 = 20; }
+/// Type representing the value 21 for the `Value` trait.
+pub struct _21; impl Value for _21 { const VALUE: u32 = 21; }
+/// Type representing the value 22 for the `Value` trait.
+pub struct _22; impl Value for _22 { const VALUE: u32 = 22; }
+/// Type representing the value 23 for the `Value` trait.
+pub struct _23; impl Value for _23 { const VALUE: u32 = 23; }
 /// Type representing the value 24 for the `Value` trait.
 pub struct _24; impl Value for _24 { const VALUE: u32 = 24; }
+/// Type representing the value 25 for the `Value` trait.
+pub struct _25; impl Value for _25 { const VALUE: u32 = 25; }
+/// Type representing the value 26 for the `Value` trait.
+pub struct _26; impl Value for _26 { const VALUE: u32 = 26; }
+/// Type representing the value 27 for the `Value` trait.
+pub struct _27; impl Value for _27 { const VALUE: u32 = 27; }
+/// Type representing the value 28 for the `Value` trait.
+pub struct _28; impl Value for _28 { const VALUE: u32 = 28; }
+/// Type representing the value 29 for the `Value` trait.
+pub struct _29; impl Value for _29 { const VALUE: u32 = 29; }
+/// Type representing the value 30 for the `Value` trait.
+pub struct _30; impl Value for _30 { const VALUE: u32 = 30; }
+/// Type representing the value 31 for the `Value` trait.
+pub struct _31; impl Value for _31 { const VALUE: u32 = 31; }
 /// Type representing the value 32 for the `Value` trait.
 pub struct _32; impl Value for _32 { const VALUE: u32 = 32; }
+/// Type representing the value 33 for the `Value` trait.
+pub struct _33; impl Value for _33 { const VALUE: u32 = 33; }
+/// Type representing the value 34 for the `Value` trait.
+pub struct _34; impl Value for _34 { const VALUE: u32 = 34; }
+/// Type representing the value 35 for the `Value` trait.
+pub struct _35; impl Value for _35 { const VALUE: u32 = 35; }
+/// Type representing the value 36 for the `Value` trait.
+pub struct _36; impl Value for _36 { const VALUE: u32 = 36; }
+/// Type representing the value 37 for the `Value` trait.
+pub struct _37; impl Value for _37 { const VALUE: u32 = 37; }
+/// Type representing the value 38 for the `Value` trait.
+pub struct _38; impl Value for _38 { const VALUE: u32 = 38; }
+/// Type representing the value 39 for the `Value` trait.
+pub struct _39; impl Value for _39 { const VALUE: u32 = 39; }
 /// Type representing the value 40 for the `Value` trait.
 pub struct _40; impl Value for _40 { const VALUE: u32 = 40; }
+/// Type representing the value 41 for the `Value` trait.
+pub struct _41; impl Value for _41 { const VALUE: u32 = 41; }
+/// Type representing the value 42 for the `Value` trait.
+pub struct _42; impl Value for _42 { const VALUE: u32 = 42; }
+/// Type representing the value 43 for the `Value` trait.
+pub struct _43; impl Value for _43 { const VALUE: u32 = 43; }
+/// Type representing the value 44 for the `Value` trait.
+pub struct _44; impl Value for _44 { const VALUE: u32 = 44; }
+/// Type representing the value 45 for the `Value` trait.
+pub struct _45; impl Value for _45 { const VALUE: u32 = 45; }
+/// Type representing the value 46 for the `Value` trait.
+pub struct _46; impl Value for _46 { const VALUE: u32 = 46; }
+/// Type representing the value 47 for the `Value` trait.
+pub struct _47; impl Value for _47 { const VALUE: u32 = 47; }
 /// Type representing the value 48 for the `Value` trait.
 pub struct _48; impl Value for _48 { const VALUE: u32 = 48; }
+/// Type representing the value 49 for the `Value` trait.
+pub struct _49; impl Value for _49 { const VALUE: u32 = 49; }
+/// Type representing the value 50 for the `Value` trait.
+pub struct _50; impl Value for _50 { const VALUE: u32 = 50; }
+/// Type representing the value 51 for the `Value` trait.
+pub struct _51; impl Value for _51 { const VALUE: u32 = 51; }
+/// Type representing the value 52 for the `Value` trait.
+pub struct _52; impl Value for _52 { const VALUE: u32 = 52; }
+/// Type representing the value 53 for the `Value` trait.
+pub struct _53; impl Value for _53 { const VALUE: u32 = 53; }
+/// Type representing the value 54 for the `Value` trait.
+pub struct _54; impl Value for _54 { const VALUE: u32 = 54; }
+/// Type representing the value 55 for the `Value` trait.
+pub struct _55; impl Value for _55 { const VALUE: u32 = 55; }
 /// Type representing the value 56 for the `Value` trait.
 pub struct _56; impl Value for _56 { const VALUE: u32 = 56; }
+/// Type representing the value 57 for the `Value` trait.
+pub struct _57; impl Value for _57 { const VALUE: u32 = 57; }
+/// Type representing the value 58 for the `Value` trait.
+pub struct _58; impl Value for _58 { const VALUE: u32 = 58; }
+/// Type representing the value 59 for the `Value` trait.
+pub struct _59; impl Value for _59 { const VALUE: u32 = 59; }
+/// Type representing the value 60 for the `Value` trait.
+pub struct _60; impl Value for _60 { const VALUE: u32 = 60; }
+/// Type representing the value 61 for the `Value` trait.
+pub struct _61; impl Value for _61 { const VALUE: u32 = 61; }
+/// Type representing the value 62 for the `Value` trait.
+pub struct _62; impl Value for _62 { const VALUE: u32 = 62; }
+/// Type representing the value 63 for the `Value` trait.
+pub struct _63; impl Value for _63 { const VALUE: u32 = 63; }
 /// Type representing the value 64 for the `Value` trait.
 pub struct _64; impl Value for _64 { const VALUE: u32 = 64; }
+/// Type representing the value 65 for the `Value` trait.
+pub struct _65; impl Value for _65 { const VALUE: u32 = 65; }
+/// Type representing the value 66 for the `Value` trait.
+pub struct _66; impl Value for _66 { const VALUE: u32 = 66; }
+/// Type representing the value 67 for the `Value` trait.
+pub struct _67; impl Value for _67 { const VALUE: u32 = 67; }
+/// Type representing the value 68 for the `Value` trait.
+pub struct _68; impl Value for _68 { const VALUE: u32 = 68; }
+/// Type representing the value 69 for the `Value` trait.
+pub struct _69; impl Value for _69 { const VALUE: u32 = 69; }
+/// Type representing the value 70 for the `Value` trait.
+pub struct _70; impl Value for _70 { const VALUE: u32 = 70; }
+/// Type representing the value 71 for the `Value` trait.
+pub struct _71; impl Value for _71 { const VALUE: u32 = 71; }
+/// Type representing the value 72 for the `Value` trait.
+pub struct _72; impl Value for _72 { const VALUE: u32 = 72; }
+/// Type representing the value 73 for the `Value` trait.
+pub struct _73; impl Value for _73 { const VALUE: u32 = 73; }
+/// Type representing the value 74 for the `Value` trait.
+pub struct _74; impl Value for _74 { const VALUE: u32 = 74; }
+/// Type representing the value 75 for the `Value` trait.
+pub struct _75; impl Value for _75 { const VALUE: u32 = 75; }
+/// Type representing the value 76 for the `Value` trait.
+pub struct _76; impl Value for _76 { const VALUE: u32 = 76; }
+/// Type representing the value 77 for the `Value` trait.
+pub struct _77; impl Value for _77 { const VALUE: u32 = 77; }
+/// Type representing the value 78 for the `Value` trait.
+pub struct _78; impl Value for _78 { const VALUE: u32 = 78; }
+/// Type representing the value 79 for the `Value` trait.
+pub struct _79; impl Value for _79 { const VALUE: u32 = 79; }
 /// Type representing the value 80 for the `Value` trait.
 pub struct _80; impl Value for _80 { const VALUE: u32 = 80; }
+/// Type representing the value 81 for the `Value` trait.
+pub struct _81; impl Value for _81 { const VALUE: u32 = 81; }
+/// Type representing the value 82 for the `Value` trait.
+pub struct _82; impl Value for _82 { const VALUE: u32 = 82; }
+/// Type representing the value 83 for the `Value` trait.
+pub struct _83; impl Value for _83 { const VALUE: u32 = 83; }
+/// Type representing the value 84 for the `Value` trait.
+pub struct _84; impl Value for _84 { const VALUE: u32 = 84; }
+/// Type representing the value 85 for the `Value` trait.
+pub struct _85; impl Value for _85 { const VALUE: u32 = 85; }
+/// Type representing the value 86 for the `Value` trait.
+pub struct _86; impl Value for _86 { const VALUE: u32 = 86; }
+/// Type representing the value 87 for the `Value` trait.
+pub struct _87; impl Value for _87 { const VALUE: u32 = 87; }
+/// Type representing the value 88 for the `Value` trait.
+pub struct _88; impl Value for _88 { const VALUE: u32 = 88; }
+/// Type representing the value 89 for the `Value` trait.
+pub struct _89; impl Value for _89 { const VALUE: u32 = 89; }
+/// Type representing the value 90 for the `Value` trait.
+pub struct _90; impl Value for _90 { const VALUE: u32 = 90; }
+/// Type representing the value 91 for the `Value` trait.
+pub struct _91; impl Value for _91 { const VALUE: u32 = 91; }
+/// Type representing the value 92 for the `Value` trait.
+pub struct _92; impl Value for _92 { const VALUE: u32 = 92; }
+/// Type representing the value 93 for the `Value` trait.
+pub struct _93; impl Value for _93 { const VALUE: u32 = 93; }
+/// Type representing the value 94 for the `Value` trait.
+pub struct _94; impl Value for _94 { const VALUE: u32 = 94; }
+/// Type representing the value 95 for the `Value` trait.
+pub struct _95; impl Value for _95 { const VALUE: u32 = 95; }
 /// Type representing the value 96 for the `Value` trait.
 pub struct _96; impl Value for _96 { const VALUE: u32 = 96; }
+/// Type representing the value 97 for the `Value` trait.
+pub struct _97; impl Value for _97 { const VALUE: u32 = 97; }
+/// Type representing the value 98 for the `Value` trait.
+pub struct _98; impl Value for _98 { const VALUE: u32 = 98; }
+/// Type representing the value 99 for the `Value` trait.
+pub struct _99; impl Value for _99 { const VALUE: u32 = 99; }
+/// Type representing the value 100 for the `Value` trait.
+pub struct _100; impl Value for _100 { const VALUE: u32 = 100; }
 /// Type representing the value 112 for the `Value` trait.
 pub struct _112; impl Value for _112 { const VALUE: u32 = 112; }
 /// Type representing the value 128 for the `Value` trait.
@@ -87,3 +240,4 @@ pub struct _256; impl Value for _256 { const VALUE: u32 = 256; }
 pub struct _384; impl Value for _384 { const VALUE: u32 = 384; }
 /// Type representing the value 512 for the `Value` trait.
 pub struct _512; impl Value for _512 { const VALUE: u32 = 512; }
+
diff --git a/substrate/core/sr-primitives/src/traits.rs b/substrate/core/sr-primitives/src/traits.rs
index 596345036079dfb9d24054d53e4633237976e9ea..f412ede0afb9bf1bbf5591b471c4c97c73d51f3c 100644
--- a/substrate/core/sr-primitives/src/traits.rs
+++ b/substrate/core/sr-primitives/src/traits.rs
@@ -73,7 +73,11 @@ pub trait EnsureOrigin<OuterOrigin> {
 	/// A return type.
 	type Success;
 	/// Perform the origin check.
-	fn ensure_origin(o: OuterOrigin) -> result::Result<Self::Success, &'static str>;
+	fn ensure_origin(o: OuterOrigin) -> result::Result<Self::Success, &'static str> {
+		Self::try_origin(o).map_err(|_| "Invalid origin")
+	}
+	/// Perform the origin check.
+	fn try_origin(o: OuterOrigin) -> result::Result<Self::Success, OuterOrigin>;
 }
 
 /// Means of changing one type into another in a manner dependent on the source type.
diff --git a/substrate/node/cli/src/chain_spec.rs b/substrate/node/cli/src/chain_spec.rs
index 2ce4a3e656fc5818e62ac510360e460a8cb815bf..bc24de9ddfebd14dece6d89ae3bf786af0696d12 100644
--- a/substrate/node/cli/src/chain_spec.rs
+++ b/substrate/node/cli/src/chain_spec.rs
@@ -18,7 +18,7 @@
 
 use primitives::{ed25519::Public as AuthorityId, ed25519, sr25519, Pair, crypto::UncheckedInto};
 use node_primitives::AccountId;
-use node_runtime::{ConsensusConfig, CouncilSeatsConfig, CouncilVotingConfig, DemocracyConfig,
+use node_runtime::{ConsensusConfig, CouncilSeatsConfig, DemocracyConfig,
 	SessionConfig, StakingConfig, StakerStatus, TimestampConfig, BalancesConfig, TreasuryConfig,
 	SudoConfig, ContractConfig, GrandpaConfig, IndicesConfig, Permill, Perbill};
 pub use node_runtime::GenesisConfig;
@@ -132,11 +132,6 @@ fn staging_testnet_config_genesis() -> GenesisConfig {
 			desired_seats: 0,
 			inactive_grace_period: 1,    // one additional vote should go by before an inactive voter can be reaped.
 		}),
-		council_voting: Some(CouncilVotingConfig {
-			cooloff_period: 4 * DAYS,
-			voting_period: 1 * DAYS,
-			enact_delay_period: 0,
-		}),
 		timestamp: Some(TimestampConfig {
 			minimum_period: SECS_PER_BLOCK / 2, // due to the nature of aura the slots are 2*period
 		}),
@@ -312,11 +307,6 @@ pub fn testnet_genesis(
 			desired_seats: (endowed_accounts.len() / 2 - initial_authorities.len()) as u32,
 			inactive_grace_period: 1,
 		}),
-		council_voting: Some(CouncilVotingConfig {
-			cooloff_period: 75,
-			voting_period: 20,
-			enact_delay_period: 0,
-		}),
 		timestamp: Some(TimestampConfig {
 			minimum_period: 2,                    // 2*2=4 second block time.
 		}),
diff --git a/substrate/node/executor/src/lib.rs b/substrate/node/executor/src/lib.rs
index 8813850bbd05241348e8c44dba9bf2715b5f3f7d..05dc424d496b2fc8c908e84823352c3adb1b3d2e 100644
--- a/substrate/node/executor/src/lib.rs
+++ b/substrate/node/executor/src/lib.rs
@@ -316,7 +316,6 @@ mod tests {
 			}),
 			democracy: Some(Default::default()),
 			council_seats: Some(Default::default()),
-			council_voting: Some(Default::default()),
 			timestamp: Some(Default::default()),
 			treasury: Some(Default::default()),
 			contract: Some(Default::default()),
diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs
index 5daeccf72c7ab1677c05085c96803560a463a431..f0c1a8ae7d3158cc164b0289a767c2ca54916343 100644
--- a/substrate/node/runtime/src/lib.rs
+++ b/substrate/node/runtime/src/lib.rs
@@ -22,7 +22,7 @@
 
 use rstd::prelude::*;
 use support::{construct_runtime, parameter_types};
-use substrate_primitives::u32_trait::{_2, _4};
+use substrate_primitives::u32_trait::{_1, _2, _3, _4};
 use node_primitives::{
 	AccountId, AccountIndex, Balance, BlockNumber, Hash, Index, AuthorityId, Signature, AuthoritySignature
 };
@@ -37,7 +37,7 @@ use runtime_primitives::traits::{
 	BlakeTwo256, Block as BlockT, DigestFor, NumberFor, StaticLookup, AuthorityIdFor, Convert,
 };
 use version::RuntimeVersion;
-use council::{motions as council_motions, voting as council_voting};
+use council::{motions as council_motions};
 #[cfg(feature = "std")]
 use council::seats as council_seats;
 #[cfg(any(feature = "std", test))]
@@ -156,8 +156,10 @@ const BUCKS: Balance = 1_000_000_000_000;
 parameter_types! {
 	pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
 	pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
+	pub const EmergencyVotingPeriod: BlockNumber = 3 * 24 * 60 * MINUTES;
 	pub const MinimumDeposit: Balance = 100 * BUCKS;
 	pub const EnactmentPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
+	pub const CooloffPeriod: BlockNumber = 30 * 24 * 60 * MINUTES;
 }
 impl democracy::Trait for Runtime {
 	type Proposal = Call;
@@ -166,17 +168,21 @@ impl democracy::Trait for Runtime {
 	type EnactmentPeriod = EnactmentPeriod;
 	type LaunchPeriod = LaunchPeriod;
 	type VotingPeriod = VotingPeriod;
+	type EmergencyVotingPeriod = EmergencyVotingPeriod;
 	type MinimumDeposit = MinimumDeposit;
+	type ExternalOrigin = council_motions::EnsureProportionAtLeast<_1, _2, AccountId>;
+	type ExternalMajorityOrigin = council_motions::EnsureProportionAtLeast<_2, _3, AccountId>;
+	type EmergencyOrigin = council_motions::EnsureProportionAtLeast<_1, _1, AccountId>;
+	type CancellationOrigin = council_motions::EnsureProportionAtLeast<_2, _3, AccountId>;
+	type VetoOrigin = council_motions::EnsureMember<AccountId>;
+	type CooloffPeriod = CooloffPeriod;
 }
 
 impl council::Trait for Runtime {
 	type Event = Event;
 	type BadPresentation = ();
 	type BadReaper = ();
-}
-
-impl council::voting::Trait for Runtime {
-	type Event = Event;
+	type OnMembersChanged = CouncilMotions;
 }
 
 impl council::motions::Trait for Runtime {
@@ -187,8 +193,8 @@ impl council::motions::Trait for Runtime {
 
 impl treasury::Trait for Runtime {
 	type Currency = Balances;
-	type ApproveOrigin = council_motions::EnsureMembers<_4>;
-	type RejectOrigin = council_motions::EnsureMembers<_2>;
+	type ApproveOrigin = council_motions::EnsureMembers<_4, AccountId>;
+	type RejectOrigin = council_motions::EnsureMembers<_2, AccountId>;
 	type Event = Event;
 	type MintedForSpending = ();
 	type ProposalRejection = ();
@@ -236,8 +242,7 @@ construct_runtime!(
 		Staking: staking::{default, OfflineWorker},
 		Democracy: democracy,
 		Council: council::{Module, Call, Storage, Event<T>},
-		CouncilVoting: council_voting,
-		CouncilMotions: council_motions::{Module, Call, Storage, Event<T>, Origin},
+		CouncilMotions: council_motions::{Module, Call, Storage, Event<T>, Origin<T>},
 		CouncilSeats: council_seats::{Config<T>},
 		FinalityTracker: finality_tracker::{Module, Call, Inherent},
 		Grandpa: grandpa::{Module, Call, Storage, Config<T>, Log(), Event<T>},
diff --git a/substrate/srml/contract/src/lib.rs b/substrate/srml/contract/src/lib.rs
index 3f05bb8a8fa0e592ba9e401863edae2a4180d0d2..0111ce7840204e6112045579fe32349c6770eceb 100644
--- a/substrate/srml/contract/src/lib.rs
+++ b/substrate/srml/contract/src/lib.rs
@@ -506,10 +506,10 @@ decl_module! {
 		fn claim_surcharge(origin, dest: T::AccountId, aux_sender: Option<T::AccountId>) {
 			let origin = origin.into();
 			let (signed, rewarded) = match origin {
-				Some(system::RawOrigin::Signed(ref account)) if aux_sender.is_none() => {
+				Ok(system::RawOrigin::Signed(ref account)) if aux_sender.is_none() => {
 					(true, account)
 				},
-				Some(system::RawOrigin::None) if aux_sender.is_some() => {
+				Ok(system::RawOrigin::None) if aux_sender.is_some() => {
 					(false, aux_sender.as_ref().expect("checked above"))
 				},
 				_ => return Err("Invalid surcharge claim: origin must be signed or \
diff --git a/substrate/srml/council/src/lib.rs b/substrate/srml/council/src/lib.rs
index ac5396e4daf428d66ca7ab8d9b26736b7ce712c1..a72e93c9ebc2202457d3b00ae20014528d0c76c7 100644
--- a/substrate/srml/council/src/lib.rs
+++ b/substrate/srml/council/src/lib.rs
@@ -18,34 +18,42 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
-pub mod voting;
 pub mod motions;
 pub mod seats;
 
 pub use crate::seats::{Trait, Module, RawEvent, Event, VoteIndex};
 
+/// Trait for type that can handle incremental changes to a set of account IDs.
+pub trait OnMembersChanged<AccountId> {
+	/// A number of members `new` just joined the set and replaced some `old` ones.
+	fn on_members_changed(new: &[AccountId], old: &[AccountId]);
+}
+
+impl<T> OnMembersChanged<T> for () {
+	fn on_members_changed(_new: &[T], _old: &[T]) {}
+}
+
 #[cfg(test)]
 mod tests {
 	// These re-exports are here for a reason, edit with care
 	pub use super::*;
 	pub use runtime_io::with_externalities;
 	use srml_support::{impl_outer_origin, impl_outer_event, impl_outer_dispatch, parameter_types};
-	pub use substrate_primitives::H256;
-	pub use primitives::BuildStorage;
-	pub use primitives::traits::{BlakeTwo256, IdentityLookup};
-	pub use primitives::testing::{Digest, DigestItem, Header};
-	pub use substrate_primitives::{Blake2Hasher};
-	pub use {seats, motions, voting};
+	pub use substrate_primitives::{H256, Blake2Hasher, u32_trait::{_1, _2, _3, _4}};
+	pub use primitives::{
+		BuildStorage, traits::{BlakeTwo256, IdentityLookup}, testing::{Digest, DigestItem, Header}
+	};
+	pub use {seats, motions};
 
 	impl_outer_origin! {
 		pub enum Origin for Test {
-			motions
+			motions<T>
 		}
 	}
 
 	impl_outer_event! {
 		pub enum Event for Test {
-			balances<T>, democracy<T>, seats<T>, voting<T>, motions<T>,
+			balances<T>, democracy<T>, seats<T>, motions<T>,
 		}
 	}
 
@@ -86,6 +94,7 @@ mod tests {
 		pub const VotingPeriod: u64 = 3;
 		pub const MinimumDeposit: u64 = 1;
 		pub const EnactmentPeriod: u64 = 0;
+		pub const CooloffPeriod: u64 = 2;
 	}
 	impl democracy::Trait for Test {
 		type Proposal = Call;
@@ -93,22 +102,27 @@ mod tests {
 		type Currency = balances::Module<Self>;
 		type EnactmentPeriod = EnactmentPeriod;
 		type LaunchPeriod = LaunchPeriod;
+		type EmergencyVotingPeriod = VotingPeriod;
 		type VotingPeriod = VotingPeriod;
 		type MinimumDeposit = MinimumDeposit;
+		type ExternalOrigin = motions::EnsureProportionAtLeast<_1, _2, u64>;
+		type ExternalMajorityOrigin = motions::EnsureProportionAtLeast<_2, _3, u64>;
+		type EmergencyOrigin = motions::EnsureProportionAtLeast<_1, _1, u64>;
+		type CancellationOrigin = motions::EnsureProportionAtLeast<_2, _3, u64>;
+		type VetoOrigin = motions::EnsureMember<u64>;
+		type CooloffPeriod = CooloffPeriod;
 	}
 	impl seats::Trait for Test {
 		type Event = Event;
 		type BadPresentation = ();
 		type BadReaper = ();
+		type OnMembersChanged = CouncilMotions;
 	}
 	impl motions::Trait for Test {
 		type Origin = Origin;
 		type Proposal = Call;
 		type Event = Event;
 	}
-	impl voting::Trait for Test {
-		type Event = Event;
-	}
 
 	pub fn new_test_ext(with_council: bool) -> runtime_io::TestExternalities<Blake2Hasher> {
 		let mut t = system::GenesisConfig::<Test>::default().build_storage().unwrap().0;
@@ -138,11 +152,6 @@ mod tests {
 			desired_seats: 2,
 			term_duration: 5,
 		}.build_storage().unwrap().0);
-		t.extend(voting::GenesisConfig::<Test> {
-			cooloff_period: 2,
-			voting_period: 1,
-			enact_delay_period: 0,
-		}.build_storage().unwrap().0);
 		runtime_io::TestExternalities::new(t)
 	}
 
@@ -150,6 +159,5 @@ mod tests {
 	pub type Balances = balances::Module<Test>;
 	pub type Democracy = democracy::Module<Test>;
 	pub type Council = seats::Module<Test>;
-	pub type CouncilVoting = voting::Module<Test>;
 	pub type CouncilMotions = motions::Module<Test>;
 }
diff --git a/substrate/srml/council/src/motions.rs b/substrate/srml/council/src/motions.rs
index e560fadb9c5a49a5a34e7b5b9d45932a480d868c..4ab4e84c12b779904f2fd3eaf8c6e752ae60ee73 100644
--- a/substrate/srml/council/src/motions.rs
+++ b/substrate/srml/council/src/motions.rs
@@ -16,21 +16,27 @@
 
 //! Council voting system.
 
-use rstd::prelude::*;
-use rstd::result;
+use rstd::{prelude::*, result};
 use substrate_primitives::u32_trait::Value as U32;
 use primitives::traits::{Hash, EnsureOrigin};
-use srml_support::dispatch::{Dispatchable, Parameter};
-use srml_support::{StorageValue, StorageMap, decl_module, decl_event, decl_storage, ensure};
-use super::{Trait as CouncilTrait, Module as Council};
+use srml_support::{
+	dispatch::{Dispatchable, Parameter}, codec::{Encode, Decode},
+	StorageValue, StorageMap, decl_module, decl_event, decl_storage, ensure
+};
+use super::{Trait as CouncilTrait, Module as Council, OnMembersChanged};
 use system::{self, ensure_signed};
 
 /// Simple index type for proposal counting.
 pub type ProposalIndex = u32;
+/// A number of council members.
+///
+/// This also serves as a number of voting members, and since for motions, each council member may
+/// vote exactly once, therefore also the number of votes for any given motion.
+pub type MemberCount = u32;
 
 pub trait Trait: CouncilTrait {
 	/// The outer origin type.
-	type Origin: From<Origin>;
+	type Origin: From<RawOrigin<Self::AccountId>>;
 
 	/// The outer call dispatch type.
 	type Proposal: Parameter + Dispatchable<Origin=<Self as Trait>::Origin>;
@@ -42,31 +48,79 @@ pub trait Trait: CouncilTrait {
 /// Origin for the council module.
 #[derive(PartialEq, Eq, Clone)]
 #[cfg_attr(feature = "std", derive(Debug))]
-pub enum Origin {
-	/// It has been condoned by a given number of council members.
-	Members(u32),
+pub enum RawOrigin<AccountId> {
+	/// It has been condoned by a given number of council members from a given total.
+	Members(MemberCount, MemberCount),
+	/// It has been condoned by a single council member.
+	Member(AccountId),
+}
+
+/// Origin for the council module.
+pub type Origin<T> = RawOrigin<<T as system::Trait>::AccountId>;
+
+#[derive(PartialEq, Eq, Clone, Encode, Decode)]
+#[cfg_attr(feature = "std", derive(Debug))]
+/// Info for keeping track of a motion being voted on.
+pub struct Votes<AccountId> {
+	/// The proposal's unique index.
+	index: ProposalIndex,
+	/// The number of approval votes that are needed to pass the motion.
+	threshold: MemberCount,
+	/// The current set of voters that approved it.
+	ayes: Vec<AccountId>,
+	/// The current set of voters that rejected it.
+	nays: Vec<AccountId>,
+}
+
+decl_storage! {
+	trait Store for Module<T: Trait> as CouncilMotions {
+		/// The hashes of the active proposals.
+		pub Proposals get(proposals): Vec<T::Hash>;
+		/// Actual proposal for a given hash, if it's current.
+		pub ProposalOf get(proposal_of): map T::Hash => Option<<T as Trait>::Proposal>;
+		/// Votes on a given proposal, if it is ongoing.
+		pub Voting get(voting): map T::Hash => Option<Votes<T::AccountId>>;
+		/// Proposals so far.
+		pub ProposalCount get(proposal_count): u32;
+	}
 }
 
 decl_event!(
 	pub enum Event<T> where <T as system::Trait>::Hash, <T as system::Trait>::AccountId {
-		/// A motion (given hash) has been proposed (by given account) with a threshold (given u32).
-		Proposed(AccountId, ProposalIndex, Hash, u32),
+		/// A motion (given hash) has been proposed (by given account) with a threshold (given
+		/// `MemberCount`).
+		Proposed(AccountId, ProposalIndex, Hash, MemberCount),
 		/// A motion (given hash) has been voted on by given account, leaving
-		/// a tally (yes votes and no votes given as u32s respectively).
-		Voted(AccountId, Hash, bool, u32, u32),
+		/// a tally (yes votes and no votes given respectively as `MemberCount`).
+		Voted(AccountId, Hash, bool, MemberCount, MemberCount),
 		/// A motion was approved by the required threshold.
 		Approved(Hash),
 		/// A motion was not approved by the required threshold.
 		Disapproved(Hash),
 		/// A motion was executed; `bool` is true if returned without error.
 		Executed(Hash, bool),
+		/// A single councillor did some action; `bool` is true if returned without error.
+		MemberExecuted(Hash, bool),
 	}
 );
 
 decl_module! {
 	pub struct Module<T: Trait> for enum Call where origin: <T as system::Trait>::Origin {
 		fn deposit_event<T>() = default;
-		fn propose(origin, #[compact] threshold: u32, proposal: Box<<T as Trait>::Proposal>) {
+
+		/// Dispatch a proposal from a councilor using the `Member` origin.
+		///
+		/// Origin must be a council member.
+		fn execute(origin, proposal: Box<<T as Trait>::Proposal>) {
+			let who = ensure_signed(origin)?;
+			ensure!(Self::is_councillor(&who), "proposer not on council");
+
+			let proposal_hash = T::Hashing::hash_of(&proposal);
+			let ok = proposal.dispatch(RawOrigin::Member(who).into()).is_ok();
+			Self::deposit_event(RawEvent::MemberExecuted(proposal_hash, ok));
+		}
+
+		fn propose(origin, #[compact] threshold: MemberCount, proposal: Box<<T as Trait>::Proposal>) {
 			let who = ensure_signed(origin)?;
 
 			ensure!(Self::is_councillor(&who), "proposer not on council");
@@ -76,14 +130,16 @@ decl_module! {
 			ensure!(!<ProposalOf<T>>::exists(proposal_hash), "duplicate proposals not allowed");
 
 			if threshold < 2 {
-				let ok = proposal.dispatch(Origin::Members(1).into()).is_ok();
+				let seats = <Council<T>>::active_council().len() as MemberCount;
+				let ok = proposal.dispatch(RawOrigin::Members(1, seats).into()).is_ok();
 				Self::deposit_event(RawEvent::Executed(proposal_hash, ok));
 			} else {
 				let index = Self::proposal_count();
 				<ProposalCount<T>>::mutate(|i| *i += 1);
 				<Proposals<T>>::mutate(|proposals| proposals.push(proposal_hash));
 				<ProposalOf<T>>::insert(proposal_hash, *proposal);
-				<Voting<T>>::insert(proposal_hash, (index, threshold, vec![who.clone()], vec![]));
+				let votes = Votes { index, threshold, ayes: vec![who.clone()], nays: vec![] };
+				<Voting<T>>::insert(proposal_hash, votes);
 
 				Self::deposit_event(RawEvent::Proposed(who, index, proposal_hash, threshold));
 			}
@@ -95,46 +151,46 @@ decl_module! {
 			ensure!(Self::is_councillor(&who), "voter not on council");
 
 			let mut voting = Self::voting(&proposal).ok_or("proposal must exist")?;
-			ensure!(voting.0 == index, "mismatched index");
+			ensure!(voting.index == index, "mismatched index");
 
-			let position_yes = voting.2.iter().position(|a| a == &who);
-			let position_no = voting.3.iter().position(|a| a == &who);
+			let position_yes = voting.ayes.iter().position(|a| a == &who);
+			let position_no = voting.nays.iter().position(|a| a == &who);
 
 			if approve {
 				if position_yes.is_none() {
-					voting.2.push(who.clone());
+					voting.ayes.push(who.clone());
 				} else {
 					return Err("duplicate vote ignored")
 				}
 				if let Some(pos) = position_no {
-					voting.3.swap_remove(pos);
+					voting.nays.swap_remove(pos);
 				}
 			} else {
 				if position_no.is_none() {
-					voting.3.push(who.clone());
+					voting.nays.push(who.clone());
 				} else {
 					return Err("duplicate vote ignored")
 				}
 				if let Some(pos) = position_yes {
-					voting.2.swap_remove(pos);
+					voting.ayes.swap_remove(pos);
 				}
 			}
 
-			let yes_votes = voting.2.len() as u32;
-			let no_votes = voting.3.len() as u32;
+			let yes_votes = voting.ayes.len() as MemberCount;
+			let no_votes = voting.nays.len() as MemberCount;
 			Self::deposit_event(RawEvent::Voted(who, proposal, approve, yes_votes, no_votes));
 
-			let threshold = voting.1;
-			let potential_votes = <Council<T>>::active_council().len() as u32;
-			let approved = yes_votes >= threshold;
-			let disapproved = potential_votes.saturating_sub(no_votes) < threshold;
+			let seats = <Council<T>>::active_council().len() as MemberCount;
+			let approved = yes_votes >= voting.threshold;
+			let disapproved = seats.saturating_sub(no_votes) < voting.threshold;
 			if approved || disapproved {
 				if approved {
 					Self::deposit_event(RawEvent::Approved(proposal));
 
 					// execute motion, assuming it exists.
 					if let Some(p) = <ProposalOf<T>>::take(&proposal) {
-						let ok = p.dispatch(Origin::Members(threshold).into()).is_ok();
+						let origin = RawOrigin::Members(voting.threshold, seats).into();
+						let ok = p.dispatch(origin).is_ok();
 						Self::deposit_event(RawEvent::Executed(proposal, ok));
 					}
 				} else {
@@ -153,22 +209,6 @@ decl_module! {
 	}
 }
 
-decl_storage! {
-	trait Store for Module<T: Trait> as CouncilMotions {
-		/// The (hashes of) the active proposals.
-		pub Proposals get(proposals): Vec<T::Hash>;
-		/// Actual proposal for a given hash, if it's current.
-		pub ProposalOf get(proposal_of): map T::Hash => Option< <T as Trait>::Proposal >;
-		/// Votes for a given proposal: (required_yes_votes, yes_voters, no_voters).
-		pub Voting get(voting): map T::Hash => Option<(ProposalIndex, u32, Vec<T::AccountId>, Vec<T::AccountId>)>;
-		/// Proposals so far.
-		pub ProposalCount get(proposal_count): u32;
-	}
-	add_extra_genesis {
-		build(|_, _, _| {});
-	}
-}
-
 impl<T: Trait> Module<T> {
 	pub fn is_councillor(who: &T::AccountId) -> bool {
 		<Council<T>>::active_council().iter()
@@ -176,24 +216,101 @@ impl<T: Trait> Module<T> {
 	}
 }
 
-/// Ensure that the origin `o` represents at least `n` council members. Returns
-/// `Ok` or an `Err` otherwise.
-pub fn ensure_council_members<OuterOrigin>(o: OuterOrigin, n: u32) -> result::Result<u32, &'static str>
-	where OuterOrigin: Into<Option<Origin>>
+impl<T: Trait> OnMembersChanged<T::AccountId> for Module<T> {
+	fn on_members_changed(_new: &[T::AccountId], old: &[T::AccountId]) {
+		// remove accounts from all current voting in motions.
+		let mut old = old.to_vec();
+		old.sort_unstable();
+		for h in Self::proposals().into_iter() {
+			<Voting<T>>::mutate(h, |v|
+				if let Some(mut votes) = v.take() {
+					votes.ayes = votes.ayes.into_iter()
+						.filter(|i| old.binary_search(i).is_err())
+						.collect();
+					votes.nays = votes.nays.into_iter()
+						.filter(|i| old.binary_search(i).is_err())
+						.collect();
+					*v = Some(votes);
+				}
+			);
+		}
+	}
+}
+
+/// Ensure that the origin `o` represents at least `n` council members. Returns `Ok` or an `Err`
+/// otherwise.
+pub fn ensure_council_members<OuterOrigin, AccountId>(o: OuterOrigin, n: MemberCount)
+	-> result::Result<MemberCount, &'static str>
+	where OuterOrigin: Into<result::Result<RawOrigin<AccountId>, OuterOrigin>>
 {
 	match o.into() {
-		Some(Origin::Members(x)) if x >= n => Ok(n),
+		Ok(RawOrigin::Members(x, _)) if x >= n => Ok(n),
 		_ => Err("bad origin: expected to be a threshold number of council members"),
 	}
 }
 
-pub struct EnsureMembers<N: U32>(::rstd::marker::PhantomData<N>);
-impl<O, N: U32> EnsureOrigin<O> for EnsureMembers<N>
-	where O: Into<Option<Origin>>
-{
-	type Success = u32;
-	fn ensure_origin(o: O) -> result::Result<Self::Success, &'static str> {
-		ensure_council_members(o, N::VALUE)
+pub struct EnsureMember<AccountId>(::rstd::marker::PhantomData<AccountId>);
+impl<
+	O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
+	AccountId
+> EnsureOrigin<O> for EnsureMember<AccountId> {
+	type Success = AccountId;
+	fn try_origin(o: O) -> Result<Self::Success, O> {
+		o.into().and_then(|o| match o {
+			RawOrigin::Member(id) => Ok(id),
+			r => Err(O::from(r)),
+		})
+	}
+}
+
+pub struct EnsureMembers<N: U32, AccountId>(::rstd::marker::PhantomData<(N, AccountId)>);
+impl<
+	O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
+	N: U32,
+	AccountId,
+> EnsureOrigin<O> for EnsureMembers<N, AccountId> {
+	type Success = (MemberCount, MemberCount);
+	fn try_origin(o: O) -> Result<Self::Success, O> {
+		o.into().and_then(|o| match o {
+			RawOrigin::Members(n, m) if n >= N::VALUE => Ok((n, m)),
+			r => Err(O::from(r)),
+		})
+	}
+}
+
+pub struct EnsureProportionMoreThan<N: U32, D: U32, AccountId>(
+	::rstd::marker::PhantomData<(N, D, AccountId)>
+);
+impl<
+	O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
+	N: U32,
+	D: U32,
+	AccountId,
+> EnsureOrigin<O> for EnsureProportionMoreThan<N, D, AccountId> {
+	type Success = ();
+	fn try_origin(o: O) -> Result<Self::Success, O> {
+		o.into().and_then(|o| match o {
+			RawOrigin::Members(n, m) if n * D::VALUE > N::VALUE * m => Ok(()),
+			r => Err(O::from(r)),
+		})
+	}
+}
+
+pub struct EnsureProportionAtLeast<N: U32, D: U32, AccountId>(
+	::rstd::marker::PhantomData<(N, D, AccountId)>
+);
+impl<
+	O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
+	N: U32,
+	D: U32,
+	AccountId,
+> EnsureOrigin<O> for EnsureProportionAtLeast<N, D, AccountId> {
+	type Success = ();
+	fn try_origin(o: O) -> Result<Self::Success, O> {
+		o.into().and_then(|o| match o {
+			RawOrigin::Members(n, m) if n * D::VALUE >= N::VALUE * m => Ok(()),
+			r => Err(O::from(r)),
+		})
 	}
 }
 
@@ -203,12 +320,13 @@ mod tests {
 	use super::RawEvent;
 	use crate::tests::*;
 	use crate::tests::{Call, Origin, Event as OuterEvent};
+	use primitives::traits::BlakeTwo256;
 	use srml_support::{Hashable, assert_ok, assert_noop};
 	use system::{EventRecord, Phase};
 	use hex_literal::hex;
 
 	#[test]
-	fn motions_basic_environment_works() {
+	fn basic_environment_works() {
 		with_externalities(&mut new_test_ext(true), || {
 			System::set_block_number(1);
 			assert_eq!(Balances::free_balance(&42), 0);
@@ -221,7 +339,41 @@ mod tests {
 	}
 
 	#[test]
-	fn motions_propose_works() {
+	fn removal_of_old_voters_votes_works() {
+		with_externalities(&mut new_test_ext(true), || {
+			System::set_block_number(1);
+			let proposal = set_balance_proposal(42);
+			let hash = BlakeTwo256::hash_of(&proposal);
+			assert_ok!(CouncilMotions::propose(Origin::signed(1), 3, Box::new(proposal.clone())));
+			assert_ok!(CouncilMotions::vote(Origin::signed(2), hash.clone(), 0, true));
+			assert_eq!(
+				CouncilMotions::voting(&hash),
+				Some(Votes { index: 0, threshold: 3, ayes: vec![1, 2], nays: vec![] })
+			);
+			CouncilMotions::on_members_changed(&[], &[1]);
+			assert_eq!(
+				CouncilMotions::voting(&hash),
+				Some(Votes { index: 0, threshold: 3, ayes: vec![2], nays: vec![] })
+			);
+
+			let proposal = set_balance_proposal(69);
+			let hash = BlakeTwo256::hash_of(&proposal);
+			assert_ok!(CouncilMotions::propose(Origin::signed(2), 2, Box::new(proposal.clone())));
+			assert_ok!(CouncilMotions::vote(Origin::signed(3), hash.clone(), 1, false));
+			assert_eq!(
+				CouncilMotions::voting(&hash),
+				Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![3] })
+			);
+			CouncilMotions::on_members_changed(&[], &[3]);
+			assert_eq!(
+				CouncilMotions::voting(&hash),
+				Some(Votes { index: 1, threshold: 2, ayes: vec![2], nays: vec![] })
+			);
+		});
+	}
+
+	#[test]
+	fn propose_works() {
 		with_externalities(&mut new_test_ext(true), || {
 			System::set_block_number(1);
 			let proposal = set_balance_proposal(42);
@@ -229,7 +381,10 @@ mod tests {
 			assert_ok!(CouncilMotions::propose(Origin::signed(1), 3, Box::new(proposal.clone())));
 			assert_eq!(CouncilMotions::proposals(), vec![hash]);
 			assert_eq!(CouncilMotions::proposal_of(&hash), Some(proposal));
-			assert_eq!(CouncilMotions::voting(&hash), Some((0, 3, vec![1], Vec::<u64>::new())));
+			assert_eq!(
+				CouncilMotions::voting(&hash),
+				Some(Votes { index: 0, threshold: 3, ayes: vec![1], nays: vec![] })
+			);
 
 			assert_eq!(System::events(), vec![
 				EventRecord {
@@ -242,7 +397,7 @@ mod tests {
 	}
 
 	#[test]
-	fn motions_ignoring_non_council_proposals_works() {
+	fn ignoring_non_council_proposals_works() {
 		with_externalities(&mut new_test_ext(true), || {
 			System::set_block_number(1);
 			let proposal = set_balance_proposal(42);
@@ -251,7 +406,7 @@ mod tests {
 	}
 
 	#[test]
-	fn motions_ignoring_non_council_votes_works() {
+	fn ignoring_non_council_votes_works() {
 		with_externalities(&mut new_test_ext(true), || {
 			System::set_block_number(1);
 			let proposal = set_balance_proposal(42);
@@ -262,7 +417,7 @@ mod tests {
 	}
 
 	#[test]
-	fn motions_ignoring_bad_index_council_vote_works() {
+	fn ignoring_bad_index_council_vote_works() {
 		with_externalities(&mut new_test_ext(true), || {
 			System::set_block_number(3);
 			let proposal = set_balance_proposal(42);
@@ -273,16 +428,22 @@ mod tests {
 	}
 
 	#[test]
-	fn motions_revoting_works() {
+	fn revoting_works() {
 		with_externalities(&mut new_test_ext(true), || {
 			System::set_block_number(1);
 			let proposal = set_balance_proposal(42);
 			let hash: H256 = proposal.blake2_256().into();
 			assert_ok!(CouncilMotions::propose(Origin::signed(1), 2, Box::new(proposal.clone())));
-			assert_eq!(CouncilMotions::voting(&hash), Some((0, 2, vec![1], Vec::<u64>::new())));
+			assert_eq!(
+				CouncilMotions::voting(&hash),
+				Some(Votes { index: 0, threshold: 2, ayes: vec![1], nays: vec![] })
+			);
 			assert_noop!(CouncilMotions::vote(Origin::signed(1), hash.clone(), 0, true), "duplicate vote ignored");
 			assert_ok!(CouncilMotions::vote(Origin::signed(1), hash.clone(), 0, false));
-			assert_eq!(CouncilMotions::voting(&hash), Some((0, 2, Vec::<u64>::new(), vec![1])));
+			assert_eq!(
+				CouncilMotions::voting(&hash),
+				Some(Votes { index: 0, threshold: 2, ayes: vec![], nays: vec![1] })
+			);
 			assert_noop!(CouncilMotions::vote(Origin::signed(1), hash.clone(), 0, false), "duplicate vote ignored");
 
 			assert_eq!(System::events(), vec![
@@ -301,7 +462,7 @@ mod tests {
 	}
 
 	#[test]
-	fn motions_disapproval_works() {
+	fn disapproval_works() {
 		with_externalities(&mut new_test_ext(true), || {
 			System::set_block_number(1);
 			let proposal = set_balance_proposal(42);
@@ -330,7 +491,7 @@ mod tests {
 	}
 
 	#[test]
-	fn motions_approval_works() {
+	fn approval_works() {
 		with_externalities(&mut new_test_ext(true), || {
 			System::set_block_number(1);
 			let proposal = set_balance_proposal(42);
diff --git a/substrate/srml/council/src/seats.rs b/substrate/srml/council/src/seats.rs
index fb93157981643dd055f2982fba061a316aac6543..584a2fb8006696f754a63b2ca2f0f3df8138cfe5 100644
--- a/substrate/srml/council/src/seats.rs
+++ b/substrate/srml/council/src/seats.rs
@@ -25,6 +25,7 @@ use srml_support::{
 };
 use democracy;
 use system::{self, ensure_signed};
+use super::OnMembersChanged;
 
 // no polynomial attacks:
 //
@@ -95,6 +96,9 @@ pub trait Trait: democracy::Trait {
 
 	/// Handler for the unbalanced reduction when slashing an invalid reaping attempt.
 	type BadReaper: OnUnbalanced<NegativeImbalanceOf<Self>>;
+
+	/// What to do when the members change.
+	type OnMembersChanged: OnMembersChanged<Self::AccountId>;
 }
 
 decl_module! {
@@ -269,15 +273,16 @@ decl_module! {
 		}
 
 		/// Set the desired member count; if lower than the current count, then seats will not be up
-		/// election when they expire. If more, then a new vote will be started if one is not already
-		/// in progress.
+		/// election when they expire. If more, then a new vote will be started if one is not
+		/// already in progress.
 		fn set_desired_seats(#[compact] count: u32) {
 			<DesiredSeats<T>>::put(count);
 		}
 
-		/// Remove a particular member. A tally will happen instantly (if not already in a presentation
+		/// Remove a particular member from the council. This is effective immediately.
+		///
+		/// Note: A tally should happen instantly (if not already in a presentation
 		/// period) to fill the seat if removal means that the desired members are not met.
-		/// This is effective immediately.
 		fn remove_member(who: <T::Lookup as StaticLookup>::Source) {
 			let who = T::Lookup::lookup(who)?;
 			let new_council: Vec<(T::AccountId, T::BlockNumber)> = Self::active_council()
@@ -285,6 +290,7 @@ decl_module! {
 				.filter(|i| i.0 != who)
 				.collect();
 			<ActiveCouncil<T>>::put(new_council);
+			T::OnMembersChanged::on_members_changed(&[], &[who]);
 		}
 
 		/// Set the presentation duration. If there is currently a vote being presented for, will
@@ -392,6 +398,14 @@ impl<T: Trait> Module<T> {
 		<RegisterInfoOf<T>>::exists(who)
 	}
 
+	/// Iff the councillor `who` still has a seat at blocknumber `n` returns `true`.
+	pub fn will_still_be_councillor_at(who: &T::AccountId, n: T::BlockNumber) -> bool {
+		Self::active_council().iter()
+			.find(|&&(ref a, _)| a == who)
+			.map(|&(_, expires)| expires > n)
+			.unwrap_or(false)
+	}
+
 	/// Determine the block that a vote can happen on which is no less than `n`.
 	pub fn next_vote_from(n: T::BlockNumber) -> T::BlockNumber {
 		let voting_period = Self::voting_period();
@@ -514,7 +528,7 @@ impl<T: Trait> Module<T> {
 
 		// return bond to winners.
 		let candidacy_bond = Self::candidacy_bond();
-		let incoming: Vec<T::AccountId> = leaderboard.iter()
+		let incoming: Vec<_> = leaderboard.iter()
 			.rev()
 			.take_while(|&&(b, _)| !b.is_zero())
 			.take(coming as usize)
@@ -523,7 +537,9 @@ impl<T: Trait> Module<T> {
 			.inspect(|a| {T::Currency::unreserve(a, candidacy_bond);})
 			.collect();
 		let active_council = Self::active_council();
-		let outgoing = active_council.iter().take(expiring.len()).map(|a| a.0.clone()).collect();
+		let outgoing: Vec<_> = active_council.iter()
+			.take(expiring.len())
+			.map(|a| a.0.clone()).collect();
 
 		// set the new council.
 		let mut new_council: Vec<_> = active_council
@@ -534,6 +550,8 @@ impl<T: Trait> Module<T> {
 		new_council.sort_by_key(|&(_, expiry)| expiry);
 		<ActiveCouncil<T>>::put(new_council);
 
+		T::OnMembersChanged::on_members_changed(&incoming, &outgoing);
+
 		// clear all except runners-up from candidate list.
 		let candidates = Self::candidates();
 		let mut new_candidates = vec![T::AccountId::default(); candidates.len()];	// shrink later.
diff --git a/substrate/srml/council/src/voting.rs b/substrate/srml/council/src/voting.rs
deleted file mode 100644
index 0137cd6d2fc075641bee3c54f0c786a931587a73..0000000000000000000000000000000000000000
--- a/substrate/srml/council/src/voting.rs
+++ /dev/null
@@ -1,494 +0,0 @@
-// Copyright 2017-2019 Parity Technologies (UK) Ltd.
-// This file is part of Substrate.
-
-// Substrate 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 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.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Council voting system.
-
-use rstd::prelude::*;
-use rstd::borrow::Borrow;
-use primitives::traits::{Hash, Zero};
-use runtime_io::print;
-use srml_support::dispatch::Result;
-use srml_support::{StorageValue, StorageMap, IsSubType, decl_module, decl_storage, decl_event, ensure};
-use {system, democracy};
-use super::{Trait as CouncilTrait, Module as Council};
-use system::ensure_signed;
-
-pub trait Trait: CouncilTrait {
-	type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
-}
-
-decl_module! {
-	pub struct Module<T: Trait> for enum Call where origin: T::Origin {
-		fn deposit_event<T>() = default;
-
-		fn propose(origin, proposal: Box<T::Proposal>) {
-			let who = ensure_signed(origin)?;
-
-			let expiry = <system::Module<T>>::block_number() + Self::voting_period();
-			ensure!(Self::will_still_be_councillor_at(&who, expiry), "proposer would not be on council");
-
-			let proposal_hash = T::Hashing::hash_of(&proposal);
-
-			ensure!(!<ProposalOf<T>>::exists(proposal_hash), "duplicate proposals not allowed");
-			ensure!(!Self::is_vetoed(&proposal_hash), "proposal is vetoed");
-
-			let mut proposals = Self::proposals();
-			proposals.push((expiry, proposal_hash));
-			proposals.sort_by_key(|&(expiry, _)| expiry);
-			Self::set_proposals(&proposals);
-
-			<ProposalOf<T>>::insert(proposal_hash, *proposal);
-			<ProposalVoters<T>>::insert(proposal_hash, vec![who.clone()]);
-			<CouncilVoteOf<T>>::insert((proposal_hash, who.clone()), true);
-		}
-
-		fn vote(origin, proposal: T::Hash, approve: bool) {
-			let who = ensure_signed(origin)?;
-
-			ensure!(Self::is_councillor(&who), "only councillors may vote on council proposals");
-
-			if Self::vote_of((proposal, who.clone())).is_none() {
-				<ProposalVoters<T>>::mutate(proposal, |voters| voters.push(who.clone()));
-			}
-			<CouncilVoteOf<T>>::insert((proposal, who), approve);
-		}
-
-		fn veto(origin, proposal_hash: T::Hash) {
-			let who = ensure_signed(origin)?;
-
-			ensure!(Self::is_councillor(&who), "only councillors may veto council proposals");
-			ensure!(<ProposalVoters<T>>::exists(&proposal_hash), "proposal must exist to be vetoed");
-
-			let mut existing_vetoers = Self::veto_of(&proposal_hash)
-				.map(|pair| pair.1)
-				.unwrap_or_else(Vec::new);
-			let insert_position = existing_vetoers.binary_search(&who)
-				.err().ok_or("a councillor may not veto a proposal twice")?;
-			existing_vetoers.insert(insert_position, who);
-			Self::set_veto_of(
-				&proposal_hash,
-				<system::Module<T>>::block_number() + Self::cooloff_period(),
-				existing_vetoers
-			);
-
-			Self::set_proposals(
-				&Self::proposals().into_iter().filter(|&(_, h)| h != proposal_hash
-			).collect::<Vec<_>>());
-			<ProposalVoters<T>>::remove(proposal_hash);
-			<ProposalOf<T>>::remove(proposal_hash);
-			for (c, _) in <Council<T>>::active_council() {
-				<CouncilVoteOf<T>>::remove((proposal_hash, c));
-			}
-		}
-
-		fn set_cooloff_period(#[compact] blocks: T::BlockNumber) {
-			<CooloffPeriod<T>>::put(blocks);
-		}
-
-		fn set_voting_period(#[compact] blocks: T::BlockNumber) {
-			<VotingPeriod<T>>::put(blocks);
-		}
-
-		fn on_finalize(n: T::BlockNumber) {
-			if let Err(e) = Self::end_block(n) {
-				print("Guru meditation");
-				print(e);
-			}
-		}
-	}
-}
-
-decl_storage! {
-	trait Store for Module<T: Trait> as CouncilVoting {
-		pub CooloffPeriod get(cooloff_period) config(): T::BlockNumber = 1000.into();
-		pub VotingPeriod get(voting_period) config(): T::BlockNumber = 3.into();
-		/// Number of blocks by which to delay enactment of successful, non-unanimous-council-instigated referendum proposals.
-		pub EnactDelayPeriod get(enact_delay_period) config(): T::BlockNumber = 0.into();
-		pub Proposals get(proposals) build(|_| vec![]): Vec<(T::BlockNumber, T::Hash)>; // ordered by expiry.
-		pub ProposalOf get(proposal_of): map T::Hash => Option<T::Proposal>;
-		pub ProposalVoters get(proposal_voters): map T::Hash => Vec<T::AccountId>;
-		pub CouncilVoteOf get(vote_of): map (T::Hash, T::AccountId) => Option<bool>;
-		pub VetoedProposal get(veto_of): map T::Hash => Option<(T::BlockNumber, Vec<T::AccountId>)>;
-	}
-}
-
-decl_event!(
-	pub enum Event<T> where <T as system::Trait>::Hash {
-		/// A voting tally has happened for a referendum cancellation vote.
-		/// Last three are yes, no, abstain counts.
-		TallyCancelation(Hash, u32, u32, u32),
-		/// A voting tally has happened for a referendum vote.
-		/// Last three are yes, no, abstain counts.
-		TallyReferendum(Hash, u32, u32, u32),
-	}
-);
-
-impl<T: Trait> Module<T> {
-	pub fn is_vetoed<B: Borrow<T::Hash>>(proposal: B) -> bool {
-		Self::veto_of(proposal.borrow())
-			.map(|(expiry, _): (T::BlockNumber, Vec<T::AccountId>)| <system::Module<T>>::block_number() < expiry)
-			.unwrap_or(false)
-	}
-
-	pub fn will_still_be_councillor_at(who: &T::AccountId, n: T::BlockNumber) -> bool {
-		<Council<T>>::active_council().iter()
-			.find(|&&(ref a, _)| a == who)
-			.map(|&(_, expires)| expires > n)
-			.unwrap_or(false)
-	}
-
-	pub fn is_councillor(who: &T::AccountId) -> bool {
-		<Council<T>>::active_council().iter()
-			.any(|&(ref a, _)| a == who)
-	}
-
-	pub fn tally(proposal_hash: &T::Hash) -> (u32, u32, u32) {
-		Self::generic_tally(proposal_hash, |w: &T::AccountId, p: &T::Hash| Self::vote_of((*p, w.clone())))
-	}
-
-	// Private
-	fn set_veto_of(proposal: &T::Hash, expiry: T::BlockNumber, vetoers: Vec<T::AccountId>) {
-		<VetoedProposal<T>>::insert(proposal, (expiry, vetoers));
-	}
-
-	fn kill_veto_of(proposal: &T::Hash) {
-		<VetoedProposal<T>>::remove(proposal);
-	}
-
-	fn take_tally(proposal_hash: &T::Hash) -> (u32, u32, u32) {
-		Self::generic_tally(proposal_hash, |w: &T::AccountId, p: &T::Hash| <CouncilVoteOf<T>>::take((*p, w.clone())))
-	}
-
-	fn generic_tally<F: Fn(&T::AccountId, &T::Hash) -> Option<bool>>(proposal_hash: &T::Hash, vote_of: F) -> (u32, u32, u32) {
-		let c = <Council<T>>::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<(T::BlockNumber, T::Hash)>) {
-		<Proposals<T>>::put(p);
-	}
-
-	fn take_proposal_if_expiring_at(n: T::BlockNumber) -> Option<(T::Proposal, T::Hash)> {
-		let proposals = Self::proposals();
-		match proposals.first() {
-			Some(&(expiry, hash)) if expiry == n => {
-				// yes this is horrible, but fixing it will need substantial work in storage.
-				Self::set_proposals(&proposals[1..].to_vec());
-				<ProposalOf<T>>::take(hash).map(|p| (p, hash))	/* defensive only: all queued proposal hashes must have associated proposals*/
-			}
-			_ => None,
-		}
-	}
-
-	fn end_block(now: T::BlockNumber) -> Result {
-		while let Some((proposal, proposal_hash)) = Self::take_proposal_if_expiring_at(now) {
-			let tally = Self::take_tally(&proposal_hash);
-			if let Some(&democracy::Call::cancel_referendum(ref_index)) = IsSubType::<democracy::Module<T>>::is_aux_sub_type(&proposal) {
-				Self::deposit_event(RawEvent::TallyCancelation(proposal_hash, tally.0, tally.1, tally.2));
-				if let (_, 0, 0) = tally {
-					<democracy::Module<T>>::internal_cancel_referendum(ref_index.into());
-				}
-			} else {
-				Self::deposit_event(RawEvent::TallyReferendum(proposal_hash.clone(), tally.0, tally.1, tally.2));
-				if tally.0 > tally.1 + tally.2 {
-					Self::kill_veto_of(&proposal_hash);
-					// If there were no nay-votes from the council, then it's weakly uncontroversial; we enact immediately.
-					let period = match tally.1 {
-						0 => Zero::zero(),
-						_ => Self::enact_delay_period(),
-					};
-					// If all council members voted yes, then it's strongly uncontroversial; we require a negative
-					// super-majority at referendum in order to defeat it.
-					let threshold = match tally {
-						(_, 0, 0) => democracy::VoteThreshold::SuperMajorityAgainst,
-						_ => democracy::VoteThreshold::SimpleMajority,
-					};
-					<democracy::Module<T>>::internal_start_referendum(proposal, threshold, period).map(|_| ())?;
-				}
-			}
-		}
-		Ok(())
-	}
-}
-
-#[cfg(test)]
-mod tests {
-	use super::*;
-	use crate::tests::*;
-	use crate::tests::{Call, Origin};
-	use srml_support::{Hashable, assert_ok, assert_noop};
-	use democracy::{ReferendumInfo, VoteThreshold};
-
-	#[test]
-	fn basic_environment_works() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			assert_eq!(Balances::free_balance(&42), 0);
-			assert_eq!(CouncilVoting::cooloff_period(), 2);
-			assert_eq!(CouncilVoting::voting_period(), 1);
-			assert_eq!(CouncilVoting::will_still_be_councillor_at(&1, 1), true);
-			assert_eq!(CouncilVoting::will_still_be_councillor_at(&1, 10), false);
-			assert_eq!(CouncilVoting::will_still_be_councillor_at(&4, 10), false);
-			assert_eq!(CouncilVoting::is_councillor(&1), true);
-			assert_eq!(CouncilVoting::is_councillor(&4), false);
-			assert_eq!(CouncilVoting::proposals(), Vec::<(u64, H256)>::new());
-			assert_eq!(CouncilVoting::proposal_voters(H256::default()), Vec::<u64>::new());
-			assert_eq!(CouncilVoting::is_vetoed(&H256::default()), false);
-			assert_eq!(CouncilVoting::vote_of((H256::default(), 1)), None);
-			assert_eq!(CouncilVoting::tally(&H256::default()), (0, 0, 3));
-		});
-	}
-
-	fn set_balance_proposal(value: u64) -> Call {
-		Call::Balances(balances::Call::set_balance(42, value.into(), 0))
-	}
-
-	fn cancel_referendum_proposal(id: u32) -> Call {
-		Call::Democracy(democracy::Call::cancel_referendum(id.into()))
-	}
-
-	#[test]
-	fn referendum_cancellation_should_work_when_unanimous() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			assert_ok!(Democracy::internal_start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove, 0), 0);
-			assert_eq!(Democracy::active_referenda(), vec![(0, ReferendumInfo::new(4, proposal, VoteThreshold::SuperMajorityApprove, 0))]);
-
-			let cancellation = cancel_referendum_proposal(0);
-			let hash = cancellation.blake2_256().into();
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(cancellation)));
-			assert_ok!(CouncilVoting::vote(Origin::signed(2), hash, true));
-			assert_ok!(CouncilVoting::vote(Origin::signed(3), hash, true));
-			assert_eq!(CouncilVoting::proposals(), vec![(2, hash)]);
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-
-			System::set_block_number(2);
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-			assert_eq!(Democracy::active_referenda(), vec![]);
-			assert_eq!(Balances::free_balance(&42), 0);
-		});
-	}
-
-	#[test]
-	fn referendum_cancellation_should_fail_when_not_unanimous() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			assert_ok!(Democracy::internal_start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove, 0), 0);
-
-			let cancellation = cancel_referendum_proposal(0);
-			let hash = cancellation.blake2_256().into();
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(cancellation)));
-			assert_ok!(CouncilVoting::vote(Origin::signed(2), hash, true));
-			assert_ok!(CouncilVoting::vote(Origin::signed(3), hash, false));
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-
-			System::set_block_number(2);
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-			assert_eq!(Democracy::active_referenda(), vec![(0, ReferendumInfo::new(4, proposal, VoteThreshold::SuperMajorityApprove, 0))]);
-		});
-	}
-
-	#[test]
-	fn referendum_cancellation_should_fail_when_abstentions() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			assert_ok!(Democracy::internal_start_referendum(proposal.clone(), VoteThreshold::SuperMajorityApprove, 0), 0);
-
-			let cancellation = cancel_referendum_proposal(0);
-			let hash = cancellation.blake2_256().into();
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(cancellation)));
-			assert_ok!(CouncilVoting::vote(Origin::signed(2), hash, true));
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-
-			System::set_block_number(2);
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-			assert_eq!(Democracy::active_referenda(), vec![(0, ReferendumInfo::new(4, proposal, VoteThreshold::SuperMajorityApprove, 0))]);
-		});
-	}
-
-	#[test]
-	fn veto_should_work() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			let hash = proposal.blake2_256().into();
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_ok!(CouncilVoting::veto(Origin::signed(2), hash));
-			assert_eq!(CouncilVoting::proposals().len(), 0);
-			assert_eq!(Democracy::active_referenda().len(), 0);
-		});
-	}
-
-	#[test]
-	fn double_veto_should_not_work() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			let hash = proposal.blake2_256().into();
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_ok!(CouncilVoting::veto(Origin::signed(2), hash));
-
-			System::set_block_number(3);
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_noop!(CouncilVoting::veto(Origin::signed(2), hash), "a councillor may not veto a proposal twice");
-		});
-	}
-
-	#[test]
-	fn retry_in_cooloff_should_not_work() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			let hash = proposal.blake2_256().into();
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_ok!(CouncilVoting::veto(Origin::signed(2), hash));
-
-			System::set_block_number(2);
-			assert_noop!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())), "proposal is vetoed");
-		});
-	}
-
-	#[test]
-	fn retry_after_cooloff_should_work() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			let hash = proposal.blake2_256().into();
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_ok!(CouncilVoting::veto(Origin::signed(2), hash));
-
-			System::set_block_number(3);
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_ok!(CouncilVoting::vote(Origin::signed(2), hash, false));
-			assert_ok!(CouncilVoting::vote(Origin::signed(3), hash, true));
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-
-			System::set_block_number(4);
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-			assert_eq!(CouncilVoting::proposals().len(), 0);
-			assert_eq!(Democracy::active_referenda(), vec![(0, ReferendumInfo::new(7, set_balance_proposal(42), VoteThreshold::SimpleMajority, 0))]);
-		});
-	}
-
-	#[test]
-	fn alternative_double_veto_should_work() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			let hash = proposal.blake2_256().into();
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_ok!(CouncilVoting::veto(Origin::signed(2), hash));
-
-			System::set_block_number(3);
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_ok!(CouncilVoting::veto(Origin::signed(3), hash));
-			assert_eq!(CouncilVoting::proposals().len(), 0);
-			assert_eq!(Democracy::active_referenda().len(), 0);
-		});
-	}
-
-	#[test]
-	fn simple_propose_should_work() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			let hash = proposal.blake2_256().into();
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_eq!(CouncilVoting::proposals().len(), 1);
-			assert_eq!(CouncilVoting::proposal_voters(&hash), vec![1]);
-			assert_eq!(CouncilVoting::vote_of((hash, 1)), Some(true));
-			assert_eq!(CouncilVoting::tally(&hash), (1, 0, 2));
-		});
-	}
-
-	#[test]
-	fn unvoted_proposal_should_expire_without_action() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_eq!(CouncilVoting::tally(&proposal.blake2_256().into()), (1, 0, 2));
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-
-			System::set_block_number(2);
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-			assert_eq!(CouncilVoting::proposals().len(), 0);
-			assert_eq!(Democracy::active_referenda().len(), 0);
-		});
-	}
-
-	#[test]
-	fn unanimous_proposal_should_expire_with_biased_referendum() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_ok!(CouncilVoting::vote(Origin::signed(2), proposal.blake2_256().into(), true));
-			assert_ok!(CouncilVoting::vote(Origin::signed(3), proposal.blake2_256().into(), true));
-			assert_eq!(CouncilVoting::tally(&proposal.blake2_256().into()), (3, 0, 0));
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-
-			System::set_block_number(2);
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-			assert_eq!(CouncilVoting::proposals().len(), 0);
-			assert_eq!(Democracy::active_referenda(), vec![(0, ReferendumInfo::new(5, proposal, VoteThreshold::SuperMajorityAgainst, 0))]);
-		});
-	}
-
-	#[test]
-	fn majority_proposal_should_expire_with_unbiased_referendum() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_ok!(CouncilVoting::vote(Origin::signed(2), proposal.blake2_256().into(), true));
-			assert_ok!(CouncilVoting::vote(Origin::signed(3), proposal.blake2_256().into(), false));
-			assert_eq!(CouncilVoting::tally(&proposal.blake2_256().into()), (2, 1, 0));
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-
-			System::set_block_number(2);
-			assert_ok!(CouncilVoting::end_block(System::block_number()));
-			assert_eq!(CouncilVoting::proposals().len(), 0);
-			assert_eq!(Democracy::active_referenda(), vec![(0, ReferendumInfo::new(5, proposal, VoteThreshold::SimpleMajority, 0))]);
-		});
-	}
-
-	#[test]
-	fn propose_by_public_should_not_work() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			assert_noop!(CouncilVoting::propose(Origin::signed(4), Box::new(proposal)), "proposer would not be on council");
-		});
-	}
-
-	#[test]
-	fn vote_by_public_should_not_work() {
-		with_externalities(&mut new_test_ext(true), || {
-			System::set_block_number(1);
-			let proposal = set_balance_proposal(42);
-			assert_ok!(CouncilVoting::propose(Origin::signed(1), Box::new(proposal.clone())));
-			assert_noop!(CouncilVoting::vote(Origin::signed(4), proposal.blake2_256().into(), true), "only councillors may vote on council proposals");
-		});
-	}
-}
diff --git a/substrate/srml/democracy/src/lib.rs b/substrate/srml/democracy/src/lib.rs
index 1846f3462d3e46331d7bc642a917893fbb0cb9dd..96d51849c9e9288822356b20f0f4b6e406a448d9 100644
--- a/substrate/srml/democracy/src/lib.rs
+++ b/substrate/srml/democracy/src/lib.rs
@@ -20,7 +20,7 @@
 
 use rstd::prelude::*;
 use rstd::{result, convert::TryFrom};
-use primitives::traits::{Zero, Bounded, CheckedMul, CheckedDiv};
+use primitives::traits::{Zero, Bounded, CheckedMul, CheckedDiv, EnsureOrigin, Hash};
 use parity_codec::{Encode, Decode, Input, Output};
 use srml_support::{
 	decl_module, decl_storage, decl_event, ensure,
@@ -31,7 +31,7 @@ use srml_support::{
 	}
 };
 use srml_support::dispatch::Result;
-use system::ensure_signed;
+use system::{ensure_signed, ensure_root};
 
 mod vote_threshold;
 pub use vote_threshold::{Approved, VoteThreshold};
@@ -188,6 +188,29 @@ pub trait Trait: system::Trait + Sized {
 
 	/// The minimum amount to be used as a deposit for a public referendum proposal.
 	type MinimumDeposit: Get<BalanceOf<Self>>;
+
+	/// Origin from which the next tabled referendum may be forced. This is a normal
+	/// "super-majority-required" referendum.
+	type ExternalOrigin: EnsureOrigin<Self::Origin>;
+
+	/// Origin from which the next tabled referendum may be forced; this allows for the tabling of
+	/// a majority-carries referendum.
+	type ExternalMajorityOrigin: EnsureOrigin<Self::Origin>;
+
+	/// Origin from which emergency referenda may be scheduled.
+	type EmergencyOrigin: EnsureOrigin<Self::Origin>;
+
+	/// Minimum voting period allowed for an emergency referendum.
+	type EmergencyVotingPeriod: Get<Self::BlockNumber>;
+
+	/// Origin from which any referenda may be cancelled in an emergency.
+	type CancellationOrigin: EnsureOrigin<Self::Origin>;
+
+	/// Origin for anyone able to veto proposals.
+	type VetoOrigin: EnsureOrigin<Self::Origin, Success=Self::AccountId>;
+
+	/// Period in blocks where an external proposal may not be re-submitted after being vetoed.
+	type CooloffPeriod: Get<Self::BlockNumber>;
 }
 
 /// Info regarding an ongoing referendum.
@@ -252,13 +275,36 @@ decl_storage! {
 
 		/// Get the account (and lock periods) to which another account is delegating vote.
 		pub Delegations get(delegations): linked_map T::AccountId => (T::AccountId, Conviction);
+
+		/// True if the last referendum tabled was submitted externally. False if it was a public
+		/// proposal.
+		pub LastTabledWasExternal: bool;
+
+		/// The referendum to be tabled whenever it would be valid to table an external proposal.
+		/// This happens when a referendum needs to be tabled and one of two conditions are met:
+		/// - `LastTabledWasExternal` is `false`; or
+		/// - `PublicProps` is empty.
+		pub NextExternal: Option<(T::Proposal, VoteThreshold)>;
+
+		/// A record of who vetoed what. Maps proposal hash to a possible existent block number
+		/// (until when it may not be resubmitted) and who vetoed it.
+		pub Blacklist get(blacklist): map T::Hash => Option<(T::BlockNumber, Vec<T::AccountId>)>;
+
+		/// Record of all proposals that have been subject to emergency cancellation.
+		pub Cancellations: map T::Hash => bool;
 	}
 }
 
 decl_event!(
-	pub enum Event<T> where Balance = BalanceOf<T>, <T as system::Trait>::AccountId {
+	pub enum Event<T> where
+		Balance = BalanceOf<T>,
+		<T as system::Trait>::AccountId,
+		<T as system::Trait>::Hash,
+		<T as system::Trait>::BlockNumber,
+	{
 		Proposed(PropIndex, Balance),
 		Tabled(PropIndex, Balance, Vec<AccountId>),
+		ExternalTabled,
 		Started(ReferendumIndex, VoteThreshold),
 		Passed(ReferendumIndex),
 		NotPassed(ReferendumIndex),
@@ -266,6 +312,7 @@ decl_event!(
 		Executed(ReferendumIndex, bool),
 		Delegated(AccountId, AccountId),
 		Undelegated(AccountId),
+		Vetoed(AccountId, Hash, BlockNumber),
 	}
 );
 
@@ -274,8 +321,7 @@ decl_module! {
 		fn deposit_event<T>() = default;
 
 		/// Propose a sensitive action to be taken.
-		fn propose(
-			origin,
+		fn propose(origin,
 			proposal: Box<T::Proposal>,
 			#[compact] value: BalanceOf<T>
 		) {
@@ -307,7 +353,7 @@ decl_module! {
 			<DepositOf<T>>::insert(proposal, deposit);
 		}
 
-		/// Vote in a referendum. If vote is aye, the vote is to enact the proposal;
+		/// Vote in a referendum. If `vote.is_aye()`, the vote is to enact the proposal;
 		/// otherwise it is a vote to keep the status quo.
 		fn vote(origin,
 			#[compact] ref_index: ReferendumIndex,
@@ -317,8 +363,8 @@ decl_module! {
 			Self::do_vote(who, ref_index, vote)
 		}
 
-		/// Vote in a referendum on behalf of a stash. If vote is aye, the vote is to enact
-		/// the proposal; otherwise it is a vote to keep the status quo.
+		/// Vote in a referendum on behalf of a stash. If `vote.is_aye()`, the vote is to enact
+		/// the proposal;  otherwise it is a vote to keep the status quo.
 		fn proxy_vote(origin,
 			#[compact] ref_index: ReferendumIndex,
 			vote: Vote
@@ -327,18 +373,95 @@ decl_module! {
 			Self::do_vote(who, ref_index, vote)
 		}
 
-		/// Start a referendum.
-		fn start_referendum(
+		/// Schedule an emergency referendum.
+		///
+		/// This will create a new referendum for the `proposal`, approved as long as counted votes
+		/// exceed `threshold` and, if approved, enacted after the given `delay`.
+		///
+		/// It may be called from either the Root or the Emergency origin.
+		fn emergency_propose(origin,
 			proposal: Box<T::Proposal>,
 			threshold: VoteThreshold,
+			voting_period: T::BlockNumber,
 			delay: T::BlockNumber
-		) -> Result {
+		) {
+			T::EmergencyOrigin::try_origin(origin)
+				.map(|_| ())
+				.or_else(|origin| ensure_root(origin))?;
+			let now = <system::Module<T>>::block_number();
+			// We don't consider it an error if `vote_period` is too low, but we do enforce the
+			// minimum. This is primarily due to practicality. If it's an emergency, we don't want
+			// to introduce more delays than is strictly needed by requiring a potentially costly
+			// resubmission in the case of a mistakenly low `vote_period`; better to just let the
+			// referendum take place with the lowest valid value.
+			let period = voting_period.max(T::EmergencyVotingPeriod::get());
 			Self::inject_referendum(
-				<system::Module<T>>::block_number() + T::VotingPeriod::get(),
+				now + period,
 				*proposal,
 				threshold,
 				delay,
-			).map(|_| ())
+			).map(|_| ())?;
+		}
+
+		/// Schedule an emergency cancellation of a referendum. Cannot happen twice to the same
+		/// referendum.
+		fn emergency_cancel(origin, ref_index: ReferendumIndex) {
+			T::CancellationOrigin::ensure_origin(origin)?;
+
+			let info = Self::referendum_info(ref_index).ok_or("unknown index")?;
+			let h = T::Hashing::hash_of(&info.proposal);
+			ensure!(!<Cancellations<T>>::exists(h), "cannot cancel the same proposal twice");
+
+			<Cancellations<T>>::insert(h, true);
+			Self::clear_referendum(ref_index);
+		}
+
+		/// Schedule a referendum to be tabled once it is legal to schedule an external
+		/// referendum.
+		fn external_propose(origin, proposal: Box<T::Proposal>) {
+			T::ExternalOrigin::ensure_origin(origin)?;
+			ensure!(!<NextExternal<T>>::exists(), "proposal already made");
+			let proposal_hash = T::Hashing::hash_of(&proposal);
+			if let Some((until, _)) = <Blacklist<T>>::get(proposal_hash) {
+				ensure!(<system::Module<T>>::block_number() >= until, "proposal still blacklisted");
+			}
+			<NextExternal<T>>::put((*proposal, VoteThreshold::SuperMajorityApprove));
+		}
+
+		/// Schedule a majority-carries referendum to be tabled next once it is legal to schedule
+		/// an external referendum.
+		fn external_propose_majority(origin, proposal: Box<T::Proposal>) {
+			T::ExternalMajorityOrigin::ensure_origin(origin)?;
+			ensure!(!<NextExternal<T>>::exists(), "proposal already made");
+			let proposal_hash = T::Hashing::hash_of(&proposal);
+			if let Some((until, _)) = <Blacklist<T>>::get(proposal_hash) {
+				ensure!(<system::Module<T>>::block_number() >= until, "proposal still blacklisted");
+			}
+			<NextExternal<T>>::put((*proposal, VoteThreshold::SimpleMajority));
+		}
+
+		/// Veto and blacklist the external proposal hash.
+		fn veto_external(origin, proposal_hash: T::Hash) {
+			let who = T::VetoOrigin::ensure_origin(origin)?;
+
+			if let Some((proposal, _)) = <NextExternal<T>>::get() {
+				ensure!(proposal_hash == T::Hashing::hash_of(&proposal), "unknown proposal");
+			} else {
+				Err("no external proposal")?;
+			}
+
+			let mut existing_vetoers = <Blacklist<T>>::get(&proposal_hash)
+				.map(|pair| pair.1)
+				.unwrap_or_else(Vec::new);
+			let insert_position = existing_vetoers.binary_search(&who)
+				.err().ok_or("identity may not veto a proposal twice")?;
+
+			existing_vetoers.insert(insert_position, who.clone());
+			let until = <system::Module<T>>::block_number() + T::CooloffPeriod::get();
+			<Blacklist<T>>::insert(&proposal_hash, (until, existing_vetoers));
+
+			Self::deposit_event(RawEvent::Vetoed(who, proposal_hash, until));
+			<NextExternal<T>>::kill();
 		}
 
 		/// Remove a referendum.
@@ -347,12 +470,19 @@ decl_module! {
 		}
 
 		/// Cancel a proposal queued for enactment.
-		pub fn cancel_queued(#[compact] when: T::BlockNumber, #[compact] which: u32) {
+		fn cancel_queued(
+			#[compact] when: T::BlockNumber,
+			#[compact] which: u32,
+			#[compact] what: ReferendumIndex
+		) {
 			let which = which as usize;
-			<DispatchQueue<T>>::mutate(
-				when,
-				|items| if items.len() > which { items[which] = None }
-			);
+			let mut items = <DispatchQueue<T>>::get(when);
+			if items.get(which).and_then(Option::as_ref).map_or(false, |x| x.1 == what) {
+				items[which] = None;
+				<DispatchQueue<T>>::insert(when, items);
+			} else {
+				Err("proposal not found")?
+			}
 		}
 
 		fn on_finalize(n: T::BlockNumber) {
@@ -603,7 +733,34 @@ impl<T: Trait> Module<T> {
 		Self::deposit_event(RawEvent::Executed(index, ok));
 	}
 
+	/// Table the next waiting proposal for a vote.
 	fn launch_next(now: T::BlockNumber) -> Result {
+		if <LastTabledWasExternal<T>>::take() {
+			Self::launch_public(now).or_else(|_| Self::launch_external(now))
+		} else {
+			Self::launch_external(now).or_else(|_| Self::launch_public(now))
+		}.map_err(|_| "No proposals waiting")
+	}
+
+	/// Table the waiting external proposal for a vote, if there is one.
+	fn launch_external(now: T::BlockNumber) -> Result {
+		if let Some((proposal, threshold)) = <NextExternal<T>>::take() {
+			<LastTabledWasExternal<T>>::put(true);
+			Self::deposit_event(RawEvent::ExternalTabled);
+			Self::inject_referendum(
+				now + T::VotingPeriod::get(),
+				proposal,
+				threshold,
+				T::EnactmentPeriod::get(),
+			)?;
+			Ok(())
+		} else {
+			Err("No external proposal waiting")
+		}
+	}
+
+	/// Table the waiting public proposal with the highest backing for a vote.
+	fn launch_public(now: T::BlockNumber) -> Result {
 		let mut public_props = Self::public_props();
 		if let Some((winner_index, _)) = public_props.iter()
 			.enumerate()
@@ -626,9 +783,11 @@ impl<T: Trait> Module<T> {
 					T::EnactmentPeriod::get(),
 				)?;
 			}
+			Ok(())
+		} else {
+			Err("No public proposals waiting")
 		}
 
-		Ok(())
 	}
 
 	fn bake_referendum(
@@ -682,11 +841,13 @@ impl<T: Trait> Module<T> {
 	}
 
 	/// Current era is ending; we should finish up any proposals.
-	// TODO: move to `initialize_block
+	// TODO: move to initialize_block #2779
 	fn end_block(now: T::BlockNumber) -> Result {
 		// pick out another public referendum if it's time.
 		if (now % T::LaunchPeriod::get()).is_zero() {
-			Self::launch_next(now.clone())?;
+			// Errors come from the queue being empty. we don't really care about that, and even if
+			// we did, there is nothing we can do here.
+			let _ = Self::launch_next(now.clone());
 		}
 
 		// tally up votes for any expiring referenda.
@@ -712,13 +873,15 @@ mod tests {
 	use super::*;
 	use runtime_io::with_externalities;
 	use srml_support::{
-		impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types
+		impl_outer_origin, impl_outer_dispatch, assert_noop, assert_ok, parameter_types,
+		traits::Contains
 	};
 	use substrate_primitives::{H256, Blake2Hasher};
 	use primitives::BuildStorage;
 	use primitives::traits::{BlakeTwo256, IdentityLookup, Bounded};
 	use primitives::testing::{Digest, DigestItem, Header};
 	use balances::BalanceLock;
+	use system::EnsureSignedBy;
 
 	const AYE: Vote = Vote{ aye: true, conviction: Conviction::None };
 	const NAY: Vote = Vote{ aye: false, conviction: Conviction::None };
@@ -762,19 +925,39 @@ mod tests {
 		type DustRemoval = ();
 	}
 	parameter_types! {
-		pub const LaunchPeriod: u64 = 1;
-		pub const VotingPeriod: u64 = 1;
+		pub const LaunchPeriod: u64 = 2;
+		pub const VotingPeriod: u64 = 2;
+		pub const EmergencyVotingPeriod: u64 = 1;
 		pub const MinimumDeposit: u64 = 1;
-		pub const EnactmentPeriod: u64 = 1;
+		pub const EnactmentPeriod: u64 = 2;
+		pub const CooloffPeriod: u64 = 2;
+		pub const One: u64 = 1;
+		pub const Two: u64 = 2;
+		pub const Three: u64 = 3;
+		pub const Four: u64 = 4;
+		pub const Five: u64 = 5;
+	}
+	pub struct OneToFive;
+	impl Contains<u64> for OneToFive {
+		fn contains(n: &u64) -> bool {
+			*n >= 1 && *n <= 5
+		}
 	}
-	impl Trait for Test {
+	impl super::Trait for Test {
 		type Proposal = Call;
 		type Event = ();
 		type Currency = balances::Module<Self>;
 		type EnactmentPeriod = EnactmentPeriod;
 		type LaunchPeriod = LaunchPeriod;
 		type VotingPeriod = VotingPeriod;
+		type EmergencyVotingPeriod = EmergencyVotingPeriod;
 		type MinimumDeposit = MinimumDeposit;
+		type EmergencyOrigin = EnsureSignedBy<One, u64>;
+		type ExternalOrigin = EnsureSignedBy<Two, u64>;
+		type ExternalMajorityOrigin = EnsureSignedBy<Three, u64>;
+		type CancellationOrigin = EnsureSignedBy<Four, u64>;
+		type VetoOrigin = EnsureSignedBy<OneToFive, u64>;
+		type CooloffPeriod = CooloffPeriod;
 	}
 
 	fn new_test_ext() -> runtime_io::TestExternalities<Blake2Hasher> {
@@ -806,13 +989,14 @@ mod tests {
 	}
 
 	fn set_balance_proposal(value: u64) -> Call {
-		Call::Balances(balances::Call::set_balance(42, value.into(), 0))
+		Call::Balances(balances::Call::set_balance(42, value, 0))
 	}
 
-	fn propose_set_balance(who: u64, value: u64, locked: u64) -> super::Result {
+	fn propose_set_balance(who: u64, value: u64, delay: u64) -> super::Result {
 		Democracy::propose(
 			Origin::signed(who),
-			Box::new(set_balance_proposal(value)), locked.into()
+			Box::new(set_balance_proposal(value)),
+			delay
 		)
 	}
 
@@ -821,6 +1005,326 @@ mod tests {
 		System::set_block_number(System::block_number() + 1);
 	}
 
+	fn fast_forward_to(n: u64) {
+		while System::block_number() < n {
+			next_block();
+		}
+	}
+
+	#[test]
+	fn external_and_public_interleaving_works() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(0);
+			assert_ok!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(1)),
+			));
+			assert_ok!(propose_set_balance(6, 2, 2));
+
+			fast_forward_to(1);
+
+			// both waiting: external goes first.
+			assert_eq!(
+				Democracy::referendum_info(0),
+				Some(ReferendumInfo {
+					end: 2,
+					proposal: set_balance_proposal(1),
+					threshold: VoteThreshold::SuperMajorityApprove,
+					delay: 2
+				})
+			);
+			// replenish external
+			assert_ok!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(3)),
+			));
+
+			fast_forward_to(3);
+
+			// both waiting: public goes next.
+			assert_eq!(
+				Democracy::referendum_info(1),
+				Some(ReferendumInfo {
+					end: 4,
+					proposal: set_balance_proposal(2),
+					threshold: VoteThreshold::SuperMajorityApprove,
+					delay: 2
+				})
+			);
+			// don't replenish public
+
+			fast_forward_to(5);
+
+			// it's external "turn" again, though since public is empty that doesn't really matter
+			assert_eq!(
+				Democracy::referendum_info(2),
+				Some(ReferendumInfo {
+					end: 6,
+					proposal: set_balance_proposal(3),
+					threshold: VoteThreshold::SuperMajorityApprove,
+					delay: 2
+				})
+			);
+			// replenish external
+			assert_ok!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(5)),
+			));
+
+			fast_forward_to(7);
+
+			// external goes again because there's no public waiting.
+			assert_eq!(
+				Democracy::referendum_info(3),
+				Some(ReferendumInfo {
+					end: 8,
+					proposal: set_balance_proposal(5),
+					threshold: VoteThreshold::SuperMajorityApprove,
+					delay: 2
+				})
+			);
+			// replenish both
+			assert_ok!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(7)),
+			));
+			assert_ok!(propose_set_balance(6, 4, 2));
+
+			fast_forward_to(9);
+
+			// public goes now since external went last time.
+			assert_eq!(
+				Democracy::referendum_info(4),
+				Some(ReferendumInfo {
+					end: 10,
+					proposal: set_balance_proposal(4),
+					threshold: VoteThreshold::SuperMajorityApprove,
+					delay: 2
+				})
+			);
+			// replenish public again
+			assert_ok!(propose_set_balance(6, 6, 2));
+			// cancel external
+			let h = BlakeTwo256::hash_of(&set_balance_proposal(7));
+			assert_ok!(Democracy::veto_external(Origin::signed(3), h));
+
+			fast_forward_to(11);
+
+			// public goes again now since there's no external waiting.
+			assert_eq!(
+				Democracy::referendum_info(5),
+				Some(ReferendumInfo {
+					end: 12,
+					proposal: set_balance_proposal(6),
+					threshold: VoteThreshold::SuperMajorityApprove,
+					delay: 2
+				})
+			);
+		});
+	}
+
+
+	#[test]
+	fn emergency_cancel_should_work() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(0);
+			let r = Democracy::inject_referendum(
+				2,
+				set_balance_proposal(2),
+				VoteThreshold::SuperMajorityApprove,
+				2
+			).unwrap();
+			assert!(Democracy::referendum_info(r).is_some());
+
+			assert_noop!(Democracy::emergency_cancel(Origin::signed(3), r), "Invalid origin");
+			assert_ok!(Democracy::emergency_cancel(Origin::signed(4), r));
+			assert!(Democracy::referendum_info(r).is_none());
+
+			// some time later...
+
+			let r = Democracy::inject_referendum(
+				2,
+				set_balance_proposal(2),
+				VoteThreshold::SuperMajorityApprove,
+				2
+			).unwrap();
+			assert!(Democracy::referendum_info(r).is_some());
+			assert_noop!(Democracy::emergency_cancel(Origin::signed(4), r), "cannot cancel the same proposal twice");
+		});
+	}
+
+	#[test]
+	fn veto_external_works() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(0);
+			assert_ok!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(2)),
+			));
+			assert!(<NextExternal<Test>>::exists());
+
+			let h = BlakeTwo256::hash_of(&set_balance_proposal(2));
+			assert_ok!(Democracy::veto_external(Origin::signed(3), h.clone()));
+			// cancelled.
+			assert!(!<NextExternal<Test>>::exists());
+			// fails - same proposal can't be resubmitted.
+			assert_noop!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(2)),
+			), "proposal still blacklisted");
+
+			fast_forward_to(1);
+			// fails as we're still in cooloff period.
+			assert_noop!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(2)),
+			), "proposal still blacklisted");
+
+			fast_forward_to(2);
+			// works; as we're out of the cooloff period.
+			assert_ok!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(2)),
+			));
+			assert!(<NextExternal<Test>>::exists());
+
+			// 3 can't veto the same thing twice.
+			assert_noop!(
+				Democracy::veto_external(Origin::signed(3), h.clone()),
+				"identity may not veto a proposal twice"
+			);
+
+			// 4 vetoes.
+			assert_ok!(Democracy::veto_external(Origin::signed(4), h.clone()));
+			// cancelled again.
+			assert!(!<NextExternal<Test>>::exists());
+
+			fast_forward_to(3);
+			// same proposal fails as we're still in cooloff
+			assert_noop!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(2)),
+			), "proposal still blacklisted");
+			// different proposal works fine.
+			assert_ok!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(3)),
+			));
+		});
+	}
+
+	#[test]
+	fn emergency_referendum_works() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(0);
+			assert_noop!(Democracy::emergency_propose(
+				Origin::signed(6),  // invalid
+				Box::new(set_balance_proposal(2)),
+				VoteThreshold::SuperMajorityAgainst,
+				0,
+				0,
+			), "bad origin: expected to be a root origin");
+			assert_ok!(Democracy::emergency_propose(
+				Origin::signed(1),
+				Box::new(set_balance_proposal(2)),
+				VoteThreshold::SuperMajorityAgainst,
+				0,
+				0,
+			));
+			assert_eq!(
+				Democracy::referendum_info(0),
+				Some(ReferendumInfo {
+					end: 1,
+					proposal: set_balance_proposal(2),
+					threshold: VoteThreshold::SuperMajorityAgainst,
+					delay: 0
+				})
+			);
+
+			assert_ok!(Democracy::vote(Origin::signed(1), 0, AYE));
+			fast_forward_to(1);
+			assert_eq!(Balances::free_balance(&42), 0);
+			fast_forward_to(2);
+			assert_eq!(Balances::free_balance(&42), 2);
+
+			assert_ok!(Democracy::emergency_propose(
+				Origin::signed(1),
+				Box::new(set_balance_proposal(4)),
+				VoteThreshold::SuperMajorityAgainst,
+				3,
+				3
+			));
+			assert_eq!(
+				Democracy::referendum_info(1),
+				Some(ReferendumInfo {
+					end: 5,
+					proposal: set_balance_proposal(4),
+					threshold: VoteThreshold::SuperMajorityAgainst,
+					delay: 3
+				})
+			);
+			assert_ok!(Democracy::vote(Origin::signed(1), 1, AYE));
+			fast_forward_to(8);
+			assert_eq!(Balances::free_balance(&42), 2);
+			fast_forward_to(9);
+			assert_eq!(Balances::free_balance(&42), 4);
+		});
+	}
+
+	#[test]
+	fn external_referendum_works() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(0);
+			assert_noop!(Democracy::external_propose(
+				Origin::signed(1),
+				Box::new(set_balance_proposal(2)),
+			), "Invalid origin");
+			assert_ok!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(2)),
+			));
+			assert_noop!(Democracy::external_propose(
+				Origin::signed(2),
+				Box::new(set_balance_proposal(1)),
+			), "proposal already made");
+			fast_forward_to(1);
+			assert_eq!(
+				Democracy::referendum_info(0),
+				Some(ReferendumInfo {
+					end: 2,
+					proposal: set_balance_proposal(2),
+					threshold: VoteThreshold::SuperMajorityApprove,
+					delay: 2
+				})
+			);
+		});
+	}
+
+	#[test]
+	fn external_majority_referendum_works() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(0);
+			assert_noop!(Democracy::external_propose_majority(
+				Origin::signed(1),
+				Box::new(set_balance_proposal(2))
+			), "Invalid origin");
+			assert_ok!(Democracy::external_propose_majority(
+				Origin::signed(3),
+				Box::new(set_balance_proposal(2))
+			));
+			fast_forward_to(1);
+			assert_eq!(
+				Democracy::referendum_info(0),
+				Some(ReferendumInfo {
+					end: 2,
+					proposal: set_balance_proposal(2),
+					threshold: VoteThreshold::SimpleMajority,
+					delay: 2,
+				})
+			);
+		});
+	}
+
 	#[test]
 	fn locked_for_should_work() {
 		with_externalities(&mut new_test_ext(), || {
@@ -837,25 +1341,74 @@ mod tests {
 	#[test]
 	fn single_proposal_should_work() {
 		with_externalities(&mut new_test_ext(), || {
-			System::set_block_number(1);
+			System::set_block_number(0);
 			assert_ok!(propose_set_balance(1, 2, 1));
-			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+			assert!(Democracy::referendum_info(0).is_none());
+
+			// end of 0 => next referendum scheduled.
+			fast_forward_to(1);
 
-			System::set_block_number(2);
 			let r = 0;
 			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
 
 			assert_eq!(Democracy::referendum_count(), 1);
+			assert_eq!(
+				Democracy::referendum_info(0),
+				Some(ReferendumInfo {
+					end: 2,
+					proposal: set_balance_proposal(2),
+					threshold: VoteThreshold::SuperMajorityApprove,
+					delay: 2
+				})
+			);
 			assert_eq!(Democracy::voters_for(r), vec![1]);
 			assert_eq!(Democracy::vote_of((r, 1)), AYE);
 			assert_eq!(Democracy::tally(r), (1, 0, 1));
 
-			next_block();
-			next_block();
+			fast_forward_to(2);
+
+			// referendum still running
+			assert!(Democracy::referendum_info(0).is_some());
+
+			// referendum runs during 1 and 2, ends @ end of 2.
+			fast_forward_to(3);
+
+			assert!(Democracy::referendum_info(0).is_none());
+			assert_eq!(Democracy::dispatch_queue(4), vec![
+				Some((set_balance_proposal(2), 0))
+			]);
+
+			// referendum passes and wait another two blocks for enactment.
+			fast_forward_to(5);
+
 			assert_eq!(Balances::free_balance(&42), 2);
 		});
 	}
 
+	#[test]
+	fn cancel_queued_should_work() {
+		with_externalities(&mut new_test_ext(), || {
+			System::set_block_number(0);
+			assert_ok!(propose_set_balance(1, 2, 1));
+
+			// end of 0 => next referendum scheduled.
+			fast_forward_to(1);
+
+			assert_ok!(Democracy::vote(Origin::signed(1), 0, AYE));
+
+			fast_forward_to(3);
+
+			assert_eq!(Democracy::dispatch_queue(4), vec![
+				Some((set_balance_proposal(2), 0))
+			]);
+
+			assert_noop!(Democracy::cancel_queued(3, 0, 0), "proposal not found");
+			assert_noop!(Democracy::cancel_queued(4, 1, 0), "proposal not found");
+			assert_ok!(Democracy::cancel_queued(4, 0, 0));
+			assert_eq!(Democracy::dispatch_queue(4), vec![None]);
+		});
+	}
+
 	#[test]
 	fn proxy_should_work() {
 		with_externalities(&mut new_test_ext(), || {
@@ -889,22 +1442,19 @@ mod tests {
 	#[test]
 	fn single_proposal_should_work_with_proxy() {
 		with_externalities(&mut new_test_ext(), || {
-			System::set_block_number(1);
+			System::set_block_number(0);
 			assert_ok!(propose_set_balance(1, 2, 1));
-			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
 
-			System::set_block_number(2);
+			fast_forward_to(1);
 			let r = 0;
 			assert_ok!(Democracy::set_proxy(Origin::signed(1), 10));
 			assert_ok!(Democracy::proxy_vote(Origin::signed(10), r, AYE));
 
-			assert_eq!(Democracy::referendum_count(), 1);
 			assert_eq!(Democracy::voters_for(r), vec![1]);
 			assert_eq!(Democracy::vote_of((r, 1)), AYE);
 			assert_eq!(Democracy::tally(r), (1, 0, 1));
 
-			next_block();
-			next_block();
+			fast_forward_to(5);
 			assert_eq!(Balances::free_balance(&42), 2);
 		});
 	}
@@ -912,27 +1462,23 @@ mod tests {
 	#[test]
 	fn single_proposal_should_work_with_delegation() {
 		with_externalities(&mut new_test_ext(), || {
-			System::set_block_number(1);
+			System::set_block_number(0);
 
 			assert_ok!(propose_set_balance(1, 2, 1));
 
-			next_block();
-			let r = 0;
+			fast_forward_to(1);
 
 			// Delegate vote.
 			assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value()));
 
+			let r = 0;
 			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
-
-			assert_eq!(Democracy::referendum_count(), 1);
 			assert_eq!(Democracy::voters_for(r), vec![1]);
 			assert_eq!(Democracy::vote_of((r, 1)), AYE);
-
 			// Delegated vote is counted.
 			assert_eq!(Democracy::tally(r), (3, 0, 3));
 
-			next_block();
-			next_block();
+			fast_forward_to(5);
 
 			assert_eq!(Balances::free_balance(&42), 2);
 		});
@@ -941,27 +1487,24 @@ mod tests {
 	#[test]
 	fn single_proposal_should_work_with_cyclic_delegation() {
 		with_externalities(&mut new_test_ext(), || {
-			System::set_block_number(1);
+			System::set_block_number(0);
 
 			assert_ok!(propose_set_balance(1, 2, 1));
 
-			next_block();
-			let r = 0;
+			fast_forward_to(1);
 
 			// Check behavior with cycle.
 			assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value()));
 			assert_ok!(Democracy::delegate(Origin::signed(3), 2, Conviction::max_value()));
 			assert_ok!(Democracy::delegate(Origin::signed(1), 3, Conviction::max_value()));
-
+			let r = 0;
 			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
-
-			assert_eq!(Democracy::referendum_count(), 1);
 			assert_eq!(Democracy::voters_for(r), vec![1]);
 
 			// Delegated vote is counted.
 			assert_eq!(Democracy::tally(r), (6, 0, 6));
-			next_block();
-			next_block();
+
+			fast_forward_to(5);
 
 			assert_eq!(Balances::free_balance(&42), 2);
 		});
@@ -971,30 +1514,24 @@ mod tests {
 	/// If transactor already voted, delegated vote is overwriten.
 	fn single_proposal_should_work_with_vote_and_delegation() {
 		with_externalities(&mut new_test_ext(), || {
-			System::set_block_number(1);
+			System::set_block_number(0);
 
 			assert_ok!(propose_set_balance(1, 2, 1));
 
-			next_block();
-			let r = 0;
+			fast_forward_to(1);
 
+			let r = 0;
 			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
-
 			// Vote.
 			assert_ok!(Democracy::vote(Origin::signed(2), r, AYE));
-
 			// Delegate vote.
 			assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value()));
-
-			assert_eq!(Democracy::referendum_count(), 1);
 			assert_eq!(Democracy::voters_for(r), vec![1, 2]);
 			assert_eq!(Democracy::vote_of((r, 1)), AYE);
-
 			// Delegated vote is not counted.
 			assert_eq!(Democracy::tally(r), (3, 0, 3));
 
-			next_block();
-			next_block();
+			fast_forward_to(5);
 
 			assert_eq!(Balances::free_balance(&42), 2);
 		});
@@ -1003,7 +1540,7 @@ mod tests {
 	#[test]
 	fn single_proposal_should_work_with_undelegation() {
 		with_externalities(&mut new_test_ext(), || {
-			System::set_block_number(1);
+			System::set_block_number(0);
 
 			assert_ok!(propose_set_balance(1, 2, 1));
 
@@ -1011,7 +1548,7 @@ mod tests {
 			assert_ok!(Democracy::delegate(Origin::signed(2), 1, Conviction::max_value()));
 			assert_ok!(Democracy::undelegate(Origin::signed(2)));
 
-			next_block();
+			fast_forward_to(1);
 			let r = 0;
 			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
 
@@ -1022,8 +1559,7 @@ mod tests {
 			// Delegated vote is not counted.
 			assert_eq!(Democracy::tally(r), (1, 0, 1));
 
-			next_block();
-			next_block();
+			fast_forward_to(5);
 
 			assert_eq!(Balances::free_balance(&42), 2);
 		});
@@ -1033,11 +1569,11 @@ mod tests {
 	/// If transactor voted, delegated vote is overwriten.
 	fn single_proposal_should_work_with_delegation_and_vote() {
 		with_externalities(&mut new_test_ext(), || {
-			System::set_block_number(1);
+			System::set_block_number(0);
 
 			assert_ok!(propose_set_balance(1, 2, 1));
 
-			next_block();
+			fast_forward_to(1);
 			let r = 0;
 
 			assert_ok!(Democracy::vote(Origin::signed(1), r, AYE));
@@ -1055,8 +1591,7 @@ mod tests {
 			// Delegated vote is not counted.
 			assert_eq!(Democracy::tally(r), (3, 0, 3));
 
-			next_block();
-			next_block();
+			fast_forward_to(5);
 
 			assert_eq!(Balances::free_balance(&42), 2);
 		});
@@ -1086,7 +1621,7 @@ mod tests {
 			assert_ok!(Democracy::second(Origin::signed(5), 0));
 			assert_ok!(Democracy::second(Origin::signed(5), 0));
 			assert_ok!(Democracy::second(Origin::signed(5), 0));
-			assert_eq!(Democracy::end_block(System::block_number()), Ok(()));
+			fast_forward_to(3);
 			assert_eq!(Balances::free_balance(&1), 10);
 			assert_eq!(Balances::free_balance(&2), 20);
 			assert_eq!(Balances::free_balance(&5), 50);
@@ -1125,11 +1660,11 @@ mod tests {
 			assert_ok!(propose_set_balance(1, 2, 2));
 			assert_ok!(propose_set_balance(1, 4, 4));
 			assert_ok!(propose_set_balance(1, 3, 3));
-			next_block();
+			fast_forward_to(1);
 			assert_ok!(Democracy::vote(Origin::signed(1), 0, AYE));
-			next_block();
+			fast_forward_to(3);
 			assert_ok!(Democracy::vote(Origin::signed(1), 1, AYE));
-			next_block();
+			fast_forward_to(5);
 			assert_ok!(Democracy::vote(Origin::signed(1), 2, AYE));
 		});
 	}
@@ -1305,7 +1840,7 @@ mod tests {
 	#[test]
 	fn lock_voting_should_work() {
 		with_externalities(&mut new_test_ext(), || {
-			System::set_block_number(1);
+			System::set_block_number(0);
 			let r = Democracy::inject_referendum(
 				1,
 				set_balance_proposal(2),
@@ -1335,31 +1870,29 @@ mod tests {
 
 			assert_eq!(Democracy::tally(r), (250, 100, 150));
 
-			next_block();
+			fast_forward_to(2);
 
 			assert_eq!(Balances::locks(1), vec![]);
 			assert_eq!(Balances::locks(2), vec![BalanceLock {
 				id: DEMOCRACY_ID,
 				amount: u64::max_value(),
-				until: 9,
+				until: 17,
 				reasons: WithdrawReason::Transfer.into()
 			}]);
 			assert_eq!(Balances::locks(3), vec![BalanceLock {
 				id: DEMOCRACY_ID,
 				amount: u64::max_value(),
-				until: 5,
+				until: 9,
 				reasons: WithdrawReason::Transfer.into()
 			}]);
 			assert_eq!(Balances::locks(4), vec![BalanceLock {
 				id: DEMOCRACY_ID,
 				amount: u64::max_value(),
-				until: 3,
+				until: 5,
 				reasons: WithdrawReason::Transfer.into()
 			}]);
 			assert_eq!(Balances::locks(5), vec![]);
 
-			next_block();
-
 			assert_eq!(Balances::free_balance(&42), 2);
 		});
 	}
@@ -1395,28 +1928,6 @@ mod tests {
 			assert_eq!(Democracy::tally(r), (250, 100, 150));
 
 			next_block();
-
-			assert_eq!(Balances::locks(1), vec![]);
-			assert_eq!(Balances::locks(2), vec![BalanceLock {
-				id: DEMOCRACY_ID,
-				amount: u64::max_value(),
-				until: 9,
-				reasons: WithdrawReason::Transfer.into()
-			}]);
-			assert_eq!(Balances::locks(3), vec![BalanceLock {
-				id: DEMOCRACY_ID,
-				amount: u64::max_value(),
-				until: 5,
-				reasons: WithdrawReason::Transfer.into()
-			}]);
-			assert_eq!(Balances::locks(4), vec![BalanceLock {
-				id: DEMOCRACY_ID,
-				amount: u64::max_value(),
-				until: u64::max_value(),
-				reasons: WithdrawReason::Transfer.into()
-			}]);
-			assert_eq!(Balances::locks(5), vec![]);
-
 			next_block();
 
 			assert_eq!(Balances::free_balance(&42), 2);
diff --git a/substrate/srml/support/src/metadata.rs b/substrate/srml/support/src/metadata.rs
index b1da7587be390d18789d0eb1a853a450d5e20790..ed3e443afdcf414cfb718b1b0aafabd9a4e2b535 100644
--- a/substrate/srml/support/src/metadata.rs
+++ b/substrate/srml/support/src/metadata.rs
@@ -246,7 +246,8 @@ mod tests {
 
 	mod system {
 		pub trait Trait {
-			type Origin: Into<Option<RawOrigin<Self::AccountId>>> + From<RawOrigin<Self::AccountId>>;
+			type Origin: Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>
+				+ From<RawOrigin<Self::AccountId>>;
 			type AccountId;
 			type BlockNumber;
 		}
diff --git a/substrate/srml/support/src/origin.rs b/substrate/srml/support/src/origin.rs
index 48d4be80c6f984b068c0e882bb6ace3b1be27397..9bc2cab8b9d178630144cfee9d44c3485fef0f1e 100644
--- a/substrate/srml/support/src/origin.rs
+++ b/substrate/srml/support/src/origin.rs
@@ -112,12 +112,12 @@ macro_rules! impl_outer_origin {
 				$name::system(x)
 			}
 		}
-		impl Into<Option<$system::Origin<$runtime>>> for $name {
-			fn into(self) -> Option<$system::Origin<$runtime>> {
+		impl Into<$crate::rstd::result::Result<$system::Origin<$runtime>, $name>> for $name {
+			fn into(self) -> $crate::rstd::result::Result<$system::Origin<$runtime>, Self> {
 				if let $name::system(l) = self {
-					Some(l)
+					Ok(l)
 				} else {
-					None
+					Err(self)
 				}
 			}
 		}
@@ -132,12 +132,18 @@ macro_rules! impl_outer_origin {
 					$name::$module(x)
 				}
 			}
-			impl Into<Option<$module::Origin $( <$generic_param $(, $generic_instance )? > )*>> for $name {
-				fn into(self) -> Option<$module::Origin $( <$generic_param $(, $generic_instance )? > )*> {
+			impl Into<$crate::rstd::result::Result<
+				$module::Origin $( <$generic_param $(, $generic_instance )? > )*,
+				$name
+			>> for $name {
+				fn into(self) -> $crate::rstd::result::Result<
+					$module::Origin $( <$generic_param $(, $generic_instance )? > )*,
+					Self
+				> {
 					if let $name::$module(l) = self {
-						Some(l)
+						Ok(l)
 					} else {
-						None
+						Err(self)
 					}
 				}
 			}
diff --git a/substrate/srml/support/src/traits.rs b/substrate/srml/support/src/traits.rs
index 599de27c2ec3de0268d423dfd1bf287969ffe0b5..3b3c63e223ce14831368094bf3b882a929c89f74 100644
--- a/substrate/srml/support/src/traits.rs
+++ b/substrate/srml/support/src/traits.rs
@@ -26,12 +26,26 @@ use crate::runtime_primitives::traits::{
 
 use super::for_each_tuple;
 
-/// New trait for querying a single fixed value from a type.
+/// A trait for querying a single fixed value from a type.
 pub trait Get<T> {
 	/// Return a constant value.
 	fn get() -> T;
 }
 
+/// A trait for querying whether a type can be said to statically "contain" a value. Similar
+/// in nature to `Get`, except it is designed to be lazy rather than active (you can't ask it to
+/// enumerate all values that it contains) and work for multiple values rather than just one.
+pub trait Contains<T> {
+	/// Return `true` if this "contains" the given value `t`.
+	fn contains(t: &T) -> bool;
+}
+
+impl<V: PartialEq, T: Get<V>> Contains<V> for T {
+	fn contains(t: &V) -> bool {
+		&Self::get() == t
+	}
+}
+
 /// The account with the given id was killed.
 pub trait OnFreeBalanceZero<AccountId> {
 	/// The account was the given id was killed.
diff --git a/substrate/srml/support/test/tests/instance.rs b/substrate/srml/support/test/tests/instance.rs
index 641ad9f4b56f475b922f13706c28f1910887dcb4..796934777d9139a8ab7f2191e3579e5b260723f6 100644
--- a/substrate/srml/support/test/tests/instance.rs
+++ b/substrate/srml/support/test/tests/instance.rs
@@ -39,7 +39,8 @@ mod system {
 	use super::*;
 
 	pub trait Trait: 'static + Eq + Clone {
-		type Origin: Into<Option<RawOrigin<Self::AccountId>>> + From<RawOrigin<Self::AccountId>>;
+		type Origin: Into<Result<RawOrigin<Self::AccountId>, Self::Origin>>
+			+ From<RawOrigin<Self::AccountId>>;
 		type BlockNumber;
 		type Digest: Digest<Hash = H256>;
 		type Hash;
@@ -100,12 +101,9 @@ mod system {
 	}
 
 	pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), &'static str>
-		where OuterOrigin: Into<Option<RawOrigin<AccountId>>>
+		where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
 	{
-		match o.into() {
-			Some(RawOrigin::Root) => Ok(()),
-			_ => Err("bad origin: expected to be a root origin"),
-		}
+		o.into().map(|_| ()).map_err(|_| "bad origin: expected to be a root origin")
 	}
 }
 
diff --git a/substrate/srml/system/src/lib.rs b/substrate/srml/system/src/lib.rs
index 5a3094d821409e79fc01e696774e3ad03e250a34..b08321f86055f4206d90e3432ee45d135831edaa 100644
--- a/substrate/srml/system/src/lib.rs
+++ b/substrate/srml/system/src/lib.rs
@@ -78,14 +78,14 @@ use rstd::prelude::*;
 use rstd::map;
 use primitives::traits::{self, CheckEqual, SimpleArithmetic, SimpleBitOps, One, Bounded, Lookup,
 	Hash, Member, MaybeDisplay, EnsureOrigin, Digest as DigestT, CurrentHeight, BlockNumberToHash,
-	MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup,
+	MaybeSerializeDebugButNotDeserialize, MaybeSerializeDebug, StaticLookup
 };
 #[cfg(any(feature = "std", test))]
 use primitives::traits::Zero;
 use substrate_primitives::storage::well_known_keys;
 use srml_support::{
 	storage, decl_module, decl_event, decl_storage, StorageDoubleMap, StorageValue,
-	StorageMap, Parameter, for_each_tuple,
+	StorageMap, Parameter, for_each_tuple, traits::Contains
 };
 use safe_mix::TripletMix;
 use parity_codec::{Encode, Decode};
@@ -145,7 +145,7 @@ pub fn extrinsics_data_root<H: Hash>(xts: Vec<Vec<u8>>) -> H::Output {
 
 pub trait Trait: 'static + Eq + Clone {
 	/// The aggregated `Origin` type used by dispatchable calls.
-	type Origin: Into<Option<RawOrigin<Self::AccountId>>> + From<RawOrigin<Self::AccountId>>;
+	type Origin: Into<Result<RawOrigin<Self::AccountId>, Self::Origin>> + From<RawOrigin<Self::AccountId>>;
 
 	/// Account index (aka nonce) type. This stores the number of previous transactions associated with a sender
 	/// account.
@@ -376,40 +376,97 @@ decl_storage! {
 }
 
 pub struct EnsureRoot<AccountId>(::rstd::marker::PhantomData<AccountId>);
-impl<O: Into<Option<RawOrigin<AccountId>>>, AccountId> EnsureOrigin<O> for EnsureRoot<AccountId> {
+impl<
+	O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
+	AccountId,
+> EnsureOrigin<O> for EnsureRoot<AccountId> {
 	type Success = ();
-	fn ensure_origin(o: O) -> Result<Self::Success, &'static str> {
-		ensure_root(o)
+	fn try_origin(o: O) -> Result<Self::Success, O> {
+		o.into().and_then(|o| match o {
+			RawOrigin::Root => Ok(()),
+			r => Err(O::from(r)),
+		})
+	}
+}
+
+pub struct EnsureSigned<AccountId>(::rstd::marker::PhantomData<AccountId>);
+impl<
+	O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
+	AccountId,
+> EnsureOrigin<O> for EnsureSigned<AccountId> {
+	type Success = AccountId;
+	fn try_origin(o: O) -> Result<Self::Success, O> {
+		o.into().and_then(|o| match o {
+			RawOrigin::Signed(who) => Ok(who),
+			r => Err(O::from(r)),
+		})
+	}
+}
+
+pub struct EnsureSignedBy<Who, AccountId>(::rstd::marker::PhantomData<(Who, AccountId)>);
+impl<
+	O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
+	Who: Contains<AccountId>,
+	AccountId: PartialEq + Clone,
+> EnsureOrigin<O> for EnsureSignedBy<Who, AccountId> {
+	type Success = AccountId;
+	fn try_origin(o: O) -> Result<Self::Success, O> {
+		o.into().and_then(|o| match o {
+			RawOrigin::Signed(ref who) if Who::contains(who) => Ok(who.clone()),
+			r => Err(O::from(r)),
+		})
+	}
+}
+
+pub struct EnsureNone<AccountId>(::rstd::marker::PhantomData<AccountId>);
+impl<
+	O: Into<Result<RawOrigin<AccountId>, O>> + From<RawOrigin<AccountId>>,
+	AccountId,
+> EnsureOrigin<O> for EnsureNone<AccountId> {
+	type Success = ();
+	fn try_origin(o: O) -> Result<Self::Success, O> {
+		o.into().and_then(|o| match o {
+			RawOrigin::None => Ok(()),
+			r => Err(O::from(r)),
+		})
+	}
+}
+
+pub struct EnsureNever<T>(::rstd::marker::PhantomData<T>);
+impl<O, T> EnsureOrigin<O> for EnsureNever<T> {
+	type Success = T;
+	fn try_origin(o: O) -> Result<Self::Success, O> {
+		Err(o)
 	}
 }
 
 /// Ensure that the origin `o` represents a signed extrinsic (i.e. transaction).
 /// Returns `Ok` with the account that signed the extrinsic or an `Err` otherwise.
 pub fn ensure_signed<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<AccountId, &'static str>
-	where OuterOrigin: Into<Option<RawOrigin<AccountId>>>
+	where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
 {
 	match o.into() {
-		Some(RawOrigin::Signed(t)) => Ok(t),
+		Ok(RawOrigin::Signed(t)) => Ok(t),
 		_ => Err("bad origin: expected to be a signed origin"),
 	}
 }
 
 /// Ensure that the origin `o` represents the root. Returns `Ok` or an `Err` otherwise.
 pub fn ensure_root<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), &'static str>
-	where OuterOrigin: Into<Option<RawOrigin<AccountId>>>
+	where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
 {
 	match o.into() {
-		Some(RawOrigin::Root) => Ok(()),
+		Ok(RawOrigin::Root) => Ok(()),
 		_ => Err("bad origin: expected to be a root origin"),
 	}
 }
 
 /// Ensure that the origin `o` represents an unsigned extrinsic. Returns `Ok` or an `Err` otherwise.
 pub fn ensure_none<OuterOrigin, AccountId>(o: OuterOrigin) -> Result<(), &'static str>
-	where OuterOrigin: Into<Option<RawOrigin<AccountId>>>
+	where OuterOrigin: Into<Result<RawOrigin<AccountId>, OuterOrigin>>
 {
 	match o.into() {
-		Some(RawOrigin::None) => Ok(()),
+		Ok(RawOrigin::None) => Ok(()),
 		_ => Err("bad origin: expected to be no origin"),
 	}
 }
@@ -753,6 +810,13 @@ mod tests {
 		GenesisConfig::<Test>::default().build_storage().unwrap().0.into()
 	}
 
+	#[test]
+	fn origin_works() {
+		let o = Origin::from(RawOrigin::<u64>::Signed(1u64));
+		let x: Result<RawOrigin<u64>, Origin> = o.into();
+		assert_eq!(x, Ok(RawOrigin::<u64>::Signed(1u64)));
+	}
+
 	#[test]
 	fn deposit_event_should_work() {
 		with_externalities(&mut new_test_ext(), || {