// vim: tw=80
use super::*;

use quote::ToTokens;

/// Convert a trait object reference into a reference to a Boxed trait
fn dedynify(ty: &mut Type) {
    if let Type::Reference(ref mut tr) = ty {
        if let Type::TraitObject(ref tto) = tr.elem.as_ref() {
            if let Some(lt) = &tr.lifetime {
                if lt.ident == "static" {
                    // For methods that return 'static references, the user can
                    // usually actually supply one, unlike nonstatic references.
                    // dedynify is unneeded and harmful in such cases.
                    //
                    // But we do need to add parens to prevent parsing errors
                    // when methods like returning add a `+ Send` to the output
                    // type.
                    *tr.elem = parse2(quote!((#tto))).unwrap();
                    return;
                }
            }

            *tr.elem = parse2(quote!(Box<#tto>)).unwrap();
        }
    }
}

/// Convert a special reference type like "&str" into a reference to its owned
/// type like "&String".
fn destrify(ty: &mut Type) {
    if let Type::Reference(ref mut tr) = ty {
        if let Some(lt) = &tr.lifetime {
            if lt.ident == "static" {
                // For methods that return 'static references, the user can
                // usually actually supply one, unlike nonstatic references.
                // destrify is unneeded and harmful in such cases.
                return;
            }
        }

        let path_ty: TypePath = parse2(quote!(Path)).unwrap();
        let pathbuf_ty: Type = parse2(quote!(::std::path::PathBuf)).unwrap();

        let str_ty: TypePath = parse2(quote!(str)).unwrap();
        let string_ty: Type = parse2(quote!(::std::string::String)).unwrap();

        let cstr_ty: TypePath = parse2(quote!(CStr)).unwrap();
        let cstring_ty: Type = parse2(quote!(::std::ffi::CString)).unwrap();

        let osstr_ty: TypePath = parse2(quote!(OsStr)).unwrap();
        let osstring_ty: Type = parse2(quote!(::std::ffi::OsString)).unwrap();

        match tr.elem.as_ref() {
            Type::Path(ref path) if *path == cstr_ty =>
                *tr.elem = cstring_ty,
            Type::Path(ref path) if *path == osstr_ty =>
                *tr.elem = osstring_ty,
            Type::Path(ref path) if *path == path_ty =>
                *tr.elem = pathbuf_ty,
            Type::Path(ref path) if *path == str_ty =>
                *tr.elem = string_ty,
            Type::Slice(ts) => {
                let inner = (*ts.elem).clone();
                let mut segments = Punctuated::new();
                segments.push(format_ident!("std").into());
                segments.push(format_ident!("vec").into());
                let mut v: PathSegment = format_ident!("Vec").into();
                let mut abga_args = Punctuated::new();
                abga_args.push(GenericArgument::Type(inner));
                v.arguments = PathArguments::AngleBracketed(
                    AngleBracketedGenericArguments {
                        colon2_token: None,
                        lt_token: Token![<](Span::call_site()),
                        args: abga_args,
                        gt_token: Token![>](Span::call_site()),
                    }
                );
                segments.push(v);

                *tr.elem = Type::Path(TypePath {
                    qself: None,
                    path: Path {
                        leading_colon: Some(Token![::](Span::call_site())),
                        segments
                    }
                });
            },
            _ => (), // Nothing to do
        };
    }
}

/// Return the owned version of the input.
fn ownify(ty: &Type) -> Type {
    if let Type::Reference(ref tr) = &ty {
        if tr.lifetime.as_ref().map_or(false, |lt| lt.ident == "static")
        {
            // Just a static expectation
            ty.clone()
        } else {
            *tr.elem.clone()
        }
    } else {
        ty.clone()
    }
}

/// Add Send + Sync to a where clause
fn send_syncify(wc: &mut Option<WhereClause>, bounded_ty: Type) {
    let mut bounds = Punctuated::new();
    bounds.push(TypeParamBound::Trait(TraitBound {
        paren_token: None,
        modifier: TraitBoundModifier::None,
        lifetimes: None,
        path: Path::from(format_ident!("Send"))
    }));
    bounds.push(TypeParamBound::Trait(TraitBound {
        paren_token: None,
        modifier: TraitBoundModifier::None,
        lifetimes: None,
        path: Path::from(format_ident!("Sync"))
    }));
    if wc.is_none() {
        *wc = Some(WhereClause {
            where_token: <Token![where]>::default(),
            predicates: Punctuated::new()
        });
    }
    wc.as_mut().unwrap()
    .predicates.push(
        WherePredicate::Type(
            PredicateType {
                lifetimes: None,
                bounded_ty,
                colon_token: Default::default(),
                bounds
            }
        )
    );
}

/// Build a MockFunction.
#[derive(Clone, Copy, Debug)]
pub(crate) struct Builder<'a> {
    attrs: &'a [Attribute],
    call_levels: Option<usize>,
    levels: usize,
    parent: Option<&'a Ident>,
    sig: &'a Signature,
    struct_: Option<&'a Ident>,
    struct_generics: Option<&'a Generics>,
    trait_: Option<&'a Ident>,
    vis: &'a Visibility
}

impl<'a> Builder<'a> {
    pub fn attrs(&mut self, attrs: &'a[Attribute]) -> &mut Self {
        self.attrs = attrs;
        self
    }

    pub fn build(self) -> MockFunction {
        let mut argnames = Vec::new();
        let mut argty = Vec::new();
        let mut is_static = true;
        let mut predexprs = Vec::new();
        let mut predty = Vec::new();
        let mut refpredty = Vec::new();

        let (mut declosured_generics, declosured_inputs, call_exprs) =
            declosurefy(&self.sig.generics, &self.sig.inputs);

        for fa in declosured_inputs.iter() {
            if let FnArg::Typed(pt) = fa {
                let argname = (*pt.pat).clone();
                if pat_is_self(&argname) {
                    // A weird receiver like `Box<Self>`
                    is_static = false;
                    continue;
                }
                let aty = supersuperfy(&pt.ty, self.levels);
                if let Type::Reference(ref tr) = aty {
                    predexprs.push(quote!(#argname));
                    predty.push((*tr.elem).clone());
                    let tr2 = Type::Reference(TypeReference {
                        and_token: tr.and_token,
                        lifetime: None,
                        mutability: None,
                        elem: tr.elem.clone()
                    });
                    refpredty.push(tr2);
                } else {
                    predexprs.push(quote!(&#argname));
                    predty.push(aty.clone());
                    let tr = TypeReference {
                        and_token: Token![&](Span::call_site()),
                        lifetime: None,
                        mutability: None,
                        elem: Box::new(aty.clone())
                    };
                    refpredty.push(Type::Reference(tr));
                };
                argnames.push(argname);
                argty.push(aty.clone());
            } else {
                is_static = false;
            }
        }
        let output = match self.sig.output {
            ReturnType::Default => Type::Tuple(TypeTuple {
                    paren_token: token::Paren::default(),
                    elems: Punctuated::new()
                }),
            ReturnType::Type(_, ref ty) => {
                let mut output_ty = supersuperfy(&**ty, self.levels);
                destrify(&mut output_ty);
                dedynify(&mut output_ty);
                output_ty
            }
        };
        supersuperfy_generics(&mut declosured_generics, self.levels);
        let owned_output = ownify(&output);
        let mut return_ref = false;
        let mut return_refmut = false;
        if let Type::Reference(ref tr) = &output {
            if tr.lifetime.as_ref().map_or(true, |lt| lt.ident != "static")
            {
                if tr.mutability.is_none() {
                    return_ref = true;
                } else {
                    return_refmut = true;
                }
            }
        };
        if is_static && (return_ref || return_refmut) {
            compile_error(self.sig.span(),
                "Mockall cannot mock static methods that return non-'static references.  It's unclear what the return value's lifetime should be.");
        }
        let struct_generics = self.struct_generics.cloned()
            .unwrap_or_default();
        let (type_generics, salifetimes, srlifetimes) = split_lifetimes(
            struct_generics.clone(),
            &declosured_inputs,
            &ReturnType::Type(<Token![->]>::default(),
                              Box::new(owned_output.clone()))
        );
        let srltg = lifetimes_to_generics(&srlifetimes);
        let (call_generics, malifetimes, mrlifetimes) = split_lifetimes(
            declosured_generics,
            &declosured_inputs,
            &ReturnType::Type(<Token![->]>::default(),
                              Box::new(owned_output.clone()))
        );
        let mrltg = lifetimes_to_generics(&mrlifetimes);
        let cgenerics = merge_generics(&type_generics, &call_generics);
        let egenerics = merge_generics(
            &merge_generics(&cgenerics, &srltg),
            &mrltg);
        let alifetimes = salifetimes.into_iter()
            .collect::<HashSet<LifetimeDef>>()
            .union(&malifetimes.into_iter().collect::<HashSet<_>>())
            .into_iter()
            .cloned()
            .collect();

        let fn_params = egenerics.type_params()
            .map(|tp| tp.ident.clone())
            .collect();
        let call_levels = self.call_levels.unwrap_or(self.levels);

        MockFunction {
            alifetimes,
            argnames,
            argty,
            attrs: self.attrs.to_vec(),
            call_exprs,
            call_generics,
            call_vis: expectation_visibility(self.vis, call_levels),
            egenerics,
            cgenerics,
            fn_params,
            is_static,
            mod_ident: self.parent.unwrap_or(&Ident::new("FIXME", Span::call_site())).clone(),
            output,
            owned_output,
            predexprs,
            predty,
            refpredty,
            return_ref,
            return_refmut,
            sig: self.sig.clone(),
            struct_: self.struct_.cloned(),
            struct_generics,
            trait_: self.trait_.cloned(),
            type_generics,
            privmod_vis: expectation_visibility(self.vis, self.levels)
        }
    }

    /// How many levels of modules beneath the original function this one is
    /// nested.
    pub fn call_levels(&mut self, levels: usize) -> &mut Self {
        self.call_levels = Some(levels);
        self
    }

    /// How many levels of modules beneath the original function this one's
    /// private module is nested.
    pub fn levels(&mut self, levels: usize) -> &mut Self {
        self.levels = levels;
        self
    }

    /// # Arguments
    ///
    /// * sig:      The signature of the mockable function
    /// * v:        The visibility of the mockable function
    pub fn new(sig: &'a Signature, vis: &'a Visibility) -> Self {
        Builder {
            attrs: &[],
            levels: 0,
            call_levels: None,
            parent: None,
            sig,
            struct_: None,
            struct_generics: None,
            trait_: None,
            vis
        }
    }

    /// Supply the name of the parent module
    pub fn parent(&mut self, ident: &'a Ident) -> &mut Self {
        self.parent = Some(ident);
        self
    }

    /// Supply the name of the parent struct, if any
    pub fn struct_(&mut self, ident: &'a Ident) -> &mut Self {
        self.struct_= Some(ident);
        self
    }

    /// Supply the Generics of the parent struct, if any
    pub fn struct_generics(&mut self, generics: &'a Generics) -> &mut Self {
        self.struct_generics = Some(generics);
        self
    }

    /// Supply the name of the method's trait, if any
    pub fn trait_(&mut self, ident: &'a Ident) -> &mut Self {
        self.trait_ = Some(ident);
        self
    }
}

#[derive(Clone)]
pub(crate) struct MockFunction {
    /// Lifetimes of the mocked method that relate to the arguments but not the
    /// return value
    alifetimes: Punctuated<LifetimeDef, token::Comma>,
    /// Names of the method arguments
    argnames: Vec<Pat>,
    /// Types of the method arguments
    argty: Vec<Type>,
    /// any attributes on the original function, like #[inline]
    pub attrs: Vec<Attribute>,
    /// Expressions that should be used for Expectation::call's arguments
    call_exprs: Vec<TokenStream>,
    /// Generics used for the expectation call
    call_generics: Generics,
    /// Visibility of the mock function itself
    call_vis: Visibility,
    /// Generics of the Expectation object
    egenerics: Generics,
    /// Generics of the Common object
    cgenerics: Generics,
    /// The mock function's generic types as a list of types
    fn_params: Vec<Ident>,
    /// Is this for a static method or free function?
    is_static: bool,
    /// name of the function's parent module
    mod_ident: Ident,
    /// Output type of the Method, supersuperfied.
    output: Type,
    /// Owned version of the output type of the Method, supersuperfied.
    ///
    /// If the real output type is a non-'static reference, then it will differ
    /// from this field.
    owned_output: Type,
    /// Expressions that create the predicate arguments from the call arguments
    predexprs: Vec<TokenStream>,
    /// Types used for Predicates.  Will be almost the same as args, but every
    /// type will be a non-reference type.
    predty: Vec<Type>,
    /// Does the function return a non-'static reference? 
    return_ref: bool,
    /// Does the function return a mutable reference? 
    return_refmut: bool,
    /// References to every type in `predty`.
    refpredty: Vec<Type>,
    /// The signature of the mockable function
    sig: Signature,
    /// Name of the parent structure, if any
    struct_: Option<Ident>,
    /// Generics of the parent structure
    struct_generics: Generics,
    /// Name of this method's trait, if the method comes from a trait
    trait_: Option<Ident>,
    /// Type generics of the mock structure
    type_generics: Generics,
    /// Visibility of the expectation and its methods
    privmod_vis: Visibility
}

impl MockFunction {
    /// Return the mock function itself
    ///
    /// # Arguments
    ///
    /// * `modname`:    Name of the parent struct's private module
    // Supplying modname is an unfortunately hack.  Ideally MockFunction
    // wouldn't need to know that.
    pub fn call(&self, modname: Option<&Ident>) -> impl ToTokens {
        let attrs = AttrFormatter::new(&self.attrs).format();
        let call_exprs = &self.call_exprs;
        let (_, tg, _) = if self.is_method_generic() || self.is_static() {
            &self.egenerics
        } else {
            &self.call_generics
        }.split_for_impl();
        let tbf = tg.as_turbofish();
        let name = self.name();
        let no_match_msg = if let Some(s) = &self.struct_ {
            format!("{}::{}: No matching expectation found", s, name)
        } else {
            format!("{}::{}: No matching expectation found", self.mod_ident,
                    self.name())
        };
        let sig = &self.sig;
        let vis = if self.trait_.is_some() {
            &Visibility::Inherited
        } else {
            &self.call_vis
        };
        let substruct_obj = if let Some(trait_) = &self.trait_ {
            let ident = format_ident!("{}_expectations", trait_);
            quote!(#ident.)
        } else {
            quote!()
        };
        let call = if self.return_refmut {
            Ident::new("call_mut", Span::call_site())
        } else {
            Ident::new("call", Span::call_site())
        };
        if self.is_static {
            let outer_mod_path = self.outer_mod_path(modname);
            quote!(
                // Don't add a doc string.  The original is included in #attrs
                #(#attrs)*
                #vis #sig {
                    {
                        let __mockall_guard = #outer_mod_path::EXPECTATIONS
                            .lock().unwrap();
                        /*
                         * TODO: catch panics, then gracefully release the mutex
                         * so it won't be poisoned.  This requires bounding any
                         * generic parameters with UnwindSafe
                         */
                        /* std::panic::catch_unwind(|| */
                        __mockall_guard.#call#tbf(#(#call_exprs,)*)
                        /*)*/
                    }.expect(#no_match_msg)
                }
            )
        } else {
            quote!(
                // Don't add a doc string.  The original is included in #attrs
                #(#attrs)*
                #vis #sig {
                    self.#substruct_obj #name.#call#tbf(#(#call_exprs,)*)
                    .expect(#no_match_msg)
                }

            )
        }
    }

    /// Return this method's contribution to its parent's checkpoint method
    pub fn checkpoint(&self) -> impl ToTokens {
        let attrs = AttrFormatter::new(&self.attrs)
            .doc(false)
            .format();
        let inner_mod_ident = self.inner_mod_ident();
        if self.is_static {
            quote!(
                #(#attrs)*
                {
                    let __mockall_timeses = #inner_mod_ident::EXPECTATIONS.lock()
                        .unwrap()
                        .checkpoint()
                        .collect::<Vec<_>>();
                }
            )
        } else {
            let name = &self.name();
            quote!(#(#attrs)* { self.#name.checkpoint(); })
        }
    }

    /// Return a function that creates a Context object for this function
    ///
    /// # Arguments
    ///
    /// * `modname`:    Name of the parent struct's private module
    // Supplying modname is an unfortunately hack.  Ideally MockFunction
    // wouldn't need to know that.
    pub fn context_fn(&self, modname: Option<&Ident>) -> impl ToTokens {
        let attrs = AttrFormatter::new(&self.attrs)
            .doc(false)
            .format();
        let context_docstr = format!("Create a [`Context`]({}{}/struct.Context.html) for mocking the `{}` method",
            modname.map(|m| format!("{}/", m)).unwrap_or_default(),
            self.inner_mod_ident(),
            self.name());
        let context_ident = format_ident!("{}_context", self.name());
        let (_, tg, _) = self.type_generics.split_for_impl();
        let outer_mod_path = self.outer_mod_path(modname);
        let v = &self.call_vis;
        quote!(
            #(#attrs)*
            #[doc = #context_docstr]
            #v fn #context_ident() -> #outer_mod_path::Context #tg
            {
                #outer_mod_path::Context::default()
            }
        )
    }

    /// Generate code for the expect_ method
    ///
    /// # Arguments
    ///
    /// * `modname`:    Name of the parent struct's private module
    // Supplying modname is an unfortunately hack.  Ideally MockFunction
    // wouldn't need to know that.
    pub fn expect(&self, modname: &Ident) -> impl ToTokens {
        let attrs = AttrFormatter::new(&self.attrs)
            .doc(false)
            .format();
        let name = self.name();
        let expect_ident = format_ident!("expect_{}", &name);
        let expectation_obj = self.expectation_obj();
        let funcname = &self.sig.ident;
        let (_, tg, _) = if self.is_method_generic() {
            &self.egenerics
        } else {
            &self.call_generics
        }.split_for_impl();
        let (ig, _, wc) = self.call_generics.split_for_impl();
        let mut wc = wc.cloned();
        if self.is_method_generic() && (self.return_ref || self.return_refmut) {
            // Add Senc + Sync, required for downcast, since Expectation
            // stores an Option<#owned_output>
            send_syncify(&mut wc, self.owned_output.clone());
        }
        let tbf = tg.as_turbofish();
        let vis = &self.call_vis;

        #[cfg(not(feature = "nightly_derive"))]
        let must_use = quote!(#[must_use =
                "Must set return value when not using the \"nightly\" feature"
            ]);
        #[cfg(feature = "nightly_derive")]
        let must_use = quote!();

        let substruct_obj = if let Some(trait_) = &self.trait_ {
            let ident = format_ident!("{}_expectations", trait_);
            quote!(#ident.)
        } else {
            quote!()
        };
        let docstr = format!("Create an [`Expectation`]({}/{}/struct.Expectation.html) for mocking the `{}` method",
            modname, self.inner_mod_ident(), funcname);
        quote!(
            #must_use
            #[doc = #docstr]
            #(#attrs)*
            #vis fn #expect_ident #ig(&mut self)
               -> &mut #modname::#expectation_obj
               #wc
            {
                self.#substruct_obj #name.expect#tbf()
            }
        )
    }

    /// Return the name of this function's expecation object
    pub fn expectation_obj(&self) -> impl ToTokens {
        let inner_mod_ident = self.inner_mod_ident();
        // staticize any lifetimes.  This is necessary for methods that return
        // non-static types, because the Expectation itself must be 'static.
        let segenerics = staticize(&self.egenerics);
        let (_, tg, _) = segenerics.split_for_impl();
        quote!(#inner_mod_ident::Expectation #tg)
    }

    /// Return the name of this function's expecations object
    pub fn expectations_obj(&self) -> impl ToTokens {
        let inner_mod_ident = self.inner_mod_ident();
        if self.is_method_generic() {
            quote!(#inner_mod_ident::GenericExpectations)
        } else {
            quote!(#inner_mod_ident::Expectations)
        }
    }

    pub fn field_definition(&self, modname: Option<&Ident>) -> TokenStream {
        let name = self.name();
        let attrs = AttrFormatter::new(&self.attrs)
            .doc(false)
            .format();
        let expectations_obj = &self.expectations_obj();
        if self.is_method_generic() {
            quote!(#(#attrs)* #name: #modname::#expectations_obj)
        } else {
            // staticize any lifetimes.  This is necessary for methods that
            // return non-static types, because the Expectation itself must be
            // 'static.
            let segenerics = staticize(&self.egenerics);
            let (_, tg, _) = segenerics.split_for_impl();
            quote!(#(#attrs)* #name: #modname::#expectations_obj #tg)
        }
    }

    /// Human-readable name of the mock function
    fn funcname(&self) -> String {
        if let Some(si) = &self.struct_ {
            format!("{}::{}", si, self.name())
        } else {
            format!("{}", self.name())
        }
    }

    fn hrtb(&self) -> Option<BoundLifetimes> {
        if self.alifetimes.is_empty() {
            None
        } else {
            Some(BoundLifetimes {
                lifetimes: self.alifetimes.clone(),
                lt_token: <Token![<]>::default(),
                gt_token: <Token![>]>::default(),
                .. Default::default()
            })
        }
    }

    fn is_expectation_generic(&self) -> bool {
        self.egenerics.params.iter().any(|p| {
            matches!(p, GenericParam::Type(_))
        }) || self.egenerics.where_clause.is_some()
    }

    /// Is the mock method generic (as opposed to a non-generic method of a
    /// generic mock struct)?
    fn is_method_generic(&self) -> bool {
        self.call_generics.params.iter().any(|p| {
            matches!(p, GenericParam::Type(_))
        }) || self.call_generics.where_clause.is_some()
    }

    fn outer_mod_path(&self, modname: Option<&Ident>) -> Path {
        let mut path = if let Some(m) = modname {
            Path::from(PathSegment::from(m.clone()))
        } else {
            Path { leading_colon: None, segments: Punctuated::new() }
        };
        path.segments.push(PathSegment::from(self.inner_mod_ident()));
        path
    }

    fn inner_mod_ident(&self) -> Ident {
        format_ident!("__{}", &self.name())
    }

    pub fn is_static(&self) -> bool {
        self.is_static
    }

    pub fn name(&self) -> &Ident {
        &self.sig.ident
    }

    /// Generate code for this function's private module
    pub fn priv_module(&self) -> impl ToTokens {
        let attrs = AttrFormatter::new(&self.attrs)
            .doc(false)
            .format();
        let common = &Common{f: self};
        let context = &Context{f: self};
        let expectation: Box<dyn ToTokens> = if self.return_ref {
            Box::new(RefExpectation{f: self})
        } else if self.return_refmut {
            Box::new(RefMutExpectation{f: self})
        } else {
            Box::new(StaticExpectation{f: self})
        };
        let expectations: Box<dyn ToTokens> = if self.return_ref {
            Box::new(RefExpectations{f: self})
        } else if self.return_refmut {
            Box::new(RefMutExpectations{f: self})
        } else {
            Box::new(StaticExpectations{f: self})
        };
        let generic_expectations = GenericExpectations{f: self};
        let guard: Box<dyn ToTokens> = if self.is_expectation_generic() {
            Box::new(GenericExpectationGuard{f: self})
        } else {
            Box::new(ConcreteExpectationGuard{f: self})
        };
        let matcher = &Matcher{f: self};
        let std_mutexguard = if self.is_static {
            quote!(use ::std::sync::MutexGuard;)
        } else {
            quote!()
        };
        let inner_mod_ident = self.inner_mod_ident();
        let rfunc: Box<dyn ToTokens> = if self.return_ref {
            Box::new(RefRfunc{f: self})
        } else if self.return_refmut {
            Box::new(RefMutRfunc{f: self})
        } else {
            Box::new(StaticRfunc{f: self})
        };
        quote!(
            #(#attrs)*
            #[allow(missing_docs)]
            pub mod #inner_mod_ident {
                use super::*;
                use ::mockall::CaseTreeExt;
                #std_mutexguard
                use ::std::{
                    mem,
                    ops::{DerefMut, Range},
                    sync::Mutex
                };
                #rfunc
                #matcher
                #common
                #expectation
                #expectations
                #generic_expectations
                #guard
                #context
            }
        )
    }
}

/// Holds parts of the expectation that are common for all output types
struct Common<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for Common<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let argnames = &self.f.argnames;
        let predty = &self.f.predty;
        let hrtb = self.f.hrtb();
        let funcname = self.f.funcname();
        let (ig, tg, wc) = self.f.cgenerics.split_for_impl();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let refpredty = &self.f.refpredty;
        let with_generics_idents = (0..self.f.predty.len())
            .map(|i| format_ident!("MockallMatcher{}", i))
            .collect::<Vec<_>>();
        let with_generics = TokenStream::from_iter(
            with_generics_idents.iter().zip(self.f.predty.iter())
            .map(|(id, mt)|
                quote!(#id: #hrtb ::mockall::Predicate<#mt> + Send + 'static, )
            )
        );
        let with_args = TokenStream::from_iter(
            self.f.argnames.iter().zip(with_generics_idents.iter())
            .map(|(argname, id)| quote!(#argname: #id, ))
        );
        let boxed_withargs = TokenStream::from_iter(
            argnames.iter().map(|aa| quote!(Box::new(#aa), ))
        );
        quote!(
            /// Holds the stuff that is independent of the output type
            struct Common #ig #wc {
                matcher: Mutex<Matcher #tg>,
                seq_handle: Option<::mockall::SeqHandle>,
                times: ::mockall::Times
            }

            impl #ig std::default::Default for Common #tg #wc
            {
                fn default() -> Self {
                    Common {
                        matcher: Mutex::new(Matcher::default()),
                        seq_handle: None,
                        times: ::mockall::Times::default()
                    }
                }
            }

            impl #ig Common #tg #wc {
                fn call(&self) {
                    self.times.call()
                        .unwrap_or_else(|m| {
                            let desc = format!("{}",
                                               self.matcher.lock().unwrap());
                            panic!("{}: Expectation({}) {}", #funcname, desc,
                                m);
                        });
                    self.verify_sequence();
                    if self.times.is_satisfied() {
                        self.satisfy_sequence()
                    }
                }

                fn in_sequence(&mut self, __mockall_seq: &mut ::mockall::Sequence)
                    -> &mut Self
                {
                    assert!(self.times.is_exact(),
                        "Only Expectations with an exact call count have sequences");
                    self.seq_handle = Some(__mockall_seq.next_handle());
                    self
                }

                fn is_done(&self) -> bool {
                    self.times.is_done()
                }

                #[allow(clippy::ptr_arg)]
                fn matches #lg (&self, #( #argnames: &#predty, )*) -> bool {
                    self.matcher.lock().unwrap().matches(#(#argnames, )*)
                }

                /// Forbid this expectation from ever being called.
                fn never(&mut self) {
                    self.times.never();
                }

                fn satisfy_sequence(&self) {
                    if let Some(__mockall_handle) = &self.seq_handle {
                        __mockall_handle.satisfy()
                    }
                }

                /// Expect this expectation to be called any number of times
                /// contained with the given range.
                fn times<MockallR>(&mut self, __mockall_r: MockallR)
                    where MockallR: Into<::mockall::TimesRange>
                {
                    self.times.times(__mockall_r)
                }

                fn with<#with_generics>(&mut self, #with_args)
                {
                    let mut __mockall_guard = self.matcher.lock().unwrap();
                    *__mockall_guard.deref_mut() =
                        Matcher::Pred(Box::new((#boxed_withargs)));
                }

                fn withf<MockallF>(&mut self, __mockall_f: MockallF)
                    where MockallF: #hrtb Fn(#( #refpredty, )*)
                                    -> bool + Send + 'static
                {
                    let mut __mockall_guard = self.matcher.lock().unwrap();
                    *__mockall_guard.deref_mut() =
                         Matcher::Func(Box::new(__mockall_f));
                }

                fn withf_st<MockallF>(&mut self, __mockall_f: MockallF)
                    where MockallF: #hrtb Fn(#( #refpredty, )*)
                                    -> bool + 'static
                {
                    let mut __mockall_guard = self.matcher.lock().unwrap();
                    *__mockall_guard.deref_mut() =
                         Matcher::FuncST(
                             ::mockall::Fragile::new(Box::new(__mockall_f))
                        );
                }

                fn verify_sequence(&self) {
                    if let Some(__mockall_handle) = &self.seq_handle {
                        __mockall_handle.verify()
                    }
                }
            }

            impl #ig Drop for Common #tg #wc {
                fn drop(&mut self) {
                    if !::std::thread::panicking() && !self.times.is_satisfied()
                    {
                        let desc = format!("{}", self.matcher.lock().unwrap());
                        panic!("{}: Expectation({}) called fewer than {} times",
                               #funcname,
                               desc,
                               self.times.minimum());
                    }
                }
            }
        ).to_tokens(tokens);
    }
}

/// Generates methods that are common for all Expectation types
struct CommonExpectationMethods<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for CommonExpectationMethods<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let argnames = &self.f.argnames;
        let hrtb = self.f.hrtb();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let predty = &self.f.predty;
        let with_generics_idents = (0..self.f.predty.len())
            .map(|i| format_ident!("MockallMatcher{}", i))
            .collect::<Vec<_>>();
        let with_generics = TokenStream::from_iter(
            with_generics_idents.iter().zip(self.f.predty.iter())
            .map(|(id, mt)|
                quote!(#id: #hrtb ::mockall::Predicate<#mt> + Send + 'static, )
            )
        );
        let with_args = TokenStream::from_iter(
            self.f.argnames.iter().zip(with_generics_idents.iter())
            .map(|(argname, id)| quote!(#argname: #id, ))
        );
        let v = &self.f.privmod_vis;
        quote!(
            /// Add this expectation to a
            /// [`Sequence`](../../../mockall/struct.Sequence.html).
            #v fn in_sequence(&mut self, __mockall_seq: &mut ::mockall::Sequence)
                -> &mut Self
            {
                self.common.in_sequence(__mockall_seq);
                self
            }

            fn is_done(&self) -> bool {
                self.common.is_done()
            }

            /// Validate this expectation's matcher.
            #[allow(clippy::ptr_arg)]
            fn matches #lg (&self, #(#argnames: &#predty, )*) -> bool {
                self.common.matches(#(#argnames, )*)
            }

            /// Forbid this expectation from ever being called.
            #v fn never(&mut self) -> &mut Self {
                self.common.never();
                self
            }

            /// Create a new, default, [`Expectation`](struct.Expectation.html)
            #v fn new() -> Self {
                Self::default()
            }

            /// Expect this expectation to be called exactly once.  Shortcut for
            /// [`times(1)`](#method.times).
            #v fn once(&mut self) -> &mut Self {
                self.times(1)
            }

            /// Restrict the number of times that that this method may be called.
            ///
            /// The argument may be:
            /// * A fixed number: `.times(4)`
            /// * Various types of range:
            ///   - `.times(5..10)`
            ///   - `.times(..10)`
            ///   - `.times(5..)`
            ///   - `.times(5..=10)`
            ///   - `.times(..=10)`
            /// * The wildcard: `.times(..)`
            #v fn times<MockallR>(&mut self, __mockall_r: MockallR) -> &mut Self
                where MockallR: Into<::mockall::TimesRange>
            {
                self.common.times(__mockall_r);
                self
            }

            /// Set matching crieteria for this Expectation.
            ///
            /// The matching predicate can be anything implemening the
            /// [`Predicate`](../../../mockall/trait.Predicate.html) trait.  Only
            /// one matcher can be set per `Expectation` at a time.
            #v fn with<#with_generics>(&mut self, #with_args) -> &mut Self
            {
                self.common.with(#(#argnames, )*);
                self
            }

            /// Set a matching function for this Expectation.
            ///
            /// This is equivalent to calling [`with`](#method.with) with a
            /// function argument, like `with(predicate::function(f))`.
            #v fn withf<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
                where MockallF: #hrtb Fn(#(&#predty, )*)
                                -> bool + Send + 'static
            {
                self.common.withf(__mockall_f);
                self
            }

            /// Single-threaded version of [`withf`](#method.withf).
            /// Can be used when the argument type isn't `Send`.
            #v fn withf_st<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
                where MockallF: #hrtb Fn(#(&#predty, )*)
                                -> bool + 'static
            {
                self.common.withf_st(__mockall_f);
                self
            }
        ).to_tokens(tokens);
    }
}

/// Holds the moethods of the Expectations object that are common for all
/// Expectation types
struct CommonExpectationsMethods<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for CommonExpectationsMethods<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let v = &self.f.privmod_vis;
        quote!(
            /// A collection of [`Expectation`](struct.Expectations.html)
            /// objects.  Users will rarely if ever use this struct directly.
            #[doc(hidden)]
            #v struct Expectations #ig ( Vec<Expectation #tg>) #wc;

            impl #ig Expectations #tg #wc {
                /// Verify that all current expectations are satisfied and clear
                /// them.
                #v fn checkpoint(&mut self) -> std::vec::Drain<Expectation #tg>
                {
                    self.0.drain(..)
                }

                /// Create a new expectation for this method.
                #v fn expect(&mut self) -> &mut Expectation #tg
                {
                    self.0.push(Expectation::default());
                    let __mockall_l = self.0.len();
                    &mut self.0[__mockall_l - 1]
                }

                #v fn new() -> Self {
                    Self::default()
                }
            }
            impl #ig Default for Expectations #tg #wc
            {
                fn default() -> Self {
                    Expectations(Vec::new())
                }
            }
        ).to_tokens(tokens);
    }
}

/// The ExpectationGuard structure for static methods with no generic types
struct ExpectationGuardCommonMethods<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for ExpectationGuardCommonMethods<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        if !self.f.is_static {
            return;
        }

        let argnames = &self.f.argnames;
        let argty = &self.f.argty;
        let oo = &self.f.owned_output;
        let (_, tg, _) = self.f.egenerics.split_for_impl();
        let expectations = if self.f.is_expectation_generic() {
            quote!(self.guard
                   .store
                   .get_mut(&::mockall::Key::new::<(#oo, #(#argty, )*)>())
                   .unwrap()
                   .downcast_mut::<Expectations #tg>()
                   .unwrap())
        } else {
            quote!(self.guard)
        };
        let hrtb = self.f.hrtb();
        let output = &self.f.output;
        let predty = &self.f.predty;
        let with_generics_idents = (0..self.f.predty.len())
            .map(|i| format_ident!("MockallMatcher{}", i))
            .collect::<Vec<_>>();
        let with_generics = TokenStream::from_iter(
            with_generics_idents.iter().zip(self.f.predty.iter())
            .map(|(id, mt)|
                quote!(#id: #hrtb ::mockall::Predicate<#mt> + Send + 'static, )
            )
        );
        let with_args = TokenStream::from_iter(
            self.f.argnames.iter().zip(with_generics_idents.iter())
            .map(|(argname, id)| quote!(#argname: #id, ))
        );
        let v = &self.f.privmod_vis;
        quote!(
            /// Just like
            /// [`Expectation::in_sequence`](struct.Expectation.html#method.in_sequence)
            #v fn in_sequence(&mut self,
                __mockall_seq: &mut ::mockall::Sequence)
                -> &mut Expectation #tg
            {
                #expectations.0[self.i].in_sequence(__mockall_seq)
            }

            /// Just like
            /// [`Expectation::never`](struct.Expectation.html#method.never)
            #v fn never(&mut self) -> &mut Expectation #tg {
                #expectations.0[self.i].never()
            }

            /// Just like
            /// [`Expectation::once`](struct.Expectation.html#method.once)
            #v fn once(&mut self) -> &mut Expectation #tg {
                #expectations.0[self.i].once()
            }

            /// Just like
            /// [`Expectation::return_const`](struct.Expectation.html#method.return_const)
            #v fn return_const<MockallOutput>
            (&mut self, __mockall_c: MockallOutput)
                -> &mut Expectation #tg
                where MockallOutput: Clone + Into<#output> + Send + 'static
            {
                #expectations.0[self.i].return_const(__mockall_c)
            }

            /// Just like
            /// [`Expectation::return_const_st`](struct.Expectation.html#method.return_const_st)
            #v fn return_const_st<MockallOutput>
            (&mut self, __mockall_c: MockallOutput)
                -> &mut Expectation #tg
                where MockallOutput: Clone + Into<#output> + 'static
            {
                #expectations.0[self.i].return_const_st(__mockall_c)
            }

            /// Just like
            /// [`Expectation::returning`](struct.Expectation.html#method.returning)
            #v fn returning<MockallF>(&mut self, __mockall_f: MockallF)
                -> &mut Expectation #tg
                where MockallF: #hrtb FnMut(#(#argty, )*)
                    -> #output + Send + 'static
            {
                #expectations.0[self.i].returning(__mockall_f)
            }

            /// Just like
            /// [`Expectation::return_once`](struct.Expectation.html#method.return_once)
            #v fn return_once<MockallF>(&mut self, __mockall_f: MockallF)
                -> &mut Expectation #tg
                where MockallF: #hrtb FnOnce(#(#argty, )*)
                                -> #output + Send + 'static
            {
                #expectations.0[self.i].return_once(__mockall_f)
            }

            /// Just like
            /// [`Expectation::return_once_st`](struct.Expectation.html#method.return_once_st)
            #v fn return_once_st<MockallF>(&mut self, __mockall_f: MockallF)
                -> &mut Expectation #tg
                where MockallF: #hrtb FnOnce(#(#argty, )*)
                                -> #output + 'static
            {
                #expectations.0[self.i].return_once_st(__mockall_f)
            }


            /// Just like
            /// [`Expectation::returning_st`](struct.Expectation.html#method.returning_st)
            #v fn returning_st<MockallF>(&mut self, __mockall_f: MockallF)
                -> &mut Expectation #tg
                where MockallF: #hrtb FnMut(#(#argty, )*)
                                -> #output + 'static
            {
                #expectations.0[self.i].returning_st(__mockall_f)
            }

            /// Just like
            /// [`Expectation::times`](struct.Expectation.html#method.times)
            #v fn times<MockallR>(&mut self, __mockall_r: MockallR)
                -> &mut Expectation #tg
                where MockallR: Into<::mockall::TimesRange>
            {
                #expectations.0[self.i].times(__mockall_r)
            }

            /// Just like
            /// [`Expectation::with`](struct.Expectation.html#method.with)
            #v fn with<#with_generics> (&mut self, #with_args)
                -> &mut Expectation #tg
            {
                #expectations.0[self.i].with(#(#argnames, )*)
            }

            /// Just like
            /// [`Expectation::withf`](struct.Expectation.html#method.withf)
            #v fn withf<MockallF>(&mut self, __mockall_f: MockallF)
                -> &mut Expectation #tg
                where MockallF: #hrtb Fn(#(&#predty, )*)
                                -> bool + Send + 'static
            {
                #expectations.0[self.i].withf(__mockall_f)
            }

            /// Just like
            /// [`Expectation::withf_st`](struct.Expectation.html#method.withf_st)
            #v fn withf_st<MockallF>(&mut self, __mockall_f: MockallF)
                -> &mut Expectation #tg
                where MockallF: #hrtb Fn(#(&#predty, )*)
                                -> bool + 'static
            {
                #expectations.0[self.i].withf_st(__mockall_f)
            }
        ).to_tokens(tokens);
    }
}

/// The ExpectationGuard structure for static methods with no generic types
struct ConcreteExpectationGuard<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for ConcreteExpectationGuard<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        if !self.f.is_static {
            return;
        }

        let common_methods = ExpectationGuardCommonMethods{f: self.f};
        let (_, tg, _) = self.f.egenerics.split_for_impl();
        let ltdef = LifetimeDef::new(
            Lifetime::new("'__mockall_lt", Span::call_site())
        );
        let mut e_generics = self.f.egenerics.clone();
        e_generics.lt_token.get_or_insert(<Token![<]>::default());
        e_generics.params.push(GenericParam::Lifetime(ltdef));
        e_generics.gt_token.get_or_insert(<Token![>]>::default());
        let (e_ig, e_tg, e_wc) = e_generics.split_for_impl();
        let (ei_ig, _, _) = e_generics.split_for_impl();
        let v = &self.f.privmod_vis;
        quote!(
            ::mockall::lazy_static! {
                #[doc(hidden)]
                #v static ref EXPECTATIONS:
                    ::std::sync::Mutex<Expectations #tg> =
                    ::std::sync::Mutex::new(Expectations::new());
            }
            /// Like an [`&Expectation`](struct.Expectation.html) but
            /// protected by a Mutex guard.  Useful for mocking static
            /// methods.  Forwards accesses to an `Expectation` object.
            // We must return the MutexGuard to the caller so he can
            // configure the expectation.  But we can't bundle both the
            // guard and the &Expectation into the same structure; the
            // borrow checker won't let us.  Instead we'll record the
            // expectation's position within the Expectations vector so we
            // can proxy its methods.
            //
            // ExpectationGuard is only defined for expectations that return
            // 'static return types.
            #v struct ExpectationGuard #e_ig #e_wc {
                guard: MutexGuard<'__mockall_lt, Expectations #tg>,
                i: usize
            }

            #[allow(clippy::unused_unit)]
            impl #ei_ig ExpectationGuard #e_tg #e_wc
            {
                // Should only be called from the mockall_derive generated
                // code
                #[doc(hidden)]
                #v fn new(mut __mockall_guard: MutexGuard<'__mockall_lt, Expectations #tg>)
                    -> Self
                {
                    __mockall_guard.expect(); // Drop the &Expectation
                    let __mockall_i = __mockall_guard.0.len() - 1;
                    ExpectationGuard{guard: __mockall_guard, i: __mockall_i}
                }

                #common_methods
            }
        ).to_tokens(tokens);
    }
}

/// The ExpectationGuard structure for static methods with generic types
struct GenericExpectationGuard<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for GenericExpectationGuard<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        if !self.f.is_static {
            return;
        }

        let argty = &self.f.argty;
        let common_methods = ExpectationGuardCommonMethods{f: self.f};
        let (_, tg, _) = self.f.egenerics.split_for_impl();
        let ltdef = LifetimeDef::new(
            Lifetime::new("'__mockall_lt", Span::call_site())
        );
        let mut egenerics = self.f.egenerics.clone();
        egenerics.lt_token.get_or_insert(<Token![<]>::default());
        egenerics.params.push(GenericParam::Lifetime(ltdef));
        egenerics.gt_token.get_or_insert(<Token![>]>::default());
        let (e_ig, e_tg, e_wc) = egenerics.split_for_impl();
        let fn_params = &self.f.fn_params;
        let oo = &self.f.owned_output;
        let tbf = tg.as_turbofish();
        let v = &self.f.privmod_vis;
        quote!(
            ::mockall::lazy_static! {
                #v static ref EXPECTATIONS:
                    ::std::sync::Mutex<GenericExpectations> =
                    ::std::sync::Mutex::new(GenericExpectations::new());
            }
            /// Like an [`&Expectation`](struct.Expectation.html) but
            /// protected by a Mutex guard.  Useful for mocking static
            /// methods.  Forwards accesses to an `Expectation` object.
            #v struct ExpectationGuard #e_ig #e_wc{
                guard: MutexGuard<'__mockall_lt, GenericExpectations>,
                i: usize,
                _phantom: ::std::marker::PhantomData<(#(#fn_params,)*)>,
            }

            #[allow(clippy::unused_unit)]
            impl #e_ig ExpectationGuard #e_tg #e_wc
            {
                // Should only be called from the mockall_derive generated
                // code
                #[doc(hidden)]
                #v fn new(mut __mockall_guard: MutexGuard<'__mockall_lt, GenericExpectations>)
                    -> Self
                {
                    let __mockall_ee: &mut Expectations #tg =
                        __mockall_guard.store.entry(
                            ::mockall::Key::new::<(#oo, #(#argty, )*)>()
                        ).or_insert_with(||
                            Box::new(Expectations #tbf ::new()))
                        .downcast_mut()
                        .unwrap();
                    __mockall_ee.expect();    // Drop the &Expectation
                    let __mockall_i = __mockall_ee.0.len() - 1;
                    ExpectationGuard{guard: __mockall_guard, i: __mockall_i,
                        _phantom: ::std::marker::PhantomData}
                }

                #common_methods
            }
        ).to_tokens(tokens);
    }
}

/// Generates Context, which manages the context for expectations of static
/// methods.
struct Context<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for Context<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        if !self.f.is_static {
            return;
        }

        let ltdef = LifetimeDef::new(
            Lifetime::new("'__mockall_lt", Span::call_site())
        );
        let mut egenerics = self.f.egenerics.clone();
        egenerics.lt_token.get_or_insert(<Token![<]>::default());
        egenerics.params.push(GenericParam::Lifetime(ltdef));
        egenerics.gt_token.get_or_insert(<Token![>]>::default());
        let (_, e_tg, _) = egenerics.split_for_impl();
        let (ty_ig, ty_tg, ty_wc) = self.f.type_generics.split_for_impl();
        let mut meth_generics = self.f.call_generics.clone();
        let ltdef = LifetimeDef::new(
            Lifetime::new("'__mockall_lt", Span::call_site())
        );
        meth_generics.params.push(GenericParam::Lifetime(ltdef));
        let (meth_ig, _meth_tg, meth_wc) = meth_generics.split_for_impl();
        let ctx_fn_params = Punctuated::<Ident, Token![,]>::from_iter(
            self.f.struct_generics.type_params().map(|tp| tp.ident.clone())
        );
        let v = &self.f.privmod_vis;

        #[cfg(not(feature = "nightly_derive"))]
        let must_use = quote!(#[must_use =
                "Must set return value when not using the \"nightly\" feature"
            ]);
        #[cfg(feature = "nightly_derive")]
        let must_use = quote!();

        quote!(
            /// Manages the context for expectations of static methods.
            ///
            /// Expectations on this method will be validated and cleared when
            /// the `Context` object drops.  The `Context` object does *not*
            /// provide any form of synchronization, so multiple tests that set
            /// expectations on the same static method must provide their own.
            #[must_use = "Context only serves to create expectations" ]
            #v struct Context #ty_ig #ty_wc {
                // Prevent "unused type parameter" errors
                // Surprisingly, PhantomData<Fn(generics)> is Send even if
                // generics are not, unlike PhantomData<generics>
                _phantom: ::std::marker::PhantomData<
                    Box<dyn Fn(#ctx_fn_params) + Send>
                >
            }
            impl #ty_ig Context #ty_tg #ty_wc {
                /// Verify that all current expectations for this method are
                /// satisfied and clear them.
                #v fn checkpoint(&self) {
                    Self::do_checkpoint()
                }
                #[doc(hidden)]
                #v fn do_checkpoint() {
                    let __mockall_timeses = EXPECTATIONS
                        .lock()
                        .unwrap()
                        .checkpoint()
                        .collect::<Vec<_>>();
                }

                /// Create a new expectation for this method.
                #must_use
                #v fn expect #meth_ig ( &self,) -> ExpectationGuard #e_tg
                    #meth_wc
                {
                    ExpectationGuard::new(EXPECTATIONS.lock().unwrap())
                }
            }
            impl #ty_ig Default for Context #ty_tg #ty_wc {
                fn default() -> Self {
                    Context {_phantom: std::marker::PhantomData}
                }
            }
            impl #ty_ig Drop for Context #ty_tg #ty_wc {
                fn drop(&mut self) {
                    if !std::thread::panicking() {
                        Self::do_checkpoint()
                    }
                }
            }
        ).to_tokens(tokens);
    }
}

struct Matcher<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for Matcher<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let (ig, tg, wc) = self.f.cgenerics.split_for_impl();
        let argnames = &self.f.argnames;
        let braces = argnames.iter()
            .fold(String::new(), |mut acc, _argname| {
                if acc.is_empty() {
                    acc.push_str("{}");
                } else {
                    acc.push_str(", {}");
                }
                acc
            });
        let fn_params = &self.f.fn_params;
        let hrtb = self.f.hrtb();
        let indices = (0..argnames.len())
            .map(|i| {
                syn::Index::from(i)
            }).collect::<Vec<_>>();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let pred_matches = TokenStream::from_iter(
            argnames.iter().enumerate()
            .map(|(i, argname)| {
                let idx = syn::Index::from(i);
                quote!(__mockall_pred.#idx.eval(#argname),)
            })
        );
        let preds = TokenStream::from_iter(
            self.f.predty.iter().map(|t|
                quote!(Box<dyn #hrtb ::mockall::Predicate<#t> + Send>,)
            )
        );
        let predty = &self.f.predty;
        let refpredty = &self.f.refpredty;
        quote!(
            enum Matcher #ig #wc {
                Always,
                Func(Box<dyn #hrtb Fn(#( #refpredty, )*) -> bool + Send>),
                // Version of Matcher::Func for closures that aren't Send
                FuncST(::mockall::Fragile<Box<dyn #hrtb Fn(#( #refpredty, )*) -> bool>>),
                Pred(Box<(#preds)>),
                // Prevent "unused type parameter" errors
                // Surprisingly, PhantomData<Fn(generics)> is Send even if
                // generics are not, unlike PhantomData<generics>
                _Phantom(Box<dyn Fn(#(#fn_params,)*) + Send>)
            }
            impl #ig Matcher #tg #wc {
                #[allow(clippy::ptr_arg)]
                fn matches #lg (&self, #( #argnames: &#predty, )*) -> bool {
                    match self {
                        Matcher::Always => true,
                        Matcher::Func(__mockall_f) =>
                            __mockall_f(#(#argnames, )*),
                        Matcher::FuncST(__mockall_f) =>
                            (__mockall_f.get())(#(#argnames, )*),
                        Matcher::Pred(__mockall_pred) =>
                            [#pred_matches]
                            .iter()
                            .all(|__mockall_x| *__mockall_x),
                        _ => unreachable!()
                    }
                }
            }

            impl #ig Default for Matcher #tg #wc {
                #[allow(unused_variables)]
                fn default() -> Self {
                    Matcher::Always
                }
            }

            impl #ig ::std::fmt::Display for Matcher #tg #wc {
                fn fmt(&self, __mockall_fmt: &mut ::std::fmt::Formatter<'_>)
                    -> ::std::fmt::Result
                {
                    match self {
                        Matcher::Always => write!(__mockall_fmt, "<anything>"),
                        Matcher::Func(_) => write!(__mockall_fmt, "<function>"),
                        Matcher::FuncST(_) => write!(__mockall_fmt, "<single threaded function>"),
                        Matcher::Pred(__mockall_p) => {
                            write!(__mockall_fmt, #braces,
                                #(__mockall_p.#indices,)*)
                        }
                        _ => unreachable!(),
                    }
                }
            }
        ).to_tokens(tokens);
    }
}

struct RefRfunc<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for RefRfunc<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let fn_params = &self.f.fn_params;
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let owned_output = &self.f.owned_output;

        #[cfg(not(feature = "nightly_derive"))]
        let default_err_msg =
            "Returning default values requires the \"nightly\" feature";
        #[cfg(feature = "nightly_derive")]
        let default_err_msg =
            "Can only return default values for types that impl std::Default";

        quote!(
            enum Rfunc #ig #wc {
                Default(Option<#owned_output>),
                Const(#owned_output),
                // Prevent "unused type parameter" errors Surprisingly,
                // PhantomData<Fn(generics)> is Send even if generics are not,
                // unlike PhantomData<generics>
                _Phantom(Mutex<Box<dyn Fn(#(#fn_params,)*) + Send>>)
            }

            impl #ig  Rfunc #tg #wc {
                fn call #lg (&self)
                    -> std::result::Result<&#owned_output, &'static str>
                {
                    match self {
                        Rfunc::Default(Some(ref __mockall_o)) => {
                            Ok(__mockall_o)
                        },
                        Rfunc::Default(None) => {
                            Err(#default_err_msg)
                        },
                        Rfunc::Const(ref __mockall_o) => {
                            Ok(__mockall_o)
                        },
                        Rfunc::_Phantom(_) => unreachable!()
                    }
                }
            }

            impl #ig std::default::Default for Rfunc #tg #wc
            {
                fn default() -> Self {
                    use ::mockall::ReturnDefault;
                    Rfunc::Default(::mockall::DefaultReturner::<#owned_output>
                                ::maybe_return_default())
                }
            }
        ).to_tokens(tokens);
    }
}

struct RefMutRfunc<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for RefMutRfunc<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let argnames = &self.f.argnames;
        let argty = &self.f.argty;
        let fn_params = &self.f.fn_params;
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let owned_output = &self.f.owned_output;
        let output = &self.f.output;

        #[cfg(not(feature = "nightly_derive"))]
        let default_err_msg =
            "Returning default values requires the \"nightly\" feature";
        #[cfg(feature = "nightly_derive")]
        let default_err_msg =
            "Can only return default values for types that impl std::Default";

        quote!(
            #[allow(clippy::unused_unit)]
            enum Rfunc #ig #wc {
                Default(Option<#owned_output>),
                Mut((Box<dyn FnMut(#(#argty, )*) -> #owned_output + Send + Sync>),
                    Option<#owned_output>),
                // Version of Rfunc::Mut for closures that aren't Send
                MutST((::mockall::Fragile<
                           Box<dyn FnMut(#(#argty, )*) -> #owned_output >>
                       ), Option<#owned_output>
                ),
                Var(#owned_output),
                // Prevent "unused type parameter" errors Surprisingly,
                // PhantomData<Fn(generics)> is Send even if generics are not,
                // unlike PhantomData<generics>
                _Phantom(Mutex<Box<dyn Fn(#(#fn_params,)*) + Send>>)
            }

            impl #ig  Rfunc #tg #wc {
                fn call_mut #lg (&mut self, #(#argnames: #argty, )*)
                    -> std::result::Result<#output, &'static str>
                {
                    match self {
                        Rfunc::Default(Some(ref mut __mockall_o)) => {
                            Ok(__mockall_o)
                        },
                        Rfunc::Default(None) => {
                            Err(#default_err_msg)
                        },
                        Rfunc::Mut(ref mut __mockall_f, ref mut __mockall_o) =>
                        {
                            *__mockall_o = Some(__mockall_f(#(#argnames, )*));
                            if let Some(ref mut __mockall_o2) = __mockall_o {
                                Ok(__mockall_o2)
                            } else {
                                unreachable!()
                            }
                        },
                        Rfunc::MutST(ref mut __mockall_f, ref mut __mockall_o)=>
                        {
                            *__mockall_o = Some((__mockall_f.get_mut())(
                                    #(#argnames, )*)
                            );
                            if let Some(ref mut __mockall_o2) = __mockall_o {
                                Ok(__mockall_o2)
                            } else {
                                unreachable!()
                            }
                        },
                        Rfunc::Var(ref mut __mockall_o) => {
                            Ok(__mockall_o)
                        },
                        Rfunc::_Phantom(_) => unreachable!()
                    }
                }
            }

            impl #ig std::default::Default for Rfunc #tg #wc
            {
                fn default() -> Self {
                    use ::mockall::ReturnDefault;
                    Rfunc::Default(::mockall::DefaultReturner::<#owned_output>
                                ::maybe_return_default())
                }
            }
        ).to_tokens(tokens);
    }
}

struct StaticRfunc<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for StaticRfunc<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let argnames = &self.f.argnames;
        let argty = &self.f.argty;
        let fn_params = &self.f.fn_params;
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let hrtb = self.f.hrtb();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let output = &self.f.output;
        quote!(
            #[allow(clippy::unused_unit)]
            enum Rfunc #ig #wc {
                Default,
                // Indicates that a `return_once` expectation has already
                // returned
                Expired,
                Mut(Box<dyn #hrtb FnMut(#(#argty, )*) -> #output + Send>),
                // Version of Rfunc::Mut for closures that aren't Send
                MutST(::mockall::Fragile<
                    Box<dyn #hrtb FnMut(#(#argty, )*) -> #output >>
                ),
                Once(Box<dyn #hrtb FnOnce(#(#argty, )*) -> #output + Send>),
                // Version of Rfunc::Once for closure that aren't Send
                OnceST(::mockall::Fragile<
                    Box<dyn #hrtb FnOnce(#(#argty, )*) -> #output>>
                ),
                // Prevent "unused type parameter" errors Surprisingly,
                // PhantomData<Fn(generics)> is Send even if generics are not,
                // unlike PhantomData<generics>
                _Phantom(Box<dyn Fn(#(#fn_params,)*) + Send>)
            }

            impl #ig  Rfunc #tg #wc {
                fn call_mut #lg (&mut self, #( #argnames: #argty, )* )
                    -> std::result::Result<#output, &'static str>
                {
                    match self {
                        Rfunc::Default => {
                            use ::mockall::ReturnDefault;
                            ::mockall::DefaultReturner::<#output>
                                ::return_default()
                        },
                        Rfunc::Expired => {
                            Err("called twice, but it returns by move")
                        },
                        Rfunc::Mut(__mockall_f) => {
                            Ok(__mockall_f( #(#argnames, )* ))
                        },
                        Rfunc::MutST(__mockall_f) => {
                            Ok((__mockall_f.get_mut())(#(#argnames,)*))
                        },
                        Rfunc::Once(_) => {
                            if let Rfunc::Once(mut __mockall_f) =
                                mem::replace(self, Rfunc::Expired) {
                                Ok(__mockall_f( #(#argnames, )* ))
                            } else {
                                unreachable!()
                            }
                        },
                        Rfunc::OnceST(_) => {
                            if let Rfunc::OnceST(mut __mockall_f) =
                                mem::replace(self, Rfunc::Expired) {
                                Ok((__mockall_f.into_inner())(#(#argnames,)*))
                            } else {
                                unreachable!()
                            }
                        },
                        Rfunc::_Phantom(_) => unreachable!()
                    }
                }
            }

            impl #ig std::default::Default for Rfunc #tg #wc
            {
                fn default() -> Self {
                    Rfunc::Default
                }
            }
        ).to_tokens(tokens);
    }
}

/// An expectation type for functions that take a &self and return a reference
struct RefExpectation<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for RefExpectation<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let common_methods = CommonExpectationMethods{f: &self.f};
        let funcname = self.f.funcname();
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();

        let (_, common_tg, _) = self.f.cgenerics.split_for_impl();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let output = &self.f.output;
        let owned_output = &self.f.owned_output;
        let v = &self.f.privmod_vis;
        quote!(
            /// Expectation type for methods taking a `&self` argument and
            /// returning immutable references.  This is the type returned by
            /// the `expect_*` methods.
            #v struct Expectation #ig #wc {
                common: Common #common_tg,
                rfunc: Rfunc #tg,
            }

            #[allow(clippy::unused_unit)]
            impl #ig Expectation #tg #wc {
                /// Call this [`Expectation`] as if it were the real method.
                #v fn call #lg (&self) -> #output
                {
                    self.common.call();
                    self.rfunc.call().unwrap_or_else(|m| {
                        let desc = format!("{}",
                                           self.common.matcher.lock().unwrap());
                        panic!("{}: Expectation({}) {}", #funcname, desc,
                            m);
                    })
                }

                /// Return a reference to a constant value from the `Expectation`
                #v fn return_const(&mut self, __mockall_o: #owned_output)
                    -> &mut Self
                {
                    self.rfunc = Rfunc::Const(__mockall_o);
                    self
                }

                #common_methods
            }
            impl #ig Default for Expectation #tg #wc
            {
                fn default() -> Self {
                    Expectation {
                        common: Common::default(),
                        rfunc: Rfunc::default()
                    }
                }
            }
        ).to_tokens(tokens);
    }
}

/// For methods that take &mut self and return a reference
struct RefMutExpectation<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for RefMutExpectation<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let common_methods = CommonExpectationMethods{f: &self.f};
        let argnames = &self.f.argnames;
        let argty = &self.f.argty;
        let funcname = self.f.funcname();
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let (_, common_tg, _) = self.f.cgenerics.split_for_impl();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let owned_output = &self.f.owned_output;
        let v = &self.f.privmod_vis;
        quote!(
            /// Expectation type for methods taking a `&mut self` argument and
            /// returning references.  This is the type returned by the
            /// `expect_*` methods.
            #v struct Expectation #ig #wc {
                common: Common #common_tg,
                rfunc: Rfunc #tg
            }

            #[allow(clippy::unused_unit)]
            impl #ig Expectation #tg #wc {
                /// Simulating calling the real method for this expectation
                #v fn call_mut #lg (&mut self, #(#argnames: #argty, )*)
                    -> &mut #owned_output
                {
                    self.common.call();
                    let desc = format!("{}",
                        self.common.matcher.lock().unwrap());
                    self.rfunc.call_mut(#(#argnames, )*).unwrap_or_else(|m| {
                            panic!("{}: Expectation({}) {}", #funcname, desc,
                                   m);
                    })
                }

                /// Convenience method that can be used to supply a return value
                /// for a `Expectation`.  The value will be returned by mutable
                /// reference.
                #v fn return_var(&mut self, __mockall_o: #owned_output) -> &mut Self
                {
                    self.rfunc = Rfunc::Var(__mockall_o);
                    self
                }

                /// Supply a closure that the `Expectation` will use to create its
                /// return value.  The return value will be returned by mutable
                /// reference.
                #v fn returning<MockallF>(&mut self, __mockall_f: MockallF)
                    -> &mut Self
                    where MockallF: FnMut(#(#argty, )*) -> #owned_output + Send + Sync + 'static
                {
                    self.rfunc = Rfunc::Mut(Box::new(__mockall_f), None);
                    self
                }

                /// Single-threaded version of [`returning`](#method.returning).
                /// Can be used when the argument or return type isn't `Send`.
                #v fn returning_st<MockallF>(&mut self, __mockall_f: MockallF)
                    -> &mut Self
                    where MockallF: FnMut(#(#argty, )*) -> #owned_output + 'static
                {
                    self.rfunc = Rfunc::MutST(
                        ::mockall::Fragile::new(Box::new(__mockall_f)), None);
                    self
                }

                #common_methods
            }
            impl #ig Default for Expectation #tg #wc
            {
                fn default() -> Self {
                    Expectation {
                        common: Common::default(),
                        rfunc: Rfunc::default()
                    }
                }
            }
        ).to_tokens(tokens);
    }
}

/// An expectation type for functions return a `'static` value
struct StaticExpectation<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for StaticExpectation<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let common_methods = CommonExpectationMethods{f: &self.f};
        let argnames = &self.f.argnames;
        let argty = &self.f.argty;
        let hrtb = self.f.hrtb();
        let funcname = self.f.funcname();
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let (_, common_tg, _) = self.f.cgenerics.split_for_impl();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let output = &self.f.output;
        let v = &self.f.privmod_vis;
        quote!(
            /// Expectation type for methods that return a `'static` type.
            /// This is the type returned by the `expect_*` methods.
            #v struct Expectation #ig #wc {
                common: Common #common_tg,
                rfunc: Mutex<Rfunc #tg>,
            }

            #[allow(clippy::unused_unit)]
            impl #ig Expectation #tg #wc {
                /// Call this [`Expectation`] as if it were the real method.
                #[doc(hidden)]
                #v fn call #lg (&self, #(#argnames: #argty, )* ) -> #output
                {
                    self.common.call();
                    self.rfunc.lock().unwrap().call_mut(#(#argnames, )*)
                        .unwrap_or_else(|message| {
                            let desc = format!("{}",
                                self.common.matcher.lock().unwrap());
                            panic!("{}: Expectation({}) {}", #funcname, desc,
                                   message);
                        })
                }

                /// Return a constant value from the `Expectation`
                ///
                /// The output type must be `Clone`.  The compiler can't always
                /// infer the proper type to use with this method; you will
                /// usually need to specify it explicitly.  i.e.
                /// `return_const(42i32)` instead of `return_const(42)`.
                // We must use Into<#output> instead of #output because where
                // clauses don't accept equality constraints.
                // https://github.com/rust-lang/rust/issues/20041
                #[allow(unused_variables)]
                #v fn return_const<MockallOutput>(&mut self,
                    __mockall_c: MockallOutput)
                    -> &mut Self
                    where MockallOutput: Clone + Into<#output> + Send + 'static
                {
                    self.returning(move |#(#argnames, )*| __mockall_c.clone().into())
                }

                /// Single-threaded version of
                /// [`return_const`](#method.return_const).  This is useful for
                /// return types that are not `Send`.
                ///
                /// The output type must be `Clone`.  The compiler can't always
                /// infer the proper type to use with this method; you will
                /// usually need to specify it explicitly.  i.e.
                /// `return_const(42i32)` instead of `return_const(42)`.
                ///
                /// It is a runtime error to call the mock method from a
                /// different thread than the one that originally called this
                /// method.
                // We must use Into<#output> instead of #output because where
                // clauses don't accept equality constraints.
                // https://github.com/rust-lang/rust/issues/20041
                #[allow(unused_variables)]
                #v fn return_const_st<MockallOutput>(&mut self,
                    __mockall_c: MockallOutput)
                    -> &mut Self
                    where MockallOutput: Clone + Into<#output> + 'static
                {
                    self.returning_st(move |#(#argnames, )*| __mockall_c.clone().into())
                }

                /// Supply an `FnOnce` closure that will provide the return
                /// value for this Expectation.  This is useful for return types
                /// that aren't `Clone`.  It will be an error to call this
                /// method multiple times.
                #v fn return_once<MockallF>(&mut self, __mockall_f: MockallF)
                    -> &mut Self
                    where MockallF: #hrtb FnOnce(#(#argty, )*)
                                    -> #output + Send + 'static
                {
                    {
                        let mut __mockall_guard = self.rfunc.lock().unwrap();
                        *__mockall_guard.deref_mut() =
                            Rfunc::Once(Box::new(__mockall_f));
                    }
                    self
                }

                /// Single-threaded version of
                /// [`return_once`](#method.return_once).  This is useful for
                /// return types that are neither `Send` nor `Clone`.
                ///
                /// It is a runtime error to call the mock method from a
                /// different thread than the one that originally called this
                /// method.  It is also a runtime error to call the method more
                /// than once.
                #v fn return_once_st<MockallF>(&mut self, __mockall_f:
                                                  MockallF) -> &mut Self
                    where MockallF: #hrtb FnOnce(#(#argty, )*)
                                    -> #output + 'static
                {
                    {
                        let mut __mockall_guard = self.rfunc.lock().unwrap();
                        *__mockall_guard.deref_mut() = Rfunc::OnceST(
                            ::mockall::Fragile::new(Box::new(__mockall_f)));
                    }
                    self
                }

                /// Supply a closure that will provide the return value for this
                /// `Expectation`.  The method's arguments are passed to the
                /// closure by value.
                #v fn returning<MockallF>(&mut self, __mockall_f: MockallF)
                    -> &mut Self
                    where MockallF: #hrtb FnMut(#(#argty, )*)
                                    -> #output + Send + 'static
                {
                    {
                        let mut __mockall_guard = self.rfunc.lock().unwrap();
                        *__mockall_guard.deref_mut() =
                            Rfunc::Mut(Box::new(__mockall_f));
                    }
                    self
                }

                /// Single-threaded version of [`returning`](#method.returning).
                /// Can be used when the argument or return type isn't `Send`.
                ///
                /// It is a runtime error to call the mock method from a
                /// different thread than the one that originally called this
                /// method.
                #v fn returning_st<MockallF>(&mut self, __mockall_f: MockallF)
                    -> &mut Self
                    where MockallF: #hrtb FnMut(#(#argty, )*)
                                    -> #output + 'static
                {
                    {
                        let mut __mockall_guard = self.rfunc.lock().unwrap();
                        *__mockall_guard.deref_mut() = Rfunc::MutST(
                            ::mockall::Fragile::new(Box::new(__mockall_f)));
                    }
                    self
                }

                #common_methods
            }
            impl #ig Default for Expectation #tg #wc
            {
                fn default() -> Self {
                    Expectation {
                        common: Common::default(),
                        rfunc: Mutex::new(Rfunc::default())
                    }
                }
            }
        ).to_tokens(tokens);
    }
}

/// An collection of RefExpectation's
struct RefExpectations<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for RefExpectations<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let common_methods = CommonExpectationsMethods{f: &self.f};
        let argnames = &self.f.argnames;
        let argty = &self.f.argty;
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let output = &self.f.output;
        let predexprs = &self.f.predexprs;
        let v = &self.f.privmod_vis;
        quote!(
            #common_methods
            impl #ig Expectations #tg #wc {
                /// Simulate calling the real method.  Every current expectation
                /// will be checked in FIFO order and the first one with
                /// matching arguments will be used.
                #v fn call #lg (&self, #(#argnames: #argty, )* )
                    -> Option<#output>
                {
                    self.0.iter()
                        .find(|__mockall_e|
                              __mockall_e.matches(#(#predexprs, )*) &&
                              (!__mockall_e.is_done() || self.0.len() == 1))
                        .map(move |__mockall_e|
                             __mockall_e.call()
                        )
                }

            }
        ).to_tokens(tokens);
    }
}

/// An collection of RefMutExpectation's
struct RefMutExpectations<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for RefMutExpectations<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let common_methods = CommonExpectationsMethods{f: &self.f};
        let argnames = &self.f.argnames;
        let argty = &self.f.argty;
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let output = &self.f.output;
        let predexprs = &self.f.predexprs;
        let v = &self.f.privmod_vis;
        quote!(
            #common_methods
            impl #ig Expectations #tg #wc {
                /// Simulate calling the real method.  Every current expectation
                /// will be checked in FIFO order and the first one with
                /// matching arguments will be used.
                #v fn call_mut #lg (&mut self, #(#argnames: #argty, )* )
                    -> Option<#output>
                {
                    let __mockall_n = self.0.len();
                    self.0.iter_mut()
                        .find(|__mockall_e|
                              __mockall_e.matches(#(#predexprs, )*) &&
                              (!__mockall_e.is_done() || __mockall_n == 1))
                        .map(move |__mockall_e|
                             __mockall_e.call_mut(#(#argnames, )*)
                        )
                }

            }
        ).to_tokens(tokens);
    }
}

/// An collection of Expectation's for methods returning static values
struct StaticExpectations<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for StaticExpectations<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let common_methods = CommonExpectationsMethods{f: &self.f};
        let argnames = &self.f.argnames;
        let argty = &self.f.argty;
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let lg = lifetimes_to_generics(&self.f.alifetimes);
        let output = &self.f.output;
        let predexprs = &self.f.predexprs;
        let v = &self.f.privmod_vis;
        quote!(
            #common_methods
            impl #ig Expectations #tg #wc {
                /// Simulate calling the real method.  Every current expectation
                /// will be checked in FIFO order and the first one with
                /// matching arguments will be used.
                #v fn call #lg (&self, #(#argnames: #argty, )* )
                    -> Option<#output>
                {
                    self.0.iter()
                        .find(|__mockall_e|
                              __mockall_e.matches(#(#predexprs, )*) &&
                              (!__mockall_e.is_done() || self.0.len() == 1))
                        .map(move |__mockall_e|
                             __mockall_e.call(#(#argnames, )*)
                        )
                }

            }
        ).to_tokens(tokens);
    }
}

struct GenericExpectations<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for GenericExpectations<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        if ! self.f.is_expectation_generic() {
            return;
        }
        if ! self.f.is_static() && ! self.f.is_method_generic() {
            return;
        }

        let ge = StaticGenericExpectations{f: self.f};
        let v = &self.f.privmod_vis;
        quote!(
            /// A collection of [`Expectation`](struct.Expectations.html)
            /// objects for a generic method.  Users will rarely if ever use
            /// this struct directly.
            #[doc(hidden)]
            #[derive(Default)]
            #v struct GenericExpectations{
                store: std::collections::hash_map::HashMap<::mockall::Key,
                               Box<dyn ::mockall::AnyExpectations>>
            }
            impl GenericExpectations {
                /// Verify that all current expectations are satisfied and clear
                /// them.  This applies to all sets of generic parameters!
                #v fn checkpoint(&mut self) ->
                    std::collections::hash_map::Drain<::mockall::Key,
                               Box<dyn ::mockall::AnyExpectations>>
                {
                    self.store.drain()
                }

                #v fn new() -> Self {
                    Self::default()
                }
            }
            #ge
        ).to_tokens(tokens);
    }
}

/// Generates methods for GenericExpectations for methods returning static
/// values
struct StaticGenericExpectations<'a> {
    f: &'a MockFunction
}

impl<'a> ToTokens for StaticGenericExpectations<'a> {
    fn to_tokens(&self, tokens: &mut TokenStream) {
        let argnames = &self.f.argnames;
        let argty = &self.f.argty;
        let (ig, tg, wc) = self.f.egenerics.split_for_impl();
        let mut any_wc = wc.cloned();
        if self.f.return_ref || self.f.return_refmut {
            // Add Senc + Sync, required for downcast, since Expectation
            // stores an Option<#owned_output>
            send_syncify(&mut any_wc, self.f.owned_output.clone());
        }
        let tbf = tg.as_turbofish();
        let oo = &self.f.owned_output;
        let output = &self.f.output;
        let v = &self.f.privmod_vis;
        let (call, get, self_, downcast) = if self.f.return_refmut {
            (format_ident!("call_mut"),
             format_ident!("get_mut"),
             quote!(&mut self),
             format_ident!("downcast_mut"))
        } else {
            (format_ident!("call"),
             format_ident!("get"),
             quote!(&self),
             format_ident!("downcast_ref"))
        };
        quote!(
            impl #ig ::mockall::AnyExpectations for Expectations #tg #any_wc {}
            impl GenericExpectations {
                /// Simulating calling the real method.
                #v fn #call #ig (#self_, #(#argnames: #argty, )* )
                    -> Option<#output> #wc
                {
                    self.store.#get(&::mockall::Key::new::<(#oo, #(#argty, )*)>())
                        .map(|__mockall_e| {
                            __mockall_e.#downcast::<Expectations #tg>()
                            .unwrap()
                            .#call(#(#argnames, )*)
                        }).flatten()
                }

                /// Create a new Expectation.
                #v fn expect #ig (&mut self) -> &mut Expectation #tg #any_wc
                {
                    self.store.entry(::mockall::Key::new::<(#oo, #(#argty, )*)>())
                        .or_insert_with(|| Box::new(Expectations #tbf::new()))
                        .downcast_mut::<Expectations #tg>()
                        .unwrap()
                        .expect()
                }
            }
        ).to_tokens(tokens)
    }
}

