pub mod gov {
	pub use pallet_custom_origins::*;
	#[frame_support::pallet]
	pub mod pallet_custom_origins {
		use frame_support::pallet_prelude::*;
		#[pallet::config]
		pub trait Config: frame_system::Config {}
		#[pallet::pallet]
		pub struct Pallet<T>(_);
		#[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)]
		#[pallet::origin]
		pub enum Origin {
			WhitelistedCaller,
			Treasurer,
			PoolAdmin,
			ReferendumCanceller,
			ReferendumKiller,
		}
		macro_rules! decl_unit_ensures {
			( $name:ident: $success_type:ty = $success:expr ) => {
				pub struct $name;
				impl<O: Into<Result<Origin, O>> + From<Origin>>
					EnsureOrigin<O> for $name
				{
					type Success = $success_type;
					fn try_origin(o: O) -> Result<Self::Success, O> {
						o.into().and_then(|o| match o {
							Origin::$name => Ok($success),
							r => Err(O::from(r)),
						})
					}
					#[cfg(feature = "runtime-benchmarks")]
					fn try_successful_origin() -> Result<O, ()> {
						Ok(O::from(Origin::$name))
					}
				}
			};
			( $name:ident ) => { decl_unit_ensures! { $name : () = () } };
			( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => {
				decl_unit_ensures! { $name: $success_type = $success }
				decl_unit_ensures! { $( $rest )* }
			};
			( $name:ident, $( $rest:tt )* ) => {
				decl_unit_ensures! { $name }
				decl_unit_ensures! { $( $rest )* }
			};
			() => {}
		}
		decl_unit_ensures!(
			WhitelistedCaller,
			PoolAdmin,
			Treasurer,
			ReferendumCanceller,
			ReferendumKiller,
		);
	}
	pub mod types {
		use cfg_primitives::AccountId;
		use frame_support::traits::{EitherOf, EitherOfDiverse};
		use frame_system::EnsureRoot;
		use pallet_collective::EnsureProportionAtLeast;
		use super::*;
		use crate::instances::{CouncilCollective, TechnicalCollective};
		pub type EnsureRootOr<O> = EitherOfDiverse<EnsureRoot<AccountId>, O>;
		pub type AllOfCouncil = EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 1>;
		pub type HalfOfCouncil = EnsureProportionAtLeast<AccountId, CouncilCollective, 1, 2>;
		pub type TwoThirdOfCouncil = EnsureProportionAtLeast<AccountId, CouncilCollective, 2, 3>;
		pub type ThreeFourthOfCouncil = EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 4>;
		pub type HalfOfTechnicalCommitte =
			EnsureProportionAtLeast<AccountId, TechnicalCollective, 1, 2>;
		pub type TreasuryApproveOrigin = EnsureRootOr<EitherOf<TwoThirdOfCouncil, Treasurer>>;
		pub type WhitelistOrigin = EnsureRootOr<HalfOfTechnicalCommitte>;
		pub type DispatchWhitelistedOrigin = EnsureRootOr<WhitelistedCaller>;
		pub type RefCancelOrigin = EnsureRootOr<ReferendumCanceller>;
		pub type RefKillerOrigin = EnsureRootOr<ReferendumKiller>;
		pub type PoolCreateOrigin = EnsureRootOr<PoolAdmin>;
	}
}