diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..1232443
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,6 @@
+{
+  "git": {
+    "sha1": "d5351f7215c6c5bca11f704ed41d9ae768b43007"
+  },
+  "path_in_vcs": "mockall_derive"
+}
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..2220f21
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,37 @@
+// This file is generated by cargo_embargo.
+// Do not modify this file as changes will be overridden on upgrade.
+
+rust_proc_macro {
+    name: "libmockall_derive",
+    crate_name: "mockall_derive",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.11.4",
+    srcs: ["src/lib.rs"],
+    edition: "2018",
+    rustlibs: [
+        "libcfg_if",
+        "libproc_macro2",
+        "libquote",
+        "libsyn_deprecated",
+    ],
+}
+
+rust_test_host {
+    name: "mockall_derive_test_src_lib",
+    crate_name: "mockall_derive",
+    cargo_env_compat: true,
+    cargo_pkg_version: "0.11.4",
+    srcs: ["src/lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    test_options: {
+        unit_test: true,
+    },
+    edition: "2018",
+    rustlibs: [
+        "libcfg_if",
+        "libproc_macro2",
+        "libquote",
+        "libsyn_deprecated",
+    ],
+}
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..89d8bc1
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,58 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "mockall_derive"
+version = "0.11.4"
+authors = ["Alan Somers <asomers@gmail.com>"]
+description = """
+Procedural macros for Mockall
+"""
+documentation = "https://docs.rs/mockall_derive"
+readme = "README.md"
+keywords = [
+    "mock",
+    "mocking",
+    "testing",
+]
+categories = ["development-tools::testing"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/asomers/mockall"
+
+[package.metadata.release]
+push = false
+tag = false
+
+[lib]
+proc-macro = true
+
+[dependencies.cfg-if]
+version = "1.0"
+
+[dependencies.proc-macro2]
+version = "1.0"
+
+[dependencies.quote]
+version = "1.0"
+
+[dependencies.syn]
+version = "1.0.87"
+features = [
+    "extra-traits",
+    "full",
+]
+
+[dev-dependencies.pretty_assertions]
+version = "1.3"
+
+[features]
+nightly_derive = ["proc-macro2/nightly"]
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..6b579aa
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+LICENSE-APACHE
\ No newline at end of file
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 100644
index 0000000..16fe87b
--- /dev/null
+++ b/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+   To apply the Apache License to your work, attach the following
+   boilerplate notice, with the fields enclosed by brackets "[]"
+   replaced with your own identifying information. (Don't include
+   the brackets!)  The text should be enclosed in the appropriate
+   comment syntax for the file format. We also recommend that a
+   file or class name and description of purpose be included on the
+   same "printed page" as the copyright notice for easier
+   identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..39df3da
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2019 Alan Somers
+
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..eaa868e
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,20 @@
+name: "mockall_derive"
+description: "()"
+third_party {
+  identifier {
+    type: "crates.io"
+    value: "https://crates.io/crates/mockall_derive"
+  }
+  identifier {
+    type: "Archive"
+    value: "https://static.crates.io/crates/mockall_derive/mockall_derive-0.11.4.crate"
+  }
+  version: "0.11.4"
+  # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same.
+  license_type: NOTICE
+  last_upgrade_date {
+    year: 2023
+    month: 11
+    day: 6
+  }
+}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..48bea6e
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 688011
+include platform/prebuilts/rust:main:/OWNERS
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2fa2632
--- /dev/null
+++ b/README.md
@@ -0,0 +1,14 @@
+# Mockall_derive
+
+This crate should never be used directly.  You should use
+[`mockall`](https://crates.io/crates/mockall) instead.
+
+# License
+
+`mockall` is primarily distributed under the terms of both the MIT license
+and the Apache License (Version 2.0), with portions covered by various BSD-like
+licenses.
+
+See LICENSE-APACHE, and LICENSE-MIT for details
+
+
diff --git a/cargo_embargo.json b/cargo_embargo.json
new file mode 100644
index 0000000..f14bd80
--- /dev/null
+++ b/cargo_embargo.json
@@ -0,0 +1,12 @@
+{
+  "tests": true,
+  "package": {
+    "mockall_derive": {
+      "device_supported": false,
+      "dep_blocklist": [
+        "libpretty_assertions"
+      ],
+      "patch": "patches/use-deprecated-syn1-dep.patch"
+    }
+  }
+}
diff --git a/patches/remove-pretty-assertions-dep.patch b/patches/remove-pretty-assertions-dep.patch
new file mode 100644
index 0000000..8340ef6
--- /dev/null
+++ b/patches/remove-pretty-assertions-dep.patch
@@ -0,0 +1,12 @@
+Not actually needed if the tests pass...
+
+--- a/src/automock.rs	2006-07-24 03:21:28.000000000 +0200
++++ b/src/automock.rs	2023-11-06 14:54:02.079601472 +0100
+@@ -280,7 +280,6 @@
+ #[cfg(test)]
+ mod t {
+     use super::super::*;
+-    use pretty_assertions::assert_eq;
+ 
+     fn check_substitute_type(
+         attrs: TokenStream,
diff --git a/patches/use-deprecated-syn1-dep.patch b/patches/use-deprecated-syn1-dep.patch
new file mode 100644
index 0000000..5d85ecf
--- /dev/null
+++ b/patches/use-deprecated-syn1-dep.patch
@@ -0,0 +1,21 @@
+Patch Android.bp to use the old syn v1 package.
+
+--- a/Android.bp	2023-11-06 16:05:46.887866053 +0100
++++ b/Android.bp	2023-11-06 16:06:15.768058832 +0100
+@@ -14,7 +14,7 @@
+         "libcfg_if",
+         "libproc_macro2",
+         "libquote",
+-        "libsyn",
++        "libsyn_deprecated",
+     ],
+ }
+ 
+@@ -34,6 +34,6 @@
+         "libcfg_if",
+         "libproc_macro2",
+         "libquote",
+-        "libsyn",
++        "libsyn_deprecated",
+     ],
+ }
diff --git a/patches/use-explicit-extern-crate-proc-macro.patch b/patches/use-explicit-extern-crate-proc-macro.patch
new file mode 100644
index 0000000..5985b65
--- /dev/null
+++ b/patches/use-explicit-extern-crate-proc-macro.patch
@@ -0,0 +1,14 @@
+Cargo automatically imports proc_macro in Rust 2018, but Soong only
+does this for rust_proc_macro targets.
+
+--- a/src/lib.rs	2023-11-06 16:32:46.480193187 +0100
++++ b/src/lib.rs	2023-11-06 16:29:38.743132168 +0100
+@@ -34,6 +34,8 @@
+ use crate::mock_item_struct::MockItemStruct;
+ use crate::mockable_item::MockableItem;
+ 
++extern crate proc_macro;
++
+ // Define deterministic aliases for these common types.
+ type HashMap<K, V> = std::collections::HashMap<K, V, BuildHasherDefault<std::collections::hash_map::DefaultHasher>>;
+ type HashSet<K> = std::collections::HashSet<K, BuildHasherDefault<std::collections::hash_map::DefaultHasher>>;
diff --git a/src/automock.rs b/src/automock.rs
new file mode 100644
index 0000000..bba6cb1
--- /dev/null
+++ b/src/automock.rs
@@ -0,0 +1,325 @@
+// vim: tw=80
+use super::*;
+use std::collections::HashMap;
+use syn::parse::{Parse, ParseStream};
+
+/// A single automock attribute
+// This enum is very short-lived, so it's fine not to box it.
+#[allow(clippy::large_enum_variant)]
+enum Attr {
+    Mod(ItemMod),
+    Type(TraitItemType),
+}
+
+impl Parse for Attr {
+    fn parse(input: ParseStream) -> parse::Result<Self> {
+        let lookahead = input.lookahead1();
+        if lookahead.peek(Token![mod]) {
+            input.parse().map(Attr::Mod)
+        } else if lookahead.peek(Token![type]) {
+            input.parse().map(Attr::Type)
+        } else {
+            Err(lookahead.error())
+        }
+    }
+}
+
+/// automock attributes
+#[derive(Debug, Default)]
+pub(crate) struct Attrs {
+    pub attrs: HashMap<Ident, Type>,
+    pub modname: Option<Ident>,
+}
+
+impl Attrs {
+    fn get_path(&self, path: &Path) -> Option<Type> {
+        if path.leading_colon.is_none() & (path.segments.len() == 2) {
+            if path.segments.first().unwrap().ident == "Self" {
+                let ident = &path.segments.last().unwrap().ident;
+                self.attrs.get(ident).cloned()
+            } else {
+                None
+            }
+        } else {
+            None
+        }
+    }
+
+    pub(crate) fn substitute_item_impl(&self, item_impl: &mut ItemImpl) {
+        let (_, trait_path, _) = item_impl
+            .trait_
+            .as_ref()
+            .expect("Should only be called for trait item impls");
+        let trait_ident = find_ident_from_path(trait_path).0;
+        for item in item_impl.items.iter_mut() {
+            if let ImplItem::Method(method) = item {
+                let sig = &mut method.sig;
+                for fn_arg in sig.inputs.iter_mut() {
+                    if let FnArg::Typed(arg) = fn_arg {
+                        self.substitute_type(&mut arg.ty, &trait_ident);
+                    }
+                }
+                if let ReturnType::Type(_, ref mut ty) = &mut sig.output {
+                    self.substitute_type(ty, &trait_ident);
+                }
+            }
+        }
+    }
+
+    fn substitute_path_segment(&self, seg: &mut PathSegment, traitname: &Ident) {
+        match &mut seg.arguments {
+            PathArguments::None =>
+            /* nothing to do */
+            {
+                ()
+            }
+            PathArguments::Parenthesized(p) => {
+                compile_error(p.span(),
+                    "Mockall does not support mocking Fn objects.  See https://github.com/asomers/mockall/issues/139");
+            }
+            PathArguments::AngleBracketed(abga) => {
+                for arg in abga.args.iter_mut() {
+                    match arg {
+                        GenericArgument::Type(ty) => self.substitute_type(ty, traitname),
+                        GenericArgument::Binding(binding) => {
+                            self.substitute_type(&mut binding.ty, traitname);
+                        }
+                        _ => {
+                            /*
+                             * Nothing to do, as long as lifetimes can't be
+                             * associated types
+                             */
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /// Recursively substitute types in the input
+    fn substitute_type(&self, ty: &mut Type, traitname: &Ident) {
+        match ty {
+            Type::Slice(s) => self.substitute_type(s.elem.as_mut(), traitname),
+            Type::Array(a) => self.substitute_type(a.elem.as_mut(), traitname),
+            Type::Ptr(p) => self.substitute_type(p.elem.as_mut(), traitname),
+            Type::Reference(r) => self.substitute_type(r.elem.as_mut(), traitname),
+            Type::BareFn(bfn) => {
+                for fn_arg in bfn.inputs.iter_mut() {
+                    self.substitute_type(&mut fn_arg.ty, traitname);
+                }
+                if let ReturnType::Type(_, ref mut ty) = &mut bfn.output {
+                    self.substitute_type(ty, traitname);
+                }
+            }
+            Type::Tuple(tuple) => {
+                for elem in tuple.elems.iter_mut() {
+                    self.substitute_type(elem, traitname)
+                }
+            }
+            Type::Path(path) => {
+                if let Some(ref qself) = path.qself {
+                    let qp = if let Type::Path(p) = qself.ty.as_ref() {
+                        &p.path
+                    } else {
+                        panic!("QSelf's type isn't a path?")
+                    };
+                    let qident = &qp.segments.first().unwrap().ident;
+                    if qself.position != 1
+                        || qp.segments.len() != 1
+                        || path.path.segments.len() != 2
+                        || qident != "Self"
+                    {
+                        compile_error(path.span(), "QSelf is a work in progress");
+                    }
+
+                    let mut seg_iter = path.path.segments.iter().rev();
+                    let last_seg = seg_iter.next().unwrap();
+                    let to_sub = &last_seg.ident;
+                    let penultimate_seg = seg_iter.next().unwrap();
+                    let qident = &penultimate_seg.ident;
+                    drop(seg_iter);
+
+                    if qident != traitname {
+                        compile_error(qident.span(),
+                            "Mockall does not support QSelf substitutions except for the trait being mocked");
+                    }
+                    if let Some(new_type) = self.attrs.get(to_sub) {
+                        *ty = new_type.clone();
+                    } else {
+                        compile_error(to_sub.span(), "Unknown type substitution for QSelf");
+                    }
+                } else if let Some(newty) = self.get_path(&path.path) {
+                    *ty = newty;
+                } else {
+                    for seg in path.path.segments.iter_mut() {
+                        self.substitute_path_segment(seg, traitname);
+                    }
+                }
+            }
+            Type::TraitObject(to) => {
+                for bound in to.bounds.iter_mut() {
+                    self.substitute_type_param_bound(bound, traitname);
+                }
+            }
+            Type::ImplTrait(it) => {
+                for bound in it.bounds.iter_mut() {
+                    self.substitute_type_param_bound(bound, traitname);
+                }
+            }
+            Type::Paren(p) => self.substitute_type(p.elem.as_mut(), traitname),
+            Type::Group(g) => self.substitute_type(g.elem.as_mut(), traitname),
+            Type::Macro(_) | Type::Verbatim(_) => {
+                compile_error(
+                    ty.span(),
+                    "mockall_derive does not support this type when using associated types",
+                );
+            }
+            Type::Infer(_) | Type::Never(_) => { /* Nothing to do */ }
+            _ => compile_error(ty.span(), "Unsupported type"),
+        }
+    }
+
+    fn substitute_type_param_bound(&self, bound: &mut TypeParamBound, traitname: &Ident) {
+        if let TypeParamBound::Trait(t) = bound {
+            match self.get_path(&t.path) {
+                None => {
+                    for seg in t.path.segments.iter_mut() {
+                        self.substitute_path_segment(seg, traitname);
+                    }
+                }
+                Some(Type::Path(type_path)) => {
+                    t.path = type_path.path;
+                }
+                Some(_) => {
+                    compile_error(t.path.span(), "Can only substitute paths for trait bounds");
+                }
+            }
+        }
+    }
+
+    pub(crate) fn substitute_trait(&self, item: &ItemTrait) -> ItemTrait {
+        let mut output = item.clone();
+        for trait_item in output.items.iter_mut() {
+            match trait_item {
+                TraitItem::Type(tity) => {
+                    if let Some(ty) = self.attrs.get(&tity.ident) {
+                        let span = tity.span();
+                        tity.default = Some((Token![=](span), ty.clone()));
+                        // Concrete associated types aren't allowed to have
+                        // bounds
+                        tity.bounds = Punctuated::new();
+                    } else {
+                        compile_error(tity.span(), "Default value not given for associated type");
+                    }
+                }
+                TraitItem::Method(method) => {
+                    let sig = &mut method.sig;
+                    for fn_arg in sig.inputs.iter_mut() {
+                        if let FnArg::Typed(arg) = fn_arg {
+                            self.substitute_type(&mut arg.ty, &item.ident);
+                        }
+                    }
+                    if let ReturnType::Type(_, ref mut ty) = &mut sig.output {
+                        self.substitute_type(ty, &item.ident);
+                    }
+                }
+                _ => {
+                    // Nothing to do
+                }
+            }
+        }
+        output
+    }
+}
+
+impl Parse for Attrs {
+    fn parse(input: ParseStream) -> parse::Result<Self> {
+        let mut attrs = HashMap::new();
+        let mut modname = None;
+        while !input.is_empty() {
+            let attr: Attr = input.parse()?;
+            match attr {
+                Attr::Mod(item_mod) => {
+                    if let Some((br, _)) = item_mod.content {
+                        compile_error(
+                            br.span,
+                            "mod name attributes must have the form \"mod my_name;\"",
+                        );
+                    }
+                    modname = Some(item_mod.ident.clone());
+                }
+                Attr::Type(trait_item_type) => {
+                    let ident = trait_item_type.ident.clone();
+                    if let Some((_, ty)) = trait_item_type.default {
+                        attrs.insert(ident, ty.clone());
+                    } else {
+                        compile_error(
+                            trait_item_type.span(),
+                            "automock type attributes must have a default value",
+                        );
+                    }
+                }
+            }
+        }
+        Ok(Attrs { attrs, modname })
+    }
+}
+
+/// Unit tests for `Attrs`.
+#[cfg(test)]
+mod t {
+    use super::super::*;
+
+    fn check_substitute_type(
+        attrs: TokenStream,
+        input: TokenStream,
+        traitname: Ident,
+        expected: TokenStream,
+    ) {
+        let _self: super::Attrs = parse2(attrs).unwrap();
+        let mut in_ty: Type = parse2(input).unwrap();
+        let expect_ty: Type = parse2(expected).unwrap();
+        _self.substitute_type(&mut in_ty, &traitname);
+        assert_eq!(in_ty, expect_ty);
+    }
+
+    #[test]
+    fn qself() {
+        check_substitute_type(
+            quote!(
+                type T = u32;
+            ),
+            quote!(<Self as Foo>::T),
+            format_ident!("Foo"),
+            quote!(u32),
+        );
+    }
+
+    #[test]
+    #[should_panic(
+        expected = "Mockall does not support QSelf substitutions except for the trait being mocked"
+    )]
+    fn qself_other() {
+        check_substitute_type(
+            quote!(
+                type T = u32;
+            ),
+            quote!(<Self as AsRef>::T),
+            format_ident!("Foo"),
+            quote!(u32),
+        );
+    }
+
+    #[test]
+    #[should_panic(expected = "Unknown type substitution for QSelf")]
+    fn unknown_substitution() {
+        check_substitute_type(
+            quote!(
+                type T = u32;
+            ),
+            quote!(<Self as Foo>::Q),
+            format_ident!("Foo"),
+            quote!(u32),
+        );
+    }
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..6308c45
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,1761 @@
+// vim: tw=80
+//! Proc Macros for use with Mockall
+//!
+//! You probably don't want to use this crate directly.  Instead, you should use
+//! its reexports via the [`mockall`](https://docs.rs/mockall/latest/mockall)
+//! crate.
+
+#![cfg_attr(feature = "nightly_derive", feature(proc_macro_diagnostic))]
+#![cfg_attr(test, deny(warnings))]
+
+use cfg_if::cfg_if;
+use proc_macro2::{Span, TokenStream};
+use quote::{ToTokens, format_ident, quote};
+use std::{
+    env,
+    hash::BuildHasherDefault
+};
+use syn::{
+    *,
+    punctuated::Punctuated,
+    spanned::Spanned
+};
+
+mod automock;
+mod mock_function;
+mod mock_item;
+mod mock_item_struct;
+mod mock_trait;
+mod mockable_item;
+mod mockable_struct;
+use crate::automock::Attrs;
+use crate::mockable_struct::MockableStruct;
+use crate::mock_item::MockItem;
+use crate::mock_item_struct::MockItemStruct;
+use crate::mockable_item::MockableItem;
+
+extern crate proc_macro;
+
+// Define deterministic aliases for these common types.
+type HashMap<K, V> = std::collections::HashMap<K, V, BuildHasherDefault<std::collections::hash_map::DefaultHasher>>;
+type HashSet<K> = std::collections::HashSet<K, BuildHasherDefault<std::collections::hash_map::DefaultHasher>>;
+
+cfg_if! {
+    // proc-macro2's Span::unstable method requires the nightly feature, and it
+    // doesn't work in test mode.
+    // https://github.com/alexcrichton/proc-macro2/issues/159
+    if #[cfg(all(feature = "nightly_derive", not(test)))] {
+        fn compile_error(span: Span, msg: &str) {
+            span.unstable()
+                .error(msg)
+                .emit();
+        }
+    } else {
+        fn compile_error(_span: Span, msg: &str) {
+            panic!("{}.  More information may be available when mockall is built with the \"nightly\" feature.", msg);
+        }
+    }
+}
+
+fn deanonymize_lifetime(lt: &mut Lifetime) {
+    if lt.ident == "_" {
+        lt.ident = format_ident!("static");
+    }
+}
+
+fn deanonymize_path(path: &mut Path) {
+    for seg in path.segments.iter_mut() {
+        match &mut seg.arguments {
+            PathArguments::None => (),
+            PathArguments::AngleBracketed(abga) => {
+                for ga in abga.args.iter_mut() {
+                    if let GenericArgument::Lifetime(lt) = ga {
+                        deanonymize_lifetime(lt)
+                    }
+                }
+            },
+            _ => compile_error(seg.arguments.span(),
+                "Methods returning functions are TODO"),
+        }
+    }
+}
+
+/// Replace any references to the anonymous lifetime `'_` with `'static`.
+fn deanonymize(literal_type: &mut Type) {
+    match literal_type {
+        Type::Array(ta) => deanonymize(ta.elem.as_mut()),
+        Type::BareFn(tbf) => {
+            if let ReturnType::Type(_, ref mut bt) = tbf.output {
+                deanonymize(bt.as_mut());
+            }
+            for input in tbf.inputs.iter_mut() {
+                deanonymize(&mut input.ty);
+            }
+        },
+        Type::Group(tg) => deanonymize(tg.elem.as_mut()),
+        Type::Infer(_) => (),
+        Type::Never(_) => (),
+        Type::Paren(tp) => deanonymize(tp.elem.as_mut()),
+        Type::Path(tp) => {
+            if let Some(ref mut qself) = tp.qself {
+                deanonymize(qself.ty.as_mut());
+            }
+            deanonymize_path(&mut tp.path);
+        },
+        Type::Ptr(tptr) => deanonymize(tptr.elem.as_mut()),
+        Type::Reference(tr) => {
+            if let Some(lt) = tr.lifetime.as_mut() {
+                deanonymize_lifetime(lt)
+            }
+            deanonymize(tr.elem.as_mut());
+        },
+        Type::Slice(s) => deanonymize(s.elem.as_mut()),
+        Type::TraitObject(tto) => {
+            for tpb in tto.bounds.iter_mut() {
+                match tpb {
+                    TypeParamBound::Trait(tb) => deanonymize_path(&mut tb.path),
+                    TypeParamBound::Lifetime(lt) => deanonymize_lifetime(lt),
+                }
+            }
+        },
+        Type::Tuple(tt) => {
+            for ty in tt.elems.iter_mut() {
+                deanonymize(ty)
+            }
+        }
+        x => compile_error(x.span(), "Unimplemented type for deanonymize")
+    }
+}
+
+// If there are any closures in the argument list, turn them into boxed
+// functions
+fn declosurefy(gen: &Generics, args: &Punctuated<FnArg, Token![,]>) ->
+    (Generics, Vec<FnArg>, Vec<TokenStream>)
+{
+    let mut hm = HashMap::default();
+
+    let mut save_fn_types = |ident: &Ident, tpb: &TypeParamBound| {
+        if let TypeParamBound::Trait(tb) = tpb {
+            let fident = &tb.path.segments.last().unwrap().ident;
+            if ["Fn", "FnMut", "FnOnce"].iter().any(|s| fident == *s) {
+                let newty: Type = parse2(quote!(Box<dyn #tb>)).unwrap();
+                let subst_ty: Type = parse2(quote!(#ident)).unwrap();
+                assert!(hm.insert(subst_ty, newty).is_none(),
+                    "A generic parameter had two Fn bounds?");
+            }
+        }
+    };
+
+    // First, build a HashMap of all Fn generic types
+    for g in gen.params.iter() {
+        if let GenericParam::Type(tp) = g {
+            for tpb in tp.bounds.iter() {
+                save_fn_types(&tp.ident, tpb);
+            }
+        }
+    }
+    if let Some(wc) = &gen.where_clause {
+        for pred in wc.predicates.iter() {
+            if let WherePredicate::Type(pt) = pred {
+                let bounded_ty = &pt.bounded_ty;
+                if let Ok(ident) = parse2::<Ident>(quote!(#bounded_ty)) {
+                    for tpb in pt.bounds.iter() {
+                        save_fn_types(&ident, tpb);
+                    }
+                } else {
+                    // We can't yet handle where clauses this complicated
+                }
+            }
+        }
+    }
+
+    // Then remove those types from both the Generics' params and where clause
+    let should_remove = |ident: &Ident| {
+            let ty: Type = parse2(quote!(#ident)).unwrap();
+            hm.contains_key(&ty)
+    };
+    let params = gen.params.iter()
+        .filter(|g| {
+            if let GenericParam::Type(tp) = g {
+                !should_remove(&tp.ident)
+            } else {
+                true
+            }
+        }).cloned()
+        .collect::<Punctuated<_, _>>();
+    let mut wc2 = gen.where_clause.clone();
+    if let Some(wc) = &mut wc2 {
+        wc.predicates = wc.predicates.iter()
+            .filter(|wp| {
+                if let WherePredicate::Type(pt) = wp {
+                    let bounded_ty = &pt.bounded_ty;
+                    if let Ok(ident) = parse2::<Ident>(quote!(#bounded_ty)) {
+                        !should_remove(&ident)
+                    } else {
+                        // We can't yet handle where clauses this complicated
+                        true
+                    }
+                } else {
+                    true
+                }
+            }).cloned()
+            .collect::<Punctuated<_, _>>();
+        if wc.predicates.is_empty() {
+            wc2 = None;
+        }
+    }
+    let outg = Generics {
+        lt_token: if params.is_empty() { None } else { gen.lt_token },
+        gt_token: if params.is_empty() { None } else { gen.gt_token },
+        params,
+        where_clause: wc2
+    };
+
+    // Next substitute Box<Fn> into the arguments
+    let outargs = args.iter().map(|arg| {
+        if let FnArg::Typed(pt) = arg {
+            let mut immutable_pt = pt.clone();
+            demutify_arg(&mut immutable_pt);
+            if let Some(newty) = hm.get(&pt.ty) {
+                FnArg::Typed(PatType {
+                    attrs: Vec::default(),
+                    pat: immutable_pt.pat,
+                    colon_token: pt.colon_token,
+                    ty: Box::new(newty.clone())
+                })
+            } else {
+                FnArg::Typed(PatType {
+                    attrs: Vec::default(),
+                    pat: immutable_pt.pat,
+                    colon_token: pt.colon_token,
+                    ty: pt.ty.clone()
+                })
+            }
+        } else {
+            arg.clone()
+        }
+    }).collect();
+
+    // Finally, Box any closure arguments
+    // use filter_map to remove the &self argument
+    let callargs = args.iter().filter_map(|arg| {
+        match arg {
+            FnArg::Typed(pt) => {
+                let mut pt2 = pt.clone();
+                demutify_arg(&mut pt2);
+                let pat = &pt2.pat;
+                if pat_is_self(pat) {
+                    None
+                } else if hm.contains_key(&pt.ty) {
+                    Some(quote!(Box::new(#pat)))
+                } else {
+                    Some(quote!(#pat))
+                }
+            },
+            FnArg::Receiver(_) => None,
+        }
+    }).collect();
+    (outg, outargs, callargs)
+}
+
+/// Replace any "impl trait" types with "Box<dyn trait>" or equivalent.
+fn deimplify(rt: &mut ReturnType) {
+    if let ReturnType::Type(_, ty) = rt {
+        if let Type::ImplTrait(ref tit) = &**ty {
+            let needs_pin = tit.bounds
+                .iter()
+                .any(|tpb| {
+                    if let TypeParamBound::Trait(tb) = tpb {
+                        if let Some(seg) = tb.path.segments.last() {
+                            seg.ident == "Future" || seg.ident == "Stream"
+                        } else {
+                            // It might still be a Future, but we can't guess
+                            // what names it might be imported under.  Too bad.
+                            false
+                        }
+                    } else {
+                        false
+                    }
+                });
+            let bounds = &tit.bounds;
+            if needs_pin {
+                *ty = parse2(quote!(::std::pin::Pin<Box<dyn #bounds>>)).unwrap();
+            } else {
+                *ty = parse2(quote!(Box<dyn #bounds>)).unwrap();
+            }
+        }
+    }
+}
+
+/// Remove any generics that place constraints on Self.
+fn dewhereselfify(generics: &mut Generics) {
+    if let Some(ref mut wc) = &mut generics.where_clause {
+        let new_predicates = wc.predicates.iter()
+            .filter(|wp| match wp {
+                WherePredicate::Type(pt) => {
+                    pt.bounded_ty != parse2(quote!(Self)).unwrap()
+                },
+                _ => true
+            }).cloned()
+            .collect::<Punctuated<WherePredicate, Token![,]>>();
+        wc.predicates = new_predicates;
+    }
+    if generics.where_clause.as_ref()
+        .map(|wc| wc.predicates.is_empty())
+        .unwrap_or(false)
+    {
+        generics.where_clause = None;
+    }
+}
+
+/// Remove any mutability qualifiers from a method's argument list
+fn demutify(inputs: &mut Punctuated<FnArg, token::Comma>) {
+    for arg in inputs.iter_mut() {
+        match arg {
+            FnArg::Receiver(r) => if r.reference.is_none() {
+                r.mutability = None
+            },
+            FnArg::Typed(pt) => demutify_arg(pt),
+        }
+    }
+}
+
+/// Remove any "mut" from a method argument's binding.
+fn demutify_arg(arg: &mut PatType) {
+    match *arg.pat {
+        Pat::Wild(_) => {
+            compile_error(arg.span(),
+                "Mocked methods must have named arguments");
+        },
+        Pat::Ident(ref mut pat_ident) => {
+            if let Some(r) = &pat_ident.by_ref {
+                compile_error(r.span(),
+                    "Mockall does not support by-reference argument bindings");
+            }
+            if let Some((_at, subpat)) = &pat_ident.subpat {
+                compile_error(subpat.span(),
+                    "Mockall does not support subpattern bindings");
+            }
+            pat_ident.mutability = None;
+        },
+        _ => {
+            compile_error(arg.span(), "Unsupported argument type");
+        }
+    };
+}
+
+fn deselfify_path(path: &mut Path, actual: &Ident, generics: &Generics) {
+    for seg in path.segments.iter_mut() {
+        if seg.ident == "Self" {
+            seg.ident = actual.clone();
+            if let PathArguments::None = seg.arguments {
+                if !generics.params.is_empty() {
+                    let args = generics.params.iter()
+                        .map(|gp| {
+                            match gp {
+                                GenericParam::Type(tp) => {
+                                    let ident = tp.ident.clone();
+                                    GenericArgument::Type(
+                                        Type::Path(
+                                            TypePath {
+                                                qself: None,
+                                                path: Path::from(ident)
+                                            }
+                                        )
+                                    )
+                                },
+                                GenericParam::Lifetime(ld) =>{
+                                    GenericArgument::Lifetime(
+                                        ld.lifetime.clone()
+                                    )
+                                }
+                                _ => unimplemented!(),
+                            }
+                        }).collect::<Punctuated<_, _>>();
+                    seg.arguments = PathArguments::AngleBracketed(
+                        AngleBracketedGenericArguments {
+                            colon2_token: None,
+                            lt_token: generics.lt_token.unwrap(),
+                            args,
+                            gt_token: generics.gt_token.unwrap(),
+                        }
+                    );
+                }
+            } else {
+                compile_error(seg.arguments.span(),
+                    "Type arguments after Self are unexpected");
+            }
+        }
+        if let PathArguments::AngleBracketed(abga) = &mut seg.arguments
+        {
+            for arg in abga.args.iter_mut() {
+                match arg {
+                    GenericArgument::Type(ty) =>
+                        deselfify(ty, actual, generics),
+                    GenericArgument::Binding(b) =>
+                        deselfify(&mut b.ty, actual, generics),
+                    _ => /* Nothing to do */(),
+                }
+            }
+        }
+    }
+}
+
+/// Replace any references to `Self` in `literal_type` with `actual`.
+/// `generics` is the Generics field of the parent struct.  Useful for
+/// constructor methods.
+fn deselfify(literal_type: &mut Type, actual: &Ident, generics: &Generics) {
+    match literal_type {
+        Type::Slice(s) => {
+            deselfify(s.elem.as_mut(), actual, generics);
+        },
+        Type::Array(a) => {
+            deselfify(a.elem.as_mut(), actual, generics);
+        },
+        Type::Ptr(p) => {
+            deselfify(p.elem.as_mut(), actual, generics);
+        },
+        Type::Reference(r) => {
+            deselfify(r.elem.as_mut(), actual, generics);
+        },
+        Type::Tuple(tuple) => {
+            for elem in tuple.elems.iter_mut() {
+                deselfify(elem, actual, generics);
+            }
+        }
+        Type::Path(type_path) => {
+            if let Some(ref mut qself) = type_path.qself {
+                deselfify(qself.ty.as_mut(), actual, generics);
+            }
+            deselfify_path(&mut type_path.path, actual, generics);
+        },
+        Type::Paren(p) => {
+            deselfify(p.elem.as_mut(), actual, generics);
+        },
+        Type::Group(g) => {
+            deselfify(g.elem.as_mut(), actual, generics);
+        },
+        Type::Macro(_) | Type::Verbatim(_) => {
+            compile_error(literal_type.span(),
+                "mockall_derive does not support this type as a return argument");
+        },
+        Type::TraitObject(tto) => {
+            // Change types like `dyn Self` into `dyn MockXXX`.
+            for bound in tto.bounds.iter_mut() {
+                if let TypeParamBound::Trait(t) = bound {
+                    deselfify_path(&mut t.path, actual, generics);
+                }
+            }
+        },
+        Type::ImplTrait(_) => {
+            /* Should've already been flagged as a compile_error */
+        },
+        Type::BareFn(_) => {
+            /* Bare functions can't have Self arguments.  Nothing to do */
+        },
+        Type::Infer(_) | Type::Never(_) =>
+        {
+            /* Nothing to do */
+        },
+        _ => compile_error(literal_type.span(), "Unsupported type"),
+    }
+}
+
+/// Change any `Self` in a method's arguments' types with `actual`.
+/// `generics` is the Generics field of the parent struct.
+fn deselfify_args(
+    args: &mut Punctuated<FnArg, Token![,]>,
+    actual: &Ident,
+    generics: &Generics)
+{
+    for arg in args.iter_mut() {
+        if let FnArg::Typed(pt) = arg {
+            deselfify(pt.ty.as_mut(), actual, generics)
+        }
+    }
+}
+
+fn find_ident_from_path(path: &Path) -> (Ident, PathArguments) {
+    if path.segments.len() != 1 {
+        compile_error(path.span(),
+            "mockall_derive only supports structs defined in the current module");
+        return (Ident::new("", path.span()), PathArguments::None);
+    }
+    let last_seg = path.segments.last().unwrap();
+    (last_seg.ident.clone(), last_seg.arguments.clone())
+}
+
+fn find_lifetimes_in_tpb(bound: &TypeParamBound) -> HashSet<Lifetime> {
+    let mut ret = HashSet::default();
+    match bound {
+        TypeParamBound::Lifetime(lt) => {
+            ret.insert(lt.clone());
+        },
+        TypeParamBound::Trait(tb) => {
+            ret.extend(find_lifetimes_in_path(&tb.path));
+        },
+    };
+    ret
+}
+
+fn find_lifetimes_in_path(path: &Path) -> HashSet<Lifetime> {
+    let mut ret = HashSet::default();
+    for seg in path.segments.iter() {
+        if let PathArguments::AngleBracketed(abga) = &seg.arguments {
+            for arg in abga.args.iter() {
+                match arg {
+                    GenericArgument::Lifetime(lt) => {
+                        ret.insert(lt.clone());
+                    },
+                    GenericArgument::Type(ty) => {
+                        ret.extend(find_lifetimes(ty));
+                    },
+                    GenericArgument::Binding(b) => {
+                        ret.extend(find_lifetimes(&b.ty));
+                    },
+                    GenericArgument::Constraint(c) => {
+                        for bound in c.bounds.iter() {
+                            ret.extend(find_lifetimes_in_tpb(bound));
+                        }
+                    },
+                    GenericArgument::Const(_) => ()
+                }
+            }
+        }
+    }
+    ret
+}
+
+fn find_lifetimes(ty: &Type) -> HashSet<Lifetime> {
+    match ty {
+        Type::Array(ta) => find_lifetimes(ta.elem.as_ref()),
+        Type::Group(tg) => find_lifetimes(tg.elem.as_ref()),
+        Type::Infer(_ti) => HashSet::default(),
+        Type::Never(_tn) => HashSet::default(),
+        Type::Paren(tp) => find_lifetimes(tp.elem.as_ref()),
+        Type::Path(tp) => {
+            let mut ret = find_lifetimes_in_path(&tp.path);
+            if let Some(qs) = &tp.qself {
+                ret.extend(find_lifetimes(qs.ty.as_ref()));
+            }
+            ret
+        },
+        Type::Ptr(tp) => find_lifetimes(tp.elem.as_ref()),
+        Type::Reference(tr) => {
+            let mut ret = find_lifetimes(tr.elem.as_ref());
+            if let Some(lt) = &tr.lifetime {
+                ret.insert(lt.clone());
+            }
+            ret
+        },
+        Type::Slice(ts) => find_lifetimes(ts.elem.as_ref()),
+        Type::TraitObject(tto) => {
+            let mut ret = HashSet::default();
+            for bound in tto.bounds.iter() {
+                ret.extend(find_lifetimes_in_tpb(bound));
+            }
+            ret
+        }
+        Type::Tuple(tt) => {
+            let mut ret = HashSet::default();
+            for ty in tt.elems.iter() {
+                ret.extend(find_lifetimes(ty));
+            }
+            ret
+        },
+        Type::ImplTrait(tit) => {
+            let mut ret = HashSet::default();
+            for tpb in tit.bounds.iter() {
+                ret.extend(find_lifetimes_in_tpb(tpb));
+            }
+            ret
+        },
+        _ => {
+            compile_error(ty.span(), "unsupported type in this context");
+            HashSet::default()
+        }
+    }
+}
+
+
+struct AttrFormatter<'a>{
+    attrs: &'a [Attribute],
+    async_trait: bool,
+    doc: bool,
+}
+
+impl<'a> AttrFormatter<'a> {
+    fn new(attrs: &'a [Attribute]) -> AttrFormatter<'a> {
+        Self {
+            attrs,
+            async_trait: true,
+            doc: true
+        }
+    }
+
+    fn async_trait(&mut self, allowed: bool) -> &mut Self {
+        self.async_trait = allowed;
+        self
+    }
+
+    fn doc(&mut self, allowed: bool) -> &mut Self {
+        self.doc = allowed;
+        self
+    }
+
+    // XXX This logic requires that attributes are imported with their
+    // standard names.
+    #[allow(clippy::needless_bool)]
+    #[allow(clippy::if_same_then_else)]
+    fn format(&mut self) -> Vec<Attribute> {
+        self.attrs.iter()
+            .cloned()
+            .filter(|attr| {
+                let i = attr.path.get_ident();
+                if i.is_none() {
+                    false
+                } else if *i.as_ref().unwrap() == "derive" {
+                    // We can't usefully derive any traits.  Ignore them
+                    false
+                } else if *i.as_ref().unwrap() == "doc" {
+                    self.doc
+                } else if *i.as_ref().unwrap() == "async_trait" {
+                    self.async_trait
+                } else if *i.as_ref().unwrap() == "instrument" {
+                    // We can't usefully instrument the mock method, so just
+                    // ignore this attribute.
+                    // https://docs.rs/tracing/0.1.23/tracing/attr.instrument.html
+                    false
+                } else {
+                    true
+                }
+            }).collect()
+    }
+}
+
+/// Determine if this Pat is any kind of `self` binding
+fn pat_is_self(pat: &Pat) -> bool {
+    if let Pat::Ident(pi) = pat {
+        pi.ident == "self"
+    } else {
+        false
+    }
+}
+
+/// Add `levels` `super::` to the path.  Return the number of levels added.
+fn supersuperfy_path(path: &mut Path, levels: usize) -> usize {
+    if let Some(t) = path.segments.last_mut() {
+        match &mut t.arguments {
+            PathArguments::None => (),
+            PathArguments::AngleBracketed(ref mut abga) => {
+                for arg in abga.args.iter_mut() {
+                    match arg {
+                        GenericArgument::Type(ref mut ty) => {
+                            *ty = supersuperfy(ty, levels);
+                        },
+                        GenericArgument::Binding(ref mut binding) => {
+                            binding.ty = supersuperfy(&binding.ty, levels);
+                        },
+                        GenericArgument::Constraint(ref mut constraint) => {
+                            supersuperfy_bounds(&mut constraint.bounds, levels);
+                        },
+                        _ => (),
+                    }
+                }
+            },
+            PathArguments::Parenthesized(ref mut pga) => {
+                for input in pga.inputs.iter_mut() {
+                    *input = supersuperfy(input, levels);
+                }
+                if let ReturnType::Type(_, ref mut ty) = pga.output {
+                    *ty = Box::new(supersuperfy(ty, levels));
+                }
+            },
+        }
+    }
+    if let Some(t) = path.segments.first() {
+        if t.ident == "super" {
+            let mut ident = format_ident!("super");
+            ident.set_span(path.segments.span());
+            let ps = PathSegment {
+                ident,
+                arguments: PathArguments::None
+            };
+            for _ in 0..levels {
+                path.segments.insert(0, ps.clone());
+            }
+            levels
+        } else {
+            0
+        }
+    } else {
+        0
+    }
+}
+
+/// Replace any references to `super::X` in `original` with `super::super::X`.
+fn supersuperfy(original: &Type, levels: usize) -> Type {
+    let mut output = original.clone();
+    fn recurse(t: &mut Type, levels: usize) {
+        match t {
+            Type::Slice(s) => {
+                recurse(s.elem.as_mut(), levels);
+            },
+            Type::Array(a) => {
+                recurse(a.elem.as_mut(), levels);
+            },
+            Type::Ptr(p) => {
+                recurse(p.elem.as_mut(), levels);
+            },
+            Type::Reference(r) => {
+                recurse(r.elem.as_mut(), levels);
+            },
+            Type::BareFn(bfn) => {
+                if let ReturnType::Type(_, ref mut bt) = bfn.output {
+                    recurse(bt.as_mut(), levels);
+                }
+                for input in bfn.inputs.iter_mut() {
+                    recurse(&mut input.ty, levels);
+                }
+            },
+            Type::Tuple(tuple) => {
+                for elem in tuple.elems.iter_mut() {
+                    recurse(elem, levels);
+                }
+            }
+            Type::Path(type_path) => {
+                let added = supersuperfy_path(&mut type_path.path, levels);
+                if let Some(ref mut qself) = type_path.qself {
+                    recurse(qself.ty.as_mut(), levels);
+                    qself.position += added;
+                }
+            },
+            Type::Paren(p) => {
+                recurse(p.elem.as_mut(), levels);
+            },
+            Type::Group(g) => {
+                recurse(g.elem.as_mut(), levels);
+            },
+            Type::Macro(_) | Type::Verbatim(_) => {
+                compile_error(t.span(),
+                    "mockall_derive does not support this type in this position");
+            },
+            Type::TraitObject(tto) => {
+                for bound in tto.bounds.iter_mut() {
+                    if let TypeParamBound::Trait(tb) = bound {
+                        supersuperfy_path(&mut tb.path, levels);
+                    }
+                }
+            },
+            Type::ImplTrait(_) => {
+                /* Should've already been flagged as a compile error */
+            },
+            Type::Infer(_) | Type::Never(_) =>
+            {
+                /* Nothing to do */
+            },
+            _ => compile_error(t.span(), "Unsupported type"),
+        }
+    }
+    recurse(&mut output, levels);
+    output
+}
+
+fn supersuperfy_generics(generics: &mut Generics, levels: usize) {
+    for param in generics.params.iter_mut() {
+        if let GenericParam::Type(tp) = param {
+            supersuperfy_bounds(&mut tp.bounds, levels);
+            if let Some(ty) = tp.default.as_mut() {
+                *ty = supersuperfy(ty, levels);
+            }
+        }
+    }
+    if let Some(wc) = generics.where_clause.as_mut() {
+        for wp in wc.predicates.iter_mut() {
+            if let WherePredicate::Type(pt) = wp {
+                pt.bounded_ty = supersuperfy(&pt.bounded_ty, levels);
+                supersuperfy_bounds(&mut pt.bounds, levels);
+            }
+        }
+    }
+}
+
+fn supersuperfy_bounds(
+    bounds: &mut Punctuated<TypeParamBound, Token![+]>,
+    levels: usize)
+{
+    for bound in bounds.iter_mut() {
+        if let TypeParamBound::Trait(tb) = bound {
+            supersuperfy_path(&mut tb.path, levels);
+        }
+    }
+}
+
+/// Generate a suitable mockall::Key generic paramter from any Generics
+fn gen_keyid(g: &Generics) -> impl ToTokens {
+    match g.params.len() {
+        0 => quote!(<()>),
+        1 => {
+            let (_, tg, _) = g.split_for_impl();
+            quote!(#tg)
+        },
+        _ => {
+            // Rust doesn't support variadic Generics, so mockall::Key must
+            // always have exactly one generic type.  We need to add parentheses
+            // around whatever type generics the caller passes.
+            let tps = g.type_params()
+            .map(|tp| tp.ident.clone())
+            .collect::<Punctuated::<Ident, Token![,]>>();
+            quote!(<(#tps)>)
+        }
+    }
+}
+
+/// Generate a mock identifier from the regular one: eg "Foo" => "MockFoo"
+fn gen_mock_ident(ident: &Ident) -> Ident {
+    format_ident!("Mock{}", ident)
+}
+
+/// Generate an identifier for the mock struct's private module: eg "Foo" =>
+/// "__mock_Foo"
+fn gen_mod_ident(struct_: &Ident, trait_: Option<&Ident>) -> Ident {
+    if let Some(t) = trait_ {
+        format_ident!("__mock_{}_{}", struct_, t)
+    } else {
+        format_ident!("__mock_{}", struct_)
+    }
+}
+
+/// Combine two Generics structs, producing a new one that has the union of
+/// their parameters.
+fn merge_generics(x: &Generics, y: &Generics) -> Generics {
+    /// Compare only the identifiers of two GenericParams
+    fn cmp_gp_idents(x: &GenericParam, y: &GenericParam) -> bool {
+        use GenericParam::*;
+
+        match (x, y) {
+            (Type(xtp), Type(ytp)) => xtp.ident == ytp.ident,
+            (Lifetime(xld), Lifetime(yld)) => xld.lifetime == yld.lifetime,
+            (Const(xc), Const(yc)) => xc.ident == yc.ident,
+            _ => false
+        }
+    }
+
+    /// Compare only the identifiers of two WherePredicates
+    fn cmp_wp_idents(x: &WherePredicate, y: &WherePredicate) -> bool {
+        use WherePredicate::*;
+
+        match (x, y) {
+            (Type(xpt), Type(ypt)) => xpt.bounded_ty == ypt.bounded_ty,
+            (Lifetime(xpl), Lifetime(ypl)) => xpl.lifetime == ypl.lifetime,
+            (Eq(xeq), Eq(yeq)) => xeq.lhs_ty == yeq.lhs_ty,
+            _ => false
+        }
+    }
+
+    let mut out = if x.lt_token.is_none() && x.where_clause.is_none() {
+        y.clone()
+    } else if y.lt_token.is_none() && y.where_clause.is_none() {
+        x.clone()
+    } else {
+        let mut out = x.clone();
+        // First merge the params
+        'outer_param: for yparam in y.params.iter() {
+            // XXX: O(n^2) loop
+            for outparam in out.params.iter_mut() {
+                if cmp_gp_idents(outparam, yparam) {
+                    if let (GenericParam::Type(ref mut ot),
+                            GenericParam::Type(yt)) = (outparam, yparam)
+                    {
+                        ot.attrs.extend(yt.attrs.iter().cloned());
+                        ot.colon_token = ot.colon_token.or(yt.colon_token);
+                        ot.eq_token = ot.eq_token.or(yt.eq_token);
+                        if ot.default.is_none() {
+                            ot.default = yt.default.clone();
+                        }
+                        // XXX this might result in duplicate bounds
+                        if ot.bounds != yt.bounds {
+                            ot.bounds.extend(yt.bounds.iter().cloned());
+                        }
+                    }
+                    continue 'outer_param;
+                }
+            }
+            out.params.push(yparam.clone());
+        }
+        out
+    };
+    // Then merge the where clauses
+    match (&mut out.where_clause, &y.where_clause) {
+        (_, None) => (),
+        (None, Some(wc)) => out.where_clause = Some(wc.clone()),
+        (Some(out_wc), Some(y_wc)) => {
+            'outer_wc: for ypred in y_wc.predicates.iter() {
+                // XXX: O(n^2) loop
+                for outpred in out_wc.predicates.iter_mut() {
+                    if cmp_wp_idents(outpred, ypred) {
+                        if let (WherePredicate::Type(ref mut ot),
+                                WherePredicate::Type(yt)) = (outpred, ypred)
+                        {
+                            match (&mut ot.lifetimes, &yt.lifetimes) {
+                                (_, None) => (),
+                                (None, Some(bl)) =>
+                                    ot.lifetimes = Some(bl.clone()),
+                                (Some(obl), Some(ybl)) =>
+                                    // XXX: might result in duplicates
+                                    obl.lifetimes.extend(
+                                        ybl.lifetimes.iter().cloned()),
+                            };
+                            // XXX: might result in duplicate bounds
+                            if ot.bounds != yt.bounds {
+                                ot.bounds.extend(yt.bounds.iter().cloned())
+                            }
+                        }
+                        continue 'outer_wc;
+                    }
+                }
+                out_wc.predicates.push(ypred.clone());
+            }
+        }
+    }
+    out
+}
+
+/// Transform a Vec of lifetimes into a Generics
+fn lifetimes_to_generics(lv: &Punctuated<LifetimeDef, Token![,]>)-> Generics {
+    if lv.is_empty() {
+            Generics::default()
+    } else {
+        let params = lv.iter()
+            .map(|lt| GenericParam::Lifetime(lt.clone()))
+            .collect();
+        Generics {
+            lt_token: Some(Token![<](lv[0].span())),
+            gt_token: Some(Token![>](lv[0].span())),
+            params,
+            where_clause: None
+        }
+    }
+}
+
+/// Split a generics list into three: one for type generics and where predicates
+/// that relate to the signature, one for lifetimes that relate to the arguments
+/// only, and one for lifetimes that relate to the return type only.
+fn split_lifetimes(
+    generics: Generics,
+    args: &[FnArg],
+    rt: &ReturnType)
+    -> (Generics,
+        Punctuated<LifetimeDef, token::Comma>,
+        Punctuated<LifetimeDef, token::Comma>)
+{
+    if generics.lt_token.is_none() {
+        return (generics, Default::default(), Default::default());
+    }
+
+    // Check which types and lifetimes are referenced by the arguments
+    let mut alts = HashSet::<Lifetime>::default();
+    let mut rlts = HashSet::<Lifetime>::default();
+    for arg in args {
+        match arg {
+            FnArg::Receiver(r) => {
+                if let Some((_, Some(lt))) = &r.reference {
+                    alts.insert(lt.clone());
+                }
+            },
+            FnArg::Typed(pt) => {
+                alts.extend(find_lifetimes(pt.ty.as_ref()));
+            },
+        };
+    };
+
+    if let ReturnType::Type(_, ty) = rt {
+        rlts.extend(find_lifetimes(ty));
+    }
+
+    let mut tv = Punctuated::new();
+    let mut alv = Punctuated::new();
+    let mut rlv = Punctuated::new();
+    for p in generics.params.into_iter() {
+        match p {
+            GenericParam::Lifetime(ltd) if rlts.contains(&ltd.lifetime) =>
+                rlv.push(ltd),
+            GenericParam::Lifetime(ltd) if alts.contains(&ltd.lifetime) =>
+                alv.push(ltd),
+            GenericParam::Lifetime(_) => {
+                // Probably a lifetime parameter from the impl block that isn't
+                // used by this particular method
+            },
+            GenericParam::Type(_) => tv.push(p),
+            _ => (),
+        }
+    }
+
+    let tg = if tv.is_empty() {
+        Generics::default()
+    } else {
+        Generics {
+            lt_token: generics.lt_token,
+            gt_token: generics.gt_token,
+            params: tv,
+            where_clause: generics.where_clause
+        }
+    };
+
+    (tg, alv, rlv)
+}
+
+/// Return the visibility that should be used for expectation!, given the
+/// original method's visibility.
+///
+/// # Arguments
+/// - `vis`:    Original visibility of the item
+/// - `levels`: How many modules will the mock item be nested in?
+fn expectation_visibility(vis: &Visibility, levels: usize)
+    -> Visibility
+{
+    if levels == 0 {
+        return vis.clone();
+    }
+
+    let in_token = Token![in](vis.span());
+    let super_token = Token![super](vis.span());
+    match vis {
+        Visibility::Inherited => {
+            // Private items need pub(in super::[...]) for each level
+            let mut path = Path::from(super_token);
+            for _ in 1..levels {
+                path.segments.push(super_token.into());
+            }
+            Visibility::Restricted(VisRestricted{
+                pub_token: Token![pub](vis.span()),
+                paren_token: token::Paren::default(),
+                in_token: Some(in_token),
+                path: Box::new(path)
+            })
+        },
+        Visibility::Restricted(vr) => {
+            // crate => don't change
+            // in crate::* => don't change
+            // super => in super::super::super
+            // self => in super::super
+            // in anything_else => super::super::anything_else
+            if vr.path.segments.first().unwrap().ident == "crate" {
+                vr.clone().into()
+            } else {
+                let mut out = vr.clone();
+                out.in_token = Some(in_token);
+                for _ in 0..levels {
+                    out.path.segments.insert(0, super_token.into());
+                }
+                out.into()
+            }
+        },
+        _ => vis.clone()
+    }
+}
+
+fn staticize(generics: &Generics) -> Generics {
+    let mut ret = generics.clone();
+    for lt in ret.lifetimes_mut() {
+        lt.lifetime = Lifetime::new("'static", Span::call_site());
+    };
+    ret
+}
+
+fn mock_it<M: Into<MockableItem>>(inputs: M) -> TokenStream
+{
+    let mockable: MockableItem = inputs.into();
+    let mock = MockItem::from(mockable);
+    let ts = mock.into_token_stream();
+    if env::var("MOCKALL_DEBUG").is_ok() {
+        println!("{}", ts);
+    }
+    ts
+}
+
+fn do_mock_once(input: TokenStream) -> TokenStream
+{
+    let item: MockableStruct = match syn::parse2(input) {
+        Ok(mock) => mock,
+        Err(err) => {
+            return err.to_compile_error();
+        }
+    };
+    mock_it(item)
+}
+
+fn do_mock(input: TokenStream) -> TokenStream
+{
+    cfg_if! {
+        if #[cfg(reprocheck)] {
+            let ts_a = do_mock_once(input.clone());
+            let ts_b = do_mock_once(input.clone());
+            assert_eq!(ts_a.to_string(), ts_b.to_string());
+        }
+    }
+    do_mock_once(input)
+}
+
+#[proc_macro]
+pub fn mock(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+    do_mock(input.into()).into()
+}
+
+#[proc_macro_attribute]
+pub fn automock(attrs: proc_macro::TokenStream, input: proc_macro::TokenStream)
+    -> proc_macro::TokenStream
+{
+    let attrs: proc_macro2::TokenStream = attrs.into();
+    let input: proc_macro2::TokenStream = input.into();
+    do_automock(attrs, input).into()
+}
+
+fn do_automock_once(attrs: TokenStream, input: TokenStream) -> TokenStream {
+    let mut output = input.clone();
+    let attrs: Attrs = match parse2(attrs) {
+        Ok(a) => a,
+        Err(err) => {
+            return err.to_compile_error();
+        }
+    };
+    let item: Item = match parse2(input) {
+        Ok(item) => item,
+        Err(err) => {
+            return err.to_compile_error();
+        }
+    };
+    output.extend(mock_it((attrs, item)));
+    output
+}
+
+fn do_automock(attrs: TokenStream, input: TokenStream) -> TokenStream {
+    cfg_if! {
+        if #[cfg(reprocheck)] {
+            let ts_a = do_automock_once(attrs.clone(), input.clone());
+            let ts_b = do_automock_once(attrs.clone(), input.clone());
+            assert_eq!(ts_a.to_string(), ts_b.to_string());
+        }
+    }
+    do_automock_once(attrs, input)
+}
+
+#[cfg(test)]
+mod t {
+    use super::*;
+
+fn assert_contains(output: &str, tokens: TokenStream) {
+    let s = tokens.to_string();
+    assert!(output.contains(&s), "output does not contain {:?}", &s);
+}
+
+fn assert_not_contains(output: &str, tokens: TokenStream) {
+    let s = tokens.to_string();
+    assert!(!output.contains(&s), "output does not contain {:?}", &s);
+}
+
+/// Various tests for overall code generation that are hard or impossible to
+/// write as integration tests
+mod mock {
+    use std::str::FromStr;
+    use super::super::*;
+    use super::*;
+
+    #[test]
+    fn inherent_method_visibility() {
+        let code = r#"
+            Foo {
+                fn foo(&self);
+                pub fn bar(&self);
+                pub(crate) fn baz(&self);
+                pub(super) fn bean(&self);
+                pub(in crate::outer) fn boom(&self);
+            }
+        "#;
+        let ts = proc_macro2::TokenStream::from_str(code).unwrap();
+        let output = do_mock(ts).to_string();
+        assert_not_contains(&output, quote!(pub fn foo));
+        assert!(!output.contains(") fn foo"));
+        assert_contains(&output, quote!(pub fn bar));
+        assert_contains(&output, quote!(pub(crate) fn baz));
+        assert_contains(&output, quote!(pub(super) fn bean));
+        assert_contains(&output, quote!(pub(in crate::outer) fn boom));
+
+        assert_not_contains(&output, quote!(pub fn expect_foo));
+        assert!(!output.contains("pub fn expect_foo"));
+        assert!(!output.contains(") fn expect_foo"));
+        assert_contains(&output, quote!(pub fn expect_bar));
+        assert_contains(&output, quote!(pub(crate) fn expect_baz));
+        assert_contains(&output, quote!(pub(super) fn expect_bean));
+        assert_contains(&output, quote!(pub(in crate::outer) fn expect_boom));
+    }
+
+    #[test]
+    fn specific_impl() {
+        let code = r#"
+            pub Foo<T: 'static> {}
+            impl Bar for Foo<u32> {
+                fn bar(&self);
+            }
+            impl Bar for Foo<i32> {
+                fn bar(&self);
+            }
+        "#;
+        let ts = proc_macro2::TokenStream::from_str(code).unwrap();
+        let output = do_mock(ts).to_string();
+        assert_contains(&output, quote!(impl Bar for MockFoo<u32>));
+        assert_contains(&output, quote!(impl Bar for MockFoo<i32>));
+        // Ensure we don't duplicate the checkpoint function
+        assert_not_contains(&output, quote!(
+            self.Bar_expectations.checkpoint();
+            self.Bar_expectations.checkpoint();
+        ));
+        // The expect methods should return specific types, not generic ones
+        assert_contains(&output, quote!(
+            pub fn expect_bar(&mut self) -> &mut __mock_MockFoo_Bar::__bar::Expectation<u32>
+        ));
+        assert_contains(&output, quote!(
+            pub fn expect_bar(&mut self) -> &mut __mock_MockFoo_Bar::__bar::Expectation<i32>
+        ));
+    }
+}
+
+/// Various tests for overall code generation that are hard or impossible to
+/// write as integration tests
+mod automock {
+    use std::str::FromStr;
+    use super::super::*;
+    use super::*;
+
+    #[test]
+    fn doc_comments() {
+        let code = r#"
+            mod foo {
+                /// Function docs
+                pub fn bar() { unimplemented!() }
+            }
+        "#;
+        let ts = proc_macro2::TokenStream::from_str(code).unwrap();
+        let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
+        let output = do_automock(attrs_ts, ts).to_string();
+        assert_contains(&output, quote!(#[doc=" Function docs"] pub fn bar));
+    }
+
+    #[test]
+    fn method_visibility() {
+        let code = r#"
+        impl Foo {
+            fn foo(&self) {}
+            pub fn bar(&self) {}
+            pub(super) fn baz(&self) {}
+            pub(crate) fn bang(&self) {}
+            pub(in super::x) fn bean(&self) {}
+        }"#;
+        let ts = proc_macro2::TokenStream::from_str(code).unwrap();
+        let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
+        let output = do_automock(attrs_ts, ts).to_string();
+        assert_not_contains(&output, quote!(pub fn foo));
+        assert!(!output.contains(") fn foo"));
+        assert_not_contains(&output, quote!(pub fn expect_foo));
+        assert!(!output.contains(") fn expect_foo"));
+        assert_contains(&output, quote!(pub fn bar));
+        assert_contains(&output, quote!(pub fn expect_bar));
+        assert_contains(&output, quote!(pub(super) fn baz));
+        assert_contains(&output, quote!(pub(super) fn expect_baz));
+        assert_contains(&output, quote!(pub ( crate ) fn bang));
+        assert_contains(&output, quote!(pub ( crate ) fn expect_bang));
+        assert_contains(&output, quote!(pub ( in super :: x ) fn bean));
+        assert_contains(&output, quote!(pub ( in super :: x ) fn expect_bean));
+    }
+
+    #[test]
+    #[should_panic(expected = "can only mock inline modules")]
+    fn external_module() {
+        let code = r#"mod foo;"#;
+        let ts = proc_macro2::TokenStream::from_str(code).unwrap();
+        let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
+        do_automock(attrs_ts, ts).to_string();
+    }
+
+    #[test]
+    fn trait_visibility() {
+        let code = r#"
+        pub(super) trait Foo {}
+        "#;
+        let attrs_ts = proc_macro2::TokenStream::from_str("").unwrap();
+        let ts = proc_macro2::TokenStream::from_str(code).unwrap();
+        let output = do_automock(attrs_ts, ts).to_string();
+        assert_contains(&output, quote!(pub ( super ) struct MockFoo));
+    }
+}
+
+mod deimplify {
+    use super::*;
+
+    fn check_deimplify(orig_ts: TokenStream, expected_ts: TokenStream) {
+        let mut orig: ReturnType = parse2(orig_ts).unwrap();
+        let expected: ReturnType = parse2(expected_ts).unwrap();
+        deimplify(&mut orig);
+        assert_eq!(quote!(#orig).to_string(), quote!(#expected).to_string());
+    }
+
+    // Future is a special case
+    #[test]
+    fn impl_future() {
+        check_deimplify(
+            quote!(-> impl Future<Output=i32>),
+            quote!(-> ::std::pin::Pin<Box<dyn Future<Output=i32>>>)
+        );
+    }
+
+    // Future is a special case, wherever it appears
+    #[test]
+    fn impl_future_reverse() {
+        check_deimplify(
+            quote!(-> impl Send + Future<Output=i32>),
+            quote!(-> ::std::pin::Pin<Box<dyn Send + Future<Output=i32>>>)
+        );
+    }
+
+    // Stream is a special case
+    #[test]
+    fn impl_stream() {
+        check_deimplify(
+            quote!(-> impl Stream<Item=i32>),
+            quote!(-> ::std::pin::Pin<Box<dyn Stream<Item=i32>>>)
+        );
+    }
+
+    #[test]
+    fn impl_trait() {
+        check_deimplify(
+            quote!(-> impl Foo),
+            quote!(-> Box<dyn Foo>)
+        );
+    }
+
+    // With extra bounds
+    #[test]
+    fn impl_trait2() {
+        check_deimplify(
+            quote!(-> impl Foo + Send),
+            quote!(-> Box<dyn Foo + Send>)
+        );
+    }
+}
+
+mod deselfify {
+    use super::*;
+
+    fn check_deselfify(
+        orig_ts: TokenStream,
+        actual_ts: TokenStream,
+        generics_ts: TokenStream,
+        expected_ts: TokenStream)
+    {
+        let mut ty: Type = parse2(orig_ts).unwrap();
+        let actual: Ident = parse2(actual_ts).unwrap();
+        let generics: Generics = parse2(generics_ts).unwrap();
+        let expected: Type = parse2(expected_ts).unwrap();
+        deselfify(&mut ty, &actual, &generics);
+        assert_eq!(quote!(#ty).to_string(),
+                   quote!(#expected).to_string());
+    }
+
+    #[test]
+    fn future() {
+        check_deselfify(
+            quote!(Box<dyn Future<Output=Self>>),
+            quote!(Foo),
+            quote!(),
+            quote!(Box<dyn Future<Output=Foo>>)
+        );
+    }
+
+    #[test]
+    fn qself() {
+        check_deselfify(
+            quote!(<Self as Self>::Self),
+            quote!(Foo),
+            quote!(),
+            quote!(<Foo as Foo>::Foo)
+        );
+    }
+
+    #[test]
+    fn trait_object() {
+        check_deselfify(
+            quote!(Box<dyn Self>),
+            quote!(Foo),
+            quote!(),
+            quote!(Box<dyn Foo>)
+        );
+    }
+
+    // A trait object with multiple bounds
+    #[test]
+    fn trait_object2() {
+        check_deselfify(
+            quote!(Box<dyn Self + Send>),
+            quote!(Foo),
+            quote!(),
+            quote!(Box<dyn Foo + Send>)
+        );
+    }
+}
+
+mod dewhereselfify {
+    use super::*;
+
+    #[test]
+    fn lifetime() {
+        let mut meth: ImplItemMethod = parse2(quote!(
+                fn foo<'a>(&self) where 'a: 'static, Self: Sized;
+        )).unwrap();
+        let expected: ImplItemMethod = parse2(quote!(
+                fn foo<'a>(&self) where 'a: 'static;
+        )).unwrap();
+        dewhereselfify(&mut meth.sig.generics);
+        assert_eq!(meth, expected);
+    }
+
+    #[test]
+    fn normal_method() {
+        let mut meth: ImplItemMethod = parse2(quote!(
+                fn foo(&self) where Self: Sized;
+        )).unwrap();
+        let expected: ImplItemMethod = parse2(quote!(
+                fn foo(&self);
+        )).unwrap();
+        dewhereselfify(&mut meth.sig.generics);
+        assert_eq!(meth, expected);
+    }
+
+    #[test]
+    fn with_real_generics() {
+        let mut meth: ImplItemMethod = parse2(quote!(
+                fn foo<T>(&self, t: T) where Self: Sized, T: Copy;
+        )).unwrap();
+        let expected: ImplItemMethod = parse2(quote!(
+                fn foo<T>(&self, t: T) where T: Copy;
+        )).unwrap();
+        dewhereselfify(&mut meth.sig.generics);
+        assert_eq!(meth, expected);
+    }
+}
+
+mod gen_keyid {
+    use super::*;
+
+    fn check_gen_keyid(orig: TokenStream, expected: TokenStream) {
+        let g: Generics = parse2(orig).unwrap();
+        let keyid = gen_keyid(&g);
+        assert_eq!(quote!(#keyid).to_string(), quote!(#expected).to_string());
+    }
+
+    #[test]
+    fn empty() {
+        check_gen_keyid(quote!(), quote!(<()>));
+    }
+
+    #[test]
+    fn onetype() {
+        check_gen_keyid(quote!(<T>), quote!(<T>));
+    }
+
+    #[test]
+    fn twotypes() {
+        check_gen_keyid(quote!(<T, V>), quote!(<(T, V)>));
+    }
+}
+
+mod merge_generics {
+    use super::*;
+
+    #[test]
+    fn both() {
+        let mut g1: Generics = parse2(quote!(<T: 'static, V: Copy> )).unwrap();
+        let wc1: WhereClause = parse2(quote!(where T: Default)).unwrap();
+        g1.where_clause = Some(wc1);
+
+        let mut g2: Generics = parse2(quote!(<Q: Send, V: Clone>)).unwrap();
+        let wc2: WhereClause = parse2(quote!(where T: Sync, Q: Debug)).unwrap();
+        g2.where_clause = Some(wc2);
+
+        let gm = super::merge_generics(&g1, &g2);
+        let gm_wc = &gm.where_clause;
+
+        let ge: Generics = parse2(quote!(
+                <T: 'static, V: Copy + Clone, Q: Send>
+        )).unwrap();
+        let wce: WhereClause = parse2(quote!(
+            where T: Default + Sync, Q: Debug
+        )).unwrap();
+
+        assert_eq!(quote!(#ge #wce).to_string(),
+                   quote!(#gm #gm_wc).to_string());
+    }
+
+    #[test]
+    fn eq() {
+        let mut g1: Generics = parse2(quote!(<T: 'static, V: Copy> )).unwrap();
+        let wc1: WhereClause = parse2(quote!(where T: Default)).unwrap();
+        g1.where_clause = Some(wc1.clone());
+
+        let gm = super::merge_generics(&g1, &g1);
+        let gm_wc = &gm.where_clause;
+
+        assert_eq!(quote!(#g1 #wc1).to_string(),
+                   quote!(#gm #gm_wc).to_string());
+    }
+
+    #[test]
+    fn lhs_only() {
+        let mut g1: Generics = parse2(quote!(<T: 'static, V: Copy> )).unwrap();
+        let wc1: WhereClause = parse2(quote!(where T: Default)).unwrap();
+        g1.where_clause = Some(wc1.clone());
+
+        let g2 = Generics::default();
+
+        let gm = super::merge_generics(&g1, &g2);
+        let gm_wc = &gm.where_clause;
+
+        assert_eq!(quote!(#g1 #wc1).to_string(),
+                   quote!(#gm #gm_wc).to_string());
+    }
+
+    #[test]
+    fn lhs_wc_only() {
+        let mut g1 = Generics::default();
+        let wc1: WhereClause = parse2(quote!(where T: Default)).unwrap();
+        g1.where_clause = Some(wc1.clone());
+
+        let g2 = Generics::default();
+
+        let gm = super::merge_generics(&g1, &g2);
+        let gm_wc = &gm.where_clause;
+
+        assert_eq!(quote!(#g1 #wc1).to_string(),
+                   quote!(#gm #gm_wc).to_string());
+    }
+
+    #[test]
+    fn rhs_only() {
+        let g1 = Generics::default();
+        let mut g2: Generics = parse2(quote!(<Q: Send, V: Clone>)).unwrap();
+        let wc2: WhereClause = parse2(quote!(where T: Sync, Q: Debug)).unwrap();
+        g2.where_clause = Some(wc2.clone());
+
+        let gm = super::merge_generics(&g1, &g2);
+        let gm_wc = &gm.where_clause;
+
+        assert_eq!(quote!(#g2 #wc2).to_string(),
+                   quote!(#gm #gm_wc).to_string());
+    }
+}
+
+mod supersuperfy {
+    use super::*;
+
+    fn check_supersuperfy(orig: TokenStream, expected: TokenStream) {
+        let orig_ty: Type = parse2(orig).unwrap();
+        let expected_ty: Type = parse2(expected).unwrap();
+        let output = supersuperfy(&orig_ty, 1);
+        assert_eq!(quote!(#output).to_string(),
+                   quote!(#expected_ty).to_string());
+    }
+
+    #[test]
+    fn array() {
+        check_supersuperfy(
+            quote!([super::X; n]),
+            quote!([super::super::X; n])
+        );
+    }
+
+    #[test]
+    fn barefn() {
+        check_supersuperfy(
+            quote!(fn(super::A) -> super::B),
+            quote!(fn(super::super::A) -> super::super::B)
+        );
+    }
+
+    #[test]
+    fn group() {
+        let orig = TypeGroup {
+            group_token: token::Group::default(),
+            elem: Box::new(parse2(quote!(super::T)).unwrap())
+        };
+        let expected = TypeGroup {
+            group_token: token::Group::default(),
+            elem: Box::new(parse2(quote!(super::super::T)).unwrap())
+        };
+        let output = supersuperfy(&Type::Group(orig), 1);
+        assert_eq!(quote!(#output).to_string(),
+                   quote!(#expected).to_string());
+    }
+
+    // Just check that it doesn't panic
+    #[test]
+    fn infer() {
+        check_supersuperfy( quote!(_), quote!(_));
+    }
+
+    // Just check that it doesn't panic
+    #[test]
+    fn never() {
+        check_supersuperfy( quote!(!), quote!(!));
+    }
+
+    #[test]
+    fn paren() {
+        check_supersuperfy(
+            quote!((super::X)),
+            quote!((super::super::X))
+        );
+    }
+
+    #[test]
+    fn path() {
+        check_supersuperfy(
+            quote!(::super::SuperT<u32>),
+            quote!(::super::super::SuperT<u32>)
+        );
+    }
+
+    #[test]
+    fn path_with_qself() {
+        check_supersuperfy(
+            quote!(<super::X as super::Y>::Foo<u32>),
+            quote!(<super::super::X as super::super::Y>::Foo<u32>),
+        );
+    }
+
+    #[test]
+    fn angle_bracketed_generic_arguments() {
+        check_supersuperfy(
+            quote!(mod_::T<super::X>),
+            quote!(mod_::T<super::super::X>)
+        );
+    }
+
+    #[test]
+    fn ptr() {
+        check_supersuperfy(
+            quote!(*const super::X),
+            quote!(*const super::super::X)
+        );
+    }
+
+    #[test]
+    fn reference() {
+        check_supersuperfy(
+            quote!(&'a mut super::X),
+            quote!(&'a mut super::super::X)
+        );
+    }
+
+    #[test]
+    fn slice() {
+        check_supersuperfy(
+            quote!([super::X]),
+            quote!([super::super::X])
+        );
+    }
+
+    #[test]
+    fn trait_object() {
+        check_supersuperfy(
+            quote!(dyn super::X + super::Y),
+            quote!(dyn super::super::X + super::super::Y)
+        );
+    }
+
+    #[test]
+    fn tuple() {
+        check_supersuperfy(
+            quote!((super::A, super::B)),
+            quote!((super::super::A, super::super::B))
+        );
+    }
+}
+
+mod supersuperfy_generics {
+    use super::*;
+
+    fn check_supersuperfy_generics(
+        orig: TokenStream,
+        orig_wc: TokenStream,
+        expected: TokenStream,
+        expected_wc: TokenStream)
+    {
+        let mut orig_g: Generics = parse2(orig).unwrap();
+        orig_g.where_clause = parse2(orig_wc).unwrap();
+        let mut expected_g: Generics = parse2(expected).unwrap();
+        expected_g.where_clause = parse2(expected_wc).unwrap();
+        let mut output: Generics = orig_g;
+        supersuperfy_generics(&mut output, 1);
+        let (o_ig, o_tg, o_wc) = output.split_for_impl();
+        let (e_ig, e_tg, e_wc) = expected_g.split_for_impl();
+        assert_eq!(quote!(#o_ig).to_string(), quote!(#e_ig).to_string());
+        assert_eq!(quote!(#o_tg).to_string(), quote!(#e_tg).to_string());
+        assert_eq!(quote!(#o_wc).to_string(), quote!(#e_wc).to_string());
+    }
+
+    #[test]
+    fn default() {
+        check_supersuperfy_generics(
+            quote!(<T: X = super::Y>), quote!(),
+            quote!(<T: X = super::super::Y>), quote!(),
+        );
+    }
+
+    #[test]
+    fn empty() {
+        check_supersuperfy_generics(quote!(), quote!(), quote!(), quote!());
+    }
+
+    #[test]
+    fn everything() {
+        check_supersuperfy_generics(
+            quote!(<T: super::A = super::B>),
+            quote!(where super::C: super::D),
+            quote!(<T: super::super::A = super::super::B>),
+            quote!(where super::super::C: super::super::D),
+        );
+    }
+
+    #[test]
+    fn bound() {
+        check_supersuperfy_generics(
+            quote!(<T: super::A>), quote!(),
+            quote!(<T: super::super::A>), quote!(),
+        );
+    }
+
+    #[test]
+    fn closure() {
+        check_supersuperfy_generics(
+            quote!(<F: Fn(u32) -> super::SuperT>), quote!(),
+            quote!(<F: Fn(u32) -> super::super::SuperT>), quote!(),
+        );
+    }
+
+    #[test]
+    fn wc_bounded_ty() {
+        check_supersuperfy_generics(
+            quote!(), quote!(where super::T: X),
+            quote!(), quote!(where super::super::T: X),
+        );
+    }
+
+    #[test]
+    fn wc_bounds() {
+        check_supersuperfy_generics(
+            quote!(), quote!(where T: super::X),
+            quote!(), quote!(where T: super::super::X),
+        );
+    }
+}
+}
diff --git a/src/mock_function.rs b/src/mock_function.rs
new file mode 100644
index 0000000..86a8690
--- /dev/null
+++ b/src/mock_function.rs
@@ -0,0 +1,2436 @@
+// vim: tw=80
+use super::*;
+
+use quote::ToTokens;
+
+/// Convert a trait object reference into a reference to a Boxed trait
+///
+/// # Returns
+///
+/// Returns `true` if it was necessary to box the type.
+fn dedynify(ty: &mut Type) -> bool {
+    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 false;
+                }
+            }
+
+            *tr.elem = parse2(quote!(Box<#tto>)).unwrap();
+            return true;
+        }
+    }
+    false
+}
+
+/// 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, boxed) = match self.sig.output {
+            ReturnType::Default => (
+                Type::Tuple(TypeTuple {
+                    paren_token: token::Paren::default(),
+                    elems: Punctuated::new(),
+                }),
+                false,
+            ),
+            ReturnType::Type(_, ref ty) => {
+                let mut output_ty = supersuperfy(ty, self.levels);
+                destrify(&mut output_ty);
+                let boxed = dedynify(&mut output_ty);
+                (output_ty, boxed)
+            }
+        };
+        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<_>>())
+            .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,
+            boxed,
+            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,
+    /// True if the `owned_type` is boxed by `Box<>`.
+    boxed: bool,
+    /// 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 desc = self.desc();
+        let no_match_msg = quote!(std::format!(
+            "{}: No matching expectation found", #desc));
+        let sig = &self.sig;
+        let (vis, dead_code) = if self.trait_.is_some() {
+            (&Visibility::Inherited, quote!())
+        } else {
+            let dead_code = if let Visibility::Inherited = self.call_vis {
+                // This private method may be a helper only used by the struct's
+                // other methods, which we are mocking.  If so, the mock method
+                // will be dead code.  But we can't simply eliminate it, because
+                // it might also be used by other code in the same module.
+                quote!(#[allow(dead_code)])
+            } else {
+                quote!()
+            };
+            (&self.call_vis, dead_code)
+        };
+        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())
+        };
+        let mut deref = quote!();
+        if self.boxed {
+            if self.return_ref {
+                deref = quote!(&**);
+            } else if self.return_refmut {
+                deref = quote!(&mut **);
+            }
+        }
+        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)*
+                #dead_code
+                #vis #sig {
+                    let no_match_msg = #no_match_msg;
+                    #deref {
+                        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)*
+                #dead_code
+                #vis #sig {
+                    let no_match_msg = #no_match_msg;
+                    #deref 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 a code fragment that will print a description of the invocation
+    fn desc(&self) -> impl ToTokens {
+        let argnames = &self.argnames;
+        let name = if let Some(s) = &self.struct_ {
+            format!("{}::{}", s, self.sig.ident)
+        } else {
+            format!("{}::{}", self.mod_ident, self.sig.ident)
+        };
+        let fields = vec!["{:?}"; argnames.len()].join(", ");
+        let fstr = format!("{}({})", name, fields);
+        quote!(std::format!(#fstr, #(::mockall::MaybeDebugger(&#argnames)),*))
+    }
+
+    /// Generate code for the expect_ method
+    ///
+    /// # Arguments
+    ///
+    /// * `modname`:    Name of the parent struct's private module
+    /// * `self_args`:  If supplied, these are the
+    ///                 AngleBracketedGenericArguments of the self type of the
+    ///                 trait impl.  e.g. The `T` in `impl Foo for Bar<T>`.
+    // Supplying modname is an unfortunately hack.  Ideally MockFunction
+    // wouldn't need to know that.
+    pub fn expect(&self, modname: &Ident, self_args: Option<&PathArguments>) -> 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(self_args);
+        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
+    fn expectation_obj(&self, self_args: Option<&PathArguments>) -> impl ToTokens {
+        let inner_mod_ident = self.inner_mod_ident();
+        if let Some(PathArguments::AngleBracketed(abga)) = self_args {
+            // staticize any lifetimes that might be present in the Expectation
+            // object but not in the self args.  These come from the method's
+            // return type.
+            let mut abga2 = abga.clone();
+            for _ in self.egenerics.lifetimes() {
+                let lt = Lifetime::new("'static", Span::call_site());
+                let la = GenericArgument::Lifetime(lt);
+                abga2.args.insert(0, la);
+            }
+            assert!(
+                !self.is_method_generic(),
+                "specific impls with generic methods are TODO"
+            );
+            quote!(#inner_mod_ident::Expectation #abga2)
+        } 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!(#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)?
+    pub 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::{
+                    boxed::Box,
+                    mem,
+                    ops::{DerefMut, Range},
+                    sync::Mutex,
+                    vec::Vec,
+                };
+                #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 = with_generics_idents
+            .iter()
+            .zip(self.f.predty.iter())
+            .map(|(id, mt)| quote!(#id: #hrtb ::mockall::Predicate<#mt> + Send + 'static, ))
+            .collect::<TokenStream>();
+        let with_args = self
+            .f
+            .argnames
+            .iter()
+            .zip(with_generics_idents.iter())
+            .map(|(argname, id)| quote!(#argname: #id, ))
+            .collect::<TokenStream>();
+        let boxed_withargs = argnames
+            .iter()
+            .map(|aa| quote!(Box::new(#aa), ))
+            .collect::<TokenStream>();
+        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, desc: &str) {
+                    self.times.call()
+                        .unwrap_or_else(|m| {
+                            let desc = std::format!(
+                                "{}", self.matcher.lock().unwrap());
+                            panic!("{}: Expectation({}) {}", #funcname, desc,
+                                m);
+                        });
+                    self.verify_sequence(desc);
+                    if ::mockall::ExpectedCalls::TooFew != 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, desc: &str) {
+                    if let Some(__mockall_handle) = &self.seq_handle {
+                        __mockall_handle.verify(desc)
+                    }
+                }
+            }
+
+            impl #ig Drop for Common #tg #wc {
+                fn drop(&mut self) {
+                    if !::std::thread::panicking() {
+                        let desc = std::format!(
+                            "{}", self.matcher.lock().unwrap());
+                        match self.times.is_satisfied() {
+                            ::mockall::ExpectedCalls::TooFew => {
+                                panic!("{}: Expectation({}) called {} time(s) which is fewer than expected {}",
+                                    #funcname,
+                                    desc,
+                                    self.times.count(),
+                                    self.times.minimum());
+                            },
+                            ::mockall::ExpectedCalls::TooMany => {
+                                panic!("{}: Expectation({}) called {} time(s) which is more than expected {}",
+                                    #funcname,
+                                    desc,
+                                    self.times.count(),
+                                    self.times.maximum());
+                            },
+                            _ => ()
+                        }
+                    }
+                }
+            }
+        ).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 = with_generics_idents
+            .iter()
+            .zip(self.f.predty.iter())
+            .map(|(id, mt)| quote!(#id: #hrtb ::mockall::Predicate<#mt> + Send + 'static, ))
+            .collect::<TokenStream>();
+        let with_args = self
+            .f
+            .argnames
+            .iter()
+            .zip(with_generics_idents.iter())
+            .map(|(argname, id)| quote!(#argname: #id, ))
+            .collect::<TokenStream>();
+        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 (_, tg, _) = self.f.egenerics.split_for_impl();
+        let keyid = gen_keyid(&self.f.egenerics);
+        let expectations = if self.f.is_expectation_generic() {
+            quote!(self.guard
+                   .store
+                   .get_mut(&::mockall::Key::new::#keyid())
+                   .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 = with_generics_idents
+            .iter()
+            .zip(self.f.predty.iter())
+            .map(|(id, mt)| quote!(#id: #hrtb ::mockall::Predicate<#mt> + Send + 'static, ))
+            .collect::<TokenStream>();
+        let with_args = self
+            .f
+            .argnames
+            .iter()
+            .zip(with_generics_idents.iter())
+            .map(|(argname, id)| quote!(#argname: #id, ))
+            .collect::<TokenStream>();
+        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 common_methods = ExpectationGuardCommonMethods { f: self.f };
+        let (_, tg, _) = self.f.egenerics.split_for_impl();
+        let keyid = gen_keyid(&self.f.egenerics);
+        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 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::#keyid()
+                        ).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 = self
+            .f
+            .struct_generics
+            .type_params()
+            .map(|tp| tp.ident.clone())
+            .collect::<Punctuated<Ident, Token![,]>>();
+        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) {
+                    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 = argnames
+            .iter()
+            .enumerate()
+            .map(|(i, argname)| {
+                let idx = syn::Index::from(i);
+                quote!(__mockall_pred.#idx.eval(#argname),)
+            })
+            .collect::<TokenStream>();
+        let preds = self
+            .f
+            .predty
+            .iter()
+            .map(|t| quote!(Box<dyn #hrtb ::mockall::Predicate<#t> + Send>,))
+            .collect::<TokenStream>();
+        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)) => {
+                            ::std::result::Result::Ok(__mockall_o)
+                        },
+                        Rfunc::Default(None) => {
+                            Err(#default_err_msg)
+                        },
+                        Rfunc::Const(ref __mockall_o) => {
+                            ::std::result::Result::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)) => {
+                            ::std::result::Result::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 {
+                                ::std::result::Result::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 {
+                                ::std::result::Result::Ok(__mockall_o2)
+                            } else {
+                                unreachable!()
+                            }
+                        },
+                        Rfunc::Var(ref mut __mockall_o) => {
+                            ::std::result::Result::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) => {
+                            ::std::result::Result::Ok(__mockall_f( #(#argnames, )* ))
+                        },
+                        Rfunc::MutSt(__mockall_f) => {
+                            ::std::result::Result::Ok((__mockall_f.get_mut())(#(#argnames,)*))
+                        },
+                        Rfunc::Once(_) => {
+                            if let Rfunc::Once(mut __mockall_f) =
+                                mem::replace(self, Rfunc::Expired) {
+                                ::std::result::Result::Ok(__mockall_f( #(#argnames, )* ))
+                            } else {
+                                unreachable!()
+                            }
+                        },
+                        Rfunc::OnceSt(_) => {
+                            if let Rfunc::OnceSt(mut __mockall_f) =
+                                mem::replace(self, Rfunc::Expired) {
+                                ::std::result::Result::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 argnames = &self.f.argnames;
+        let argty = &self.f.argty;
+        let common_methods = CommonExpectationMethods { f: self.f };
+        let desc = self.f.desc();
+        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, #(#argnames: #argty, )*) -> #output
+                {
+                    self.common.call(&#desc);
+                    self.rfunc.call().unwrap_or_else(|m| {
+                        let desc = std::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 desc = self.f.desc();
+        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(&#desc);
+                    let desc = std::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 desc = self.f.desc();
+        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(&#desc);
+                    self.rfunc.lock().unwrap().call_mut(#(#argnames, )*)
+                        .unwrap_or_else(|message| {
+                            let desc = std::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(#(#argnames),*)
+                        )
+                }
+
+            }
+        )
+        .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 keyid = gen_keyid(&self.f.egenerics);
+        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 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::#keyid())
+                        .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::#keyid())
+                        .or_insert_with(|| Box::new(Expectations #tbf::new()))
+                        .downcast_mut::<Expectations #tg>()
+                        .unwrap()
+                        .expect()
+                }
+            }
+        )
+        .to_tokens(tokens)
+    }
+}
diff --git a/src/mock_item.rs b/src/mock_item.rs
new file mode 100644
index 0000000..109d9c2
--- /dev/null
+++ b/src/mock_item.rs
@@ -0,0 +1,172 @@
+// vim: tw=80
+use super::*;
+
+use crate::{
+    mock_function::MockFunction,
+    mockable_item::{MockableItem, MockableModule},
+};
+
+/// A Mock item
+pub(crate) enum MockItem {
+    Module(MockItemModule),
+    Struct(MockItemStruct),
+}
+
+impl From<MockableItem> for MockItem {
+    fn from(mockable: MockableItem) -> MockItem {
+        match mockable {
+            MockableItem::Struct(s) => MockItem::Struct(MockItemStruct::from(s)),
+            MockableItem::Module(mod_) => MockItem::Module(MockItemModule::from(mod_)),
+        }
+    }
+}
+
+impl ToTokens for MockItem {
+    fn to_tokens(&self, tokens: &mut TokenStream) {
+        match self {
+            MockItem::Module(mod_) => mod_.to_tokens(tokens),
+            MockItem::Struct(s) => s.to_tokens(tokens),
+        }
+    }
+}
+
+enum MockItemContent {
+    Fn(Box<MockFunction>),
+    Tokens(TokenStream),
+}
+
+pub(crate) struct MockItemModule {
+    attrs: TokenStream,
+    vis: Visibility,
+    mock_ident: Ident,
+    orig_ident: Option<Ident>,
+    content: Vec<MockItemContent>,
+}
+
+impl From<MockableModule> for MockItemModule {
+    fn from(mod_: MockableModule) -> MockItemModule {
+        let mock_ident = mod_.mock_ident.clone();
+        let orig_ident = mod_.orig_ident;
+        let mut content = Vec::new();
+        for item in mod_.content.into_iter() {
+            let span = item.span();
+            match item {
+                Item::ExternCrate(_) | Item::Impl(_) => {
+                    // Ignore
+                }
+                Item::Static(is) => {
+                    content.push(MockItemContent::Tokens(is.into_token_stream()));
+                }
+                Item::Const(ic) => {
+                    content.push(MockItemContent::Tokens(ic.into_token_stream()));
+                }
+                Item::Fn(f) => {
+                    let mf = mock_function::Builder::new(&f.sig, &f.vis)
+                        .attrs(&f.attrs)
+                        .parent(&mock_ident)
+                        .levels(1)
+                        .call_levels(0)
+                        .build();
+                    content.push(MockItemContent::Fn(Box::new(mf)));
+                }
+                Item::ForeignMod(ifm) => {
+                    for item in ifm.items {
+                        if let ForeignItem::Fn(mut f) = item {
+                            // Foreign functions are always unsafe.  Mock
+                            // foreign functions should be unsafe too, to
+                            // prevent "warning: unused unsafe" messages.
+                            f.sig.unsafety = Some(Token![unsafe](f.span()));
+                            let mf = mock_function::Builder::new(&f.sig, &f.vis)
+                                .attrs(&f.attrs)
+                                .parent(&mock_ident)
+                                .levels(1)
+                                .call_levels(0)
+                                .build();
+                            content.push(MockItemContent::Fn(Box::new(mf)));
+                        } else {
+                            compile_error(item.span(),
+                                "Mockall does not yet support  this type in this position.  Please open an issue with your use case at https://github.com/asomers/mockall");
+                        }
+                    }
+                }
+                Item::Mod(_)
+                | Item::Struct(_)
+                | Item::Enum(_)
+                | Item::Union(_)
+                | Item::Trait(_) => {
+                    compile_error(span, "Mockall does not yet support deriving nested mocks");
+                }
+                Item::Type(ty) => {
+                    content.push(MockItemContent::Tokens(ty.into_token_stream()));
+                }
+                Item::TraitAlias(ta) => {
+                    content.push(MockItemContent::Tokens(ta.into_token_stream()));
+                }
+                Item::Use(u) => {
+                    content.push(MockItemContent::Tokens(u.into_token_stream()));
+                }
+                _ => compile_error(span, "Unsupported item"),
+            }
+        }
+        MockItemModule {
+            attrs: mod_.attrs,
+            vis: mod_.vis,
+            mock_ident: mod_.mock_ident,
+            orig_ident,
+            content,
+        }
+    }
+}
+
+impl ToTokens for MockItemModule {
+    fn to_tokens(&self, tokens: &mut TokenStream) {
+        let mut body = TokenStream::new();
+        let mut cp_body = TokenStream::new();
+        let attrs = &self.attrs;
+        let modname = &self.mock_ident;
+        let vis = &self.vis;
+
+        for item in self.content.iter() {
+            match item {
+                MockItemContent::Tokens(ts) => ts.to_tokens(&mut body),
+                MockItemContent::Fn(f) => {
+                    let call = f.call(None);
+                    let ctx_fn = f.context_fn(None);
+                    let priv_mod = f.priv_module();
+                    quote!(
+                        #priv_mod
+                        #call
+                        #ctx_fn
+                    )
+                    .to_tokens(&mut body);
+                    f.checkpoint().to_tokens(&mut cp_body);
+                }
+            }
+        }
+
+        quote!(
+            /// Verify that all current expectations for every function in
+            /// this module are satisfied and clear them.
+            pub fn checkpoint() { #cp_body }
+        )
+        .to_tokens(&mut body);
+        let docstr = {
+            if let Some(ident) = &self.orig_ident {
+                let inner = format!("Mock version of the `{}` module", ident);
+                quote!( #[doc = #inner])
+            } else {
+                // Typically an extern FFI block.  Not really anything good we
+                // can put in the doc string.
+                quote!(#[allow(missing_docs)])
+            }
+        };
+        quote!(
+            #[allow(unused_imports)]
+            #attrs
+            #docstr
+            #vis mod #modname {
+                #body
+        })
+        .to_tokens(tokens);
+    }
+}
diff --git a/src/mock_item_struct.rs b/src/mock_item_struct.rs
new file mode 100644
index 0000000..9bf5c13
--- /dev/null
+++ b/src/mock_item_struct.rs
@@ -0,0 +1,456 @@
+// vim: tw=80
+use super::*;
+
+use quote::ToTokens;
+use std::collections::HashSet;
+
+use crate::{mock_function::MockFunction, mock_trait::MockTrait};
+
+fn phantom_default_inits(generics: &Generics) -> Vec<TokenStream> {
+    generics
+        .params
+        .iter()
+        .enumerate()
+        .map(|(count, _param)| {
+            let phident = format_ident!("_t{}", count);
+            quote!(#phident: ::std::marker::PhantomData)
+        })
+        .collect()
+}
+
+/// Generate any PhantomData field definitions
+fn phantom_fields(generics: &Generics) -> Vec<TokenStream> {
+    generics
+        .params
+        .iter()
+        .enumerate()
+        .filter_map(|(count, param)| {
+            let phident = format_ident!("_t{}", count);
+            match param {
+                syn::GenericParam::Lifetime(l) => {
+                    if !l.bounds.is_empty() {
+                        compile_error(
+                            l.bounds.span(),
+                            "#automock does not yet support lifetime bounds on structs",
+                        );
+                    }
+                    let lifetime = &l.lifetime;
+                    Some(quote!(#phident: ::std::marker::PhantomData<&#lifetime ()>))
+                }
+                syn::GenericParam::Type(tp) => {
+                    let ty = &tp.ident;
+                    Some(quote!(#phident: ::std::marker::PhantomData<#ty>))
+                }
+                syn::GenericParam::Const(_) => {
+                    compile_error(
+                        param.span(),
+                        "#automock does not yet support generic constants",
+                    );
+                    None
+                }
+            }
+        })
+        .collect()
+}
+
+/// Filter out multiple copies of the same trait, even if they're implemented on
+/// different types.  But allow them if they have different attributes, which
+/// probably indicates that they aren't meant to be compiled together.
+fn unique_trait_iter<'a, I: Iterator<Item = &'a MockTrait>>(
+    i: I,
+) -> impl Iterator<Item = &'a MockTrait> {
+    let mut hs = HashSet::<(Path, Vec<Attribute>)>::default();
+    i.filter(move |mt| {
+        let impl_attrs = AttrFormatter::new(&mt.attrs)
+            .async_trait(false)
+            .doc(false)
+            .format();
+        let key = (mt.trait_path.clone(), impl_attrs);
+        if hs.contains(&key) {
+            false
+        } else {
+            hs.insert(key);
+            true
+        }
+    })
+}
+
+/// A collection of methods defined in one spot
+struct Methods(Vec<MockFunction>);
+
+impl Methods {
+    /// Are all of these methods static?
+    fn all_static(&self) -> bool {
+        self.0.iter().all(|meth| meth.is_static())
+    }
+
+    fn checkpoints(&self) -> Vec<impl ToTokens> {
+        self.0
+            .iter()
+            .filter(|meth| !meth.is_static())
+            .map(|meth| meth.checkpoint())
+            .collect::<Vec<_>>()
+    }
+
+    /// Return a fragment of code to initialize struct fields during default()
+    fn default_inits(&self) -> Vec<TokenStream> {
+        self.0
+            .iter()
+            .filter(|meth| !meth.is_static())
+            .map(|meth| {
+                let name = meth.name();
+                let attrs = AttrFormatter::new(&meth.attrs).doc(false).format();
+                quote!(#(#attrs)* #name: Default::default())
+            })
+            .collect::<Vec<_>>()
+    }
+
+    fn field_definitions(&self, modname: &Ident) -> Vec<TokenStream> {
+        self.0
+            .iter()
+            .filter(|meth| !meth.is_static())
+            .map(|meth| meth.field_definition(Some(modname)))
+            .collect::<Vec<_>>()
+    }
+
+    fn priv_mods(&self) -> Vec<impl ToTokens> {
+        self.0
+            .iter()
+            .map(|meth| meth.priv_module())
+            .collect::<Vec<_>>()
+    }
+}
+
+pub(crate) struct MockItemStruct {
+    attrs: Vec<Attribute>,
+    consts: Vec<ImplItemConst>,
+    generics: Generics,
+    /// Should Mockall generate a Debug implementation?
+    auto_debug: bool,
+    /// Does the original struct have a `new` method?
+    has_new: bool,
+    /// Inherent methods of the mock struct
+    methods: Methods,
+    /// Name of the overall module that holds all of the mock stuff
+    modname: Ident,
+    name: Ident,
+    /// Is this a whole MockStruct or just a substructure for a trait impl?
+    traits: Vec<MockTrait>,
+    vis: Visibility,
+}
+
+impl MockItemStruct {
+    fn debug_impl(&self) -> impl ToTokens {
+        if self.auto_debug {
+            let (ig, tg, wc) = self.generics.split_for_impl();
+            let struct_name = &self.name;
+            let struct_name_str = format!("{}", self.name);
+            quote!(
+                impl #ig ::std::fmt::Debug for #struct_name #tg #wc {
+                    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>)
+                        -> ::std::result::Result<(), std::fmt::Error>
+                    {
+                        f.debug_struct(#struct_name_str).finish()
+                    }
+                }
+            )
+        } else {
+            quote!()
+        }
+    }
+
+    fn new_method(&self) -> impl ToTokens {
+        if self.has_new {
+            TokenStream::new()
+        } else {
+            quote!(
+                /// Create a new mock object with no expectations.
+                ///
+                /// This method will not be generated if the real struct
+                /// already has a `new` method.  However, it *will* be
+                /// generated if the struct implements a trait with a `new`
+                /// method.  The trait's `new` method can still be called
+                /// like `<MockX as TraitY>::new`
+                pub fn new() -> Self {
+                    Self::default()
+                }
+            )
+        }
+    }
+
+    fn phantom_default_inits(&self) -> Vec<TokenStream> {
+        phantom_default_inits(&self.generics)
+    }
+
+    fn phantom_fields(&self) -> Vec<TokenStream> {
+        phantom_fields(&self.generics)
+    }
+}
+
+impl From<MockableStruct> for MockItemStruct {
+    fn from(mockable: MockableStruct) -> MockItemStruct {
+        let auto_debug = mockable.derives_debug();
+        let modname = gen_mod_ident(&mockable.name, None);
+        let generics = mockable.generics.clone();
+        let struct_name = &mockable.name;
+        let vis = mockable.vis;
+        let has_new = mockable.methods.iter().any(|meth| meth.sig.ident == "new")
+            || mockable.impls.iter().any(|impl_| {
+                impl_.items.iter().any(|ii| {
+                    if let ImplItem::Method(iim) = ii {
+                        iim.sig.ident == "new"
+                    } else {
+                        false
+                    }
+                })
+            });
+        let methods = Methods(
+            mockable
+                .methods
+                .into_iter()
+                .map(|meth| {
+                    mock_function::Builder::new(&meth.sig, &meth.vis)
+                        .attrs(&meth.attrs)
+                        .struct_(struct_name)
+                        .struct_generics(&generics)
+                        .levels(2)
+                        .call_levels(0)
+                        .build()
+                })
+                .collect::<Vec<_>>(),
+        );
+        let structname = &mockable.name;
+        let traits = mockable
+            .impls
+            .into_iter()
+            .map(|i| MockTrait::new(structname, &generics, i, &vis))
+            .collect();
+
+        MockItemStruct {
+            attrs: mockable.attrs,
+            auto_debug,
+            consts: mockable.consts,
+            generics,
+            has_new,
+            methods,
+            modname,
+            name: mockable.name,
+            traits,
+            vis,
+        }
+    }
+}
+
+impl ToTokens for MockItemStruct {
+    fn to_tokens(&self, tokens: &mut TokenStream) {
+        let attrs = AttrFormatter::new(&self.attrs).async_trait(false).format();
+        let consts = &self.consts;
+        let debug_impl = self.debug_impl();
+        let struct_name = &self.name;
+        let (ig, tg, wc) = self.generics.split_for_impl();
+        let modname = &self.modname;
+        let calls = self
+            .methods
+            .0
+            .iter()
+            .map(|meth| meth.call(Some(modname)))
+            .collect::<Vec<_>>();
+        let contexts = self
+            .methods
+            .0
+            .iter()
+            .filter(|meth| meth.is_static())
+            .map(|meth| meth.context_fn(Some(modname)))
+            .collect::<Vec<_>>();
+        let expects = self
+            .methods
+            .0
+            .iter()
+            .filter(|meth| !meth.is_static())
+            .map(|meth| meth.expect(modname, None))
+            .collect::<Vec<_>>();
+        let method_checkpoints = self.methods.checkpoints();
+        let new_method = self.new_method();
+        let priv_mods = self.methods.priv_mods();
+        let substructs = unique_trait_iter(self.traits.iter())
+            .map(|trait_| MockItemTraitImpl {
+                attrs: trait_.attrs.clone(),
+                generics: self.generics.clone(),
+                fieldname: format_ident!("{}_expectations", trait_.ss_name()),
+                methods: Methods(trait_.methods.clone()),
+                modname: format_ident!("{}_{}", &self.modname, trait_.ss_name()),
+                name: format_ident!("{}_{}", &self.name, trait_.ss_name()),
+            })
+            .collect::<Vec<_>>();
+        let substruct_expectations = substructs
+            .iter()
+            .filter(|ss| !ss.all_static())
+            .map(|ss| {
+                let attrs = AttrFormatter::new(&ss.attrs)
+                    .async_trait(false)
+                    .doc(false)
+                    .format();
+                let fieldname = &ss.fieldname;
+                quote!(#(#attrs)* self.#fieldname.checkpoint();)
+            })
+            .collect::<Vec<_>>();
+        let mut field_definitions = substructs
+            .iter()
+            .filter(|ss| !ss.all_static())
+            .map(|ss| {
+                let attrs = AttrFormatter::new(&ss.attrs)
+                    .async_trait(false)
+                    .doc(false)
+                    .format();
+                let fieldname = &ss.fieldname;
+                let tyname = &ss.name;
+                quote!(#(#attrs)* #fieldname: #tyname #tg)
+            })
+            .collect::<Vec<_>>();
+        field_definitions.extend(self.methods.field_definitions(modname));
+        field_definitions.extend(self.phantom_fields());
+        let mut default_inits = substructs
+            .iter()
+            .filter(|ss| !ss.all_static())
+            .map(|ss| {
+                let attrs = AttrFormatter::new(&ss.attrs)
+                    .async_trait(false)
+                    .doc(false)
+                    .format();
+                let fieldname = &ss.fieldname;
+                quote!(#(#attrs)* #fieldname: Default::default())
+            })
+            .collect::<Vec<_>>();
+        default_inits.extend(self.methods.default_inits());
+        default_inits.extend(self.phantom_default_inits());
+        let trait_impls = self
+            .traits
+            .iter()
+            .map(|trait_| {
+                let modname = format_ident!("{}_{}", &self.modname, trait_.ss_name());
+                trait_.trait_impl(&modname)
+            })
+            .collect::<Vec<_>>();
+        let vis = &self.vis;
+        quote!(
+            #[allow(non_snake_case)]
+            #[allow(missing_docs)]
+            pub mod #modname {
+                use super::*;
+                #(#priv_mods)*
+            }
+            #[allow(non_camel_case_types)]
+            #[allow(non_snake_case)]
+            #[allow(missing_docs)]
+            #(#attrs)*
+            #vis struct #struct_name #ig #wc
+            {
+                #(#field_definitions),*
+            }
+            #debug_impl
+            impl #ig ::std::default::Default for #struct_name #tg #wc {
+                #[allow(clippy::default_trait_access)]
+                fn default() -> Self {
+                    Self {
+                        #(#default_inits),*
+                    }
+                }
+            }
+            #(#substructs)*
+            impl #ig #struct_name #tg #wc {
+                #(#consts)*
+                #(#calls)*
+                #(#contexts)*
+                #(#expects)*
+                /// Validate that all current expectations for all methods have
+                /// been satisfied, and discard them.
+                pub fn checkpoint(&mut self) {
+                    #(#substruct_expectations)*
+                    #(#method_checkpoints)*
+                }
+                #new_method
+            }
+            #(#trait_impls)*
+        )
+        .to_tokens(tokens);
+    }
+}
+
+pub(crate) struct MockItemTraitImpl {
+    attrs: Vec<Attribute>,
+    generics: Generics,
+    /// Inherent methods of the mock struct
+    methods: Methods,
+    /// Name of the overall module that holds all of the mock stuff
+    modname: Ident,
+    name: Ident,
+    /// Name of the field of this type in the parent's structure
+    fieldname: Ident,
+}
+
+impl MockItemTraitImpl {
+    /// Are all of this traits's methods static?
+    fn all_static(&self) -> bool {
+        self.methods.all_static()
+    }
+
+    fn phantom_default_inits(&self) -> Vec<TokenStream> {
+        phantom_default_inits(&self.generics)
+    }
+
+    fn phantom_fields(&self) -> Vec<TokenStream> {
+        phantom_fields(&self.generics)
+    }
+}
+
+impl ToTokens for MockItemTraitImpl {
+    fn to_tokens(&self, tokens: &mut TokenStream) {
+        let attrs = AttrFormatter::new(&self.attrs)
+            .async_trait(false)
+            .doc(false)
+            .format();
+        let struct_name = &self.name;
+        let (ig, tg, wc) = self.generics.split_for_impl();
+        let modname = &self.modname;
+        let method_checkpoints = self.methods.checkpoints();
+        let mut default_inits = self.methods.default_inits();
+        default_inits.extend(self.phantom_default_inits());
+        let mut field_definitions = self.methods.field_definitions(modname);
+        field_definitions.extend(self.phantom_fields());
+        let priv_mods = self.methods.priv_mods();
+        quote!(
+            #[allow(non_snake_case)]
+            #[allow(missing_docs)]
+            #(#attrs)*
+            pub mod #modname {
+                use super::*;
+                #(#priv_mods)*
+            }
+            #[allow(non_camel_case_types)]
+            #[allow(non_snake_case)]
+            #[allow(missing_docs)]
+            #(#attrs)*
+            struct #struct_name #ig #wc
+            {
+                #(#field_definitions),*
+            }
+            #(#attrs)*
+            impl #ig ::std::default::Default for #struct_name #tg #wc {
+                fn default() -> Self {
+                    Self {
+                        #(#default_inits),*
+                    }
+                }
+            }
+            #(#attrs)*
+            impl #ig #struct_name #tg #wc {
+                /// Validate that all current expectations for all methods have
+                /// been satisfied, and discard them.
+                pub fn checkpoint(&mut self) {
+                    #(#method_checkpoints)*
+                }
+            }
+        )
+        .to_tokens(tokens);
+    }
+}
diff --git a/src/mock_trait.rs b/src/mock_trait.rs
new file mode 100644
index 0000000..eba29b6
--- /dev/null
+++ b/src/mock_trait.rs
@@ -0,0 +1,184 @@
+// vim: tw=80
+use proc_macro2::Span;
+use quote::{format_ident, quote, ToTokens};
+use std::{
+    collections::hash_map::DefaultHasher,
+    hash::{Hash, Hasher},
+};
+use syn::{spanned::Spanned, *};
+
+use crate::{
+    compile_error,
+    mock_function::{self, MockFunction},
+    AttrFormatter,
+};
+
+pub(crate) struct MockTrait {
+    pub attrs: Vec<Attribute>,
+    pub consts: Vec<ImplItemConst>,
+    pub generics: Generics,
+    pub methods: Vec<MockFunction>,
+    /// Internally-used name of the trait used.
+    pub ss_name: Ident,
+    /// Fully-qualified name of the trait
+    pub trait_path: Path,
+    /// Path on which the trait is implemented.  Usually will be the same as
+    /// structname, but might include concrete generic parameters.
+    self_path: PathSegment,
+    pub types: Vec<ImplItemType>,
+    pub unsafety: Option<Token![unsafe]>,
+}
+
+impl MockTrait {
+    fn ss_name_priv(trait_path: &Path) -> Ident {
+        let path_args = &trait_path.segments.last().unwrap().arguments;
+        if path_args.is_empty() {
+            // Skip the hashing step for easie debugging of generated code
+            format_ident!("{}", trait_path.segments.last().unwrap().ident)
+        } else {
+            // Hash the path args to permit mocking structs that implement
+            // multiple traits distinguished only by their path args
+            let mut hasher = DefaultHasher::new();
+            path_args.hash(&mut hasher);
+            format_ident!(
+                "{}_{}",
+                trait_path.segments.last().unwrap().ident,
+                hasher.finish()
+            )
+        }
+    }
+
+    pub fn ss_name(&self) -> &Ident {
+        &self.ss_name
+    }
+
+    /// Create a new MockTrait
+    ///
+    /// # Arguments
+    /// * `structname` - name of the struct that implements this trait
+    /// * `struct_generics` - Generics of the parent structure
+    /// * `impl_`  -    Mockable ItemImpl for a trait
+    /// * `vis`     -   Visibility of the struct
+    pub fn new(
+        structname: &Ident,
+        struct_generics: &Generics,
+        impl_: ItemImpl,
+        vis: &Visibility,
+    ) -> Self {
+        let mut consts = Vec::new();
+        let mut methods = Vec::new();
+        let mut types = Vec::new();
+        let trait_path = if let Some((_, path, _)) = impl_.trait_ {
+            path
+        } else {
+            compile_error(impl_.span(), "impl block must implement a trait");
+            Path::from(format_ident!("__mockall_invalid"))
+        };
+        let ss_name = MockTrait::ss_name_priv(&trait_path);
+        let self_path = match *impl_.self_ty {
+            Type::Path(mut type_path) => type_path.path.segments.pop().unwrap().into_value(),
+            x => {
+                compile_error(
+                    x.span(),
+                    "mockall_derive only supports mocking traits and structs",
+                );
+                PathSegment::from(Ident::new("", Span::call_site()))
+            }
+        };
+
+        for ii in impl_.items.into_iter() {
+            match ii {
+                ImplItem::Const(iic) => {
+                    consts.push(iic);
+                }
+                ImplItem::Method(iim) => {
+                    let mf = mock_function::Builder::new(&iim.sig, vis)
+                        .attrs(&iim.attrs)
+                        .levels(2)
+                        .call_levels(0)
+                        .struct_(structname)
+                        .struct_generics(struct_generics)
+                        .trait_(&ss_name)
+                        .build();
+                    methods.push(mf);
+                }
+                ImplItem::Type(iit) => {
+                    types.push(iit);
+                }
+                _ => {
+                    compile_error(ii.span(), "This impl item is not yet supported by MockAll");
+                }
+            }
+        }
+        MockTrait {
+            attrs: impl_.attrs,
+            consts,
+            generics: impl_.generics,
+            methods,
+            ss_name,
+            trait_path,
+            self_path,
+            types,
+            unsafety: impl_.unsafety,
+        }
+    }
+
+    /// Generate code for the trait implementation on the mock struct
+    ///
+    /// # Arguments
+    ///
+    /// * `modname`:    Name of the parent struct's private module
+    // Supplying modname is an unfortunately hack.  Ideally MockTrait
+    // wouldn't need to know that.
+    pub fn trait_impl(&self, modname: &Ident) -> impl ToTokens {
+        let trait_impl_attrs = &self.attrs;
+        let impl_attrs = AttrFormatter::new(&self.attrs)
+            .async_trait(false)
+            .doc(false)
+            .format();
+        let (ig, _tg, wc) = self.generics.split_for_impl();
+        let consts = &self.consts;
+        let path_args = &self.self_path.arguments;
+        let calls = self
+            .methods
+            .iter()
+            .map(|meth| meth.call(Some(modname)))
+            .collect::<Vec<_>>();
+        let contexts = self
+            .methods
+            .iter()
+            .filter(|meth| meth.is_static())
+            .map(|meth| meth.context_fn(Some(modname)))
+            .collect::<Vec<_>>();
+        let expects = self
+            .methods
+            .iter()
+            .filter(|meth| !meth.is_static())
+            .map(|meth| {
+                if meth.is_method_generic() {
+                    // Specific impls with generic methods are TODO.
+                    meth.expect(modname, None)
+                } else {
+                    meth.expect(modname, Some(path_args))
+                }
+            })
+            .collect::<Vec<_>>();
+        let trait_path = &self.trait_path;
+        let self_path = &self.self_path;
+        let types = &self.types;
+        let unsafety = &self.unsafety;
+        quote!(
+            #(#trait_impl_attrs)*
+            #unsafety impl #ig #trait_path for #self_path #wc {
+                #(#consts)*
+                #(#types)*
+                #(#calls)*
+            }
+            #(#impl_attrs)*
+            impl #ig #self_path #wc {
+                #(#expects)*
+                #(#contexts)*
+            }
+        )
+    }
+}
diff --git a/src/mockable_item.rs b/src/mockable_item.rs
new file mode 100644
index 0000000..03c894d
--- /dev/null
+++ b/src/mockable_item.rs
@@ -0,0 +1,164 @@
+// vim: tw=80
+use super::*;
+
+/// Performs transformations on a function to make it mockable
+fn mockable_fn(mut item_fn: ItemFn) -> ItemFn {
+    demutify(&mut item_fn.sig.inputs);
+    deimplify(&mut item_fn.sig.output);
+    item_fn
+}
+
+/// Performs transformations on an Item to make it mockable
+fn mockable_item(item: Item) -> Item {
+    match item {
+        Item::Fn(item_fn) => Item::Fn(mockable_fn(item_fn)),
+        x => x,
+    }
+}
+
+/// An item that's ready to be mocked.
+///
+/// It should be functionally identical or near-identical to the original item,
+/// but with minor alterations that make it suitable for mocking, such as
+/// altered lifetimes.
+pub(crate) enum MockableItem {
+    Module(MockableModule),
+    Struct(MockableStruct),
+}
+
+impl From<(Attrs, Item)> for MockableItem {
+    fn from((attrs, item): (Attrs, Item)) -> MockableItem {
+        match item {
+            Item::Impl(item_impl) => MockableItem::Struct(MockableStruct::from(item_impl)),
+            Item::ForeignMod(item_foreign_mod) => {
+                MockableItem::Module(MockableModule::from((attrs, item_foreign_mod)))
+            }
+            Item::Mod(item_mod) => MockableItem::Module(MockableModule::from(item_mod)),
+            Item::Trait(trait_) => MockableItem::Struct(MockableStruct::from((attrs, trait_))),
+            _ => panic!("automock does not support this item type"),
+        }
+    }
+}
+
+impl From<MockableStruct> for MockableItem {
+    fn from(mock: MockableStruct) -> MockableItem {
+        MockableItem::Struct(mock)
+    }
+}
+
+pub(crate) struct MockableModule {
+    pub attrs: TokenStream,
+    pub vis: Visibility,
+    pub mock_ident: Ident,
+    /// Ident of the original module, if any
+    pub orig_ident: Option<Ident>,
+    pub content: Vec<Item>,
+}
+
+impl From<(Attrs, ItemForeignMod)> for MockableModule {
+    fn from((attrs, foreign): (Attrs, ItemForeignMod)) -> MockableModule {
+        let orig_ident = None;
+        let mock_ident = attrs.modname.expect(concat!(
+            "module name is required when mocking foreign functions,",
+            " like `#[automock(mod mock_ffi)]`"
+        ));
+        let vis = Visibility::Public(VisPublic {
+            pub_token: <Token![pub]>::default(),
+        });
+        let attrs = quote!(
+            #[deprecated(since = "0.9.0", note = "Using automock directly on an extern block is deprecated.  Instead, wrap the extern block in a module, and automock that, like #[automock] mod ffi { extern \"C\" { fn foo ... } }")]
+        );
+        let mut content = vec![
+            // When mocking extern blocks, we pretend that they're modules, so
+            // we need a "use super::*;" to ensure that types can resolve
+            Item::Use(ItemUse {
+                attrs: Vec::new(),
+                vis: Visibility::Inherited,
+                use_token: token::Use::default(),
+                leading_colon: None,
+                tree: UseTree::Path(UsePath {
+                    ident: Ident::new("super", Span::call_site()),
+                    colon2_token: token::Colon2::default(),
+                    tree: Box::new(UseTree::Glob(UseGlob {
+                        star_token: token::Star::default(),
+                    })),
+                }),
+                semi_token: token::Semi::default(),
+            }),
+        ];
+        content.extend(foreign.items.into_iter().map(|foreign_item| {
+            match foreign_item {
+                ForeignItem::Fn(f) => {
+                    let span = f.sig.span();
+                    let mut sig = f.sig;
+
+                    // When mocking extern blocks, we pretend that they're
+                    // modules.  So we must supersuperfy everything by one
+                    // level.
+                    let vis = expectation_visibility(&f.vis, 1);
+
+                    for arg in sig.inputs.iter_mut() {
+                        if let FnArg::Typed(pt) = arg {
+                            *pt.ty = supersuperfy(pt.ty.as_ref(), 1);
+                        }
+                    }
+                    if let ReturnType::Type(_, ty) = &mut sig.output {
+                        **ty = supersuperfy(&*ty, 1);
+                    }
+
+                    // Foreign functions are always unsafe.  Mock foreign
+                    // functions should be unsafe too, to prevent "warning:
+                    // unused unsafe" messages.
+                    sig.unsafety = Some(Token![unsafe](span));
+                    let block = Box::new(Block {
+                        brace_token: token::Brace::default(),
+                        stmts: Vec::new(),
+                    });
+
+                    Item::Fn(ItemFn {
+                        attrs: f.attrs,
+                        vis,
+                        sig,
+                        block,
+                    })
+                }
+                _ => {
+                    compile_error(foreign_item.span(), "Unsupported foreign item type");
+                    Item::Verbatim(TokenStream::default())
+                }
+            }
+        }));
+        MockableModule {
+            attrs,
+            vis,
+            mock_ident,
+            orig_ident,
+            content,
+        }
+    }
+}
+
+impl From<ItemMod> for MockableModule {
+    fn from(mod_: ItemMod) -> MockableModule {
+        let span = mod_.span();
+        let vis = mod_.vis;
+        let mock_ident = format_ident!("mock_{}", mod_.ident);
+        let orig_ident = Some(mod_.ident);
+        let content = if let Some((_, content)) = mod_.content {
+            content.into_iter().map(mockable_item).collect()
+        } else {
+            compile_error(
+                span,
+                "automock can only mock inline modules, not modules from another file",
+            );
+            Vec::new()
+        };
+        MockableModule {
+            attrs: TokenStream::new(),
+            vis,
+            mock_ident,
+            orig_ident,
+            content,
+        }
+    }
+}
diff --git a/src/mockable_struct.rs b/src/mockable_struct.rs
new file mode 100644
index 0000000..fe28199
--- /dev/null
+++ b/src/mockable_struct.rs
@@ -0,0 +1,642 @@
+// vim: tw=80
+use super::*;
+use syn::parse::{Parse, ParseStream};
+
+/// Make any implicit lifetime parameters explicit
+fn add_lifetime_parameters(sig: &mut Signature) {
+    fn add_to_trait_object(generics: &mut Generics, var: &Pat, to: &mut TypeTraitObject) {
+        let mut has_lifetime = false;
+        for bound in to.bounds.iter() {
+            if let TypeParamBound::Lifetime(_) = bound {
+                has_lifetime = true;
+            }
+        }
+        if !has_lifetime {
+            let arg_ident = match *var {
+                Pat::Wild(_) => {
+                    compile_error(var.span(), "Mocked methods must have named arguments");
+                    format_ident!("dont_care")
+                }
+                Pat::Ident(ref pat_ident) => {
+                    if let Some(r) = &pat_ident.by_ref {
+                        compile_error(
+                            r.span(),
+                            "Mockall does not support by-reference argument bindings",
+                        );
+                    }
+                    if let Some((_at, subpat)) = &pat_ident.subpat {
+                        compile_error(
+                            subpat.span(),
+                            "Mockall does not support subpattern bindings",
+                        );
+                    }
+                    pat_ident.ident.clone()
+                }
+                _ => {
+                    compile_error(var.span(), "Unsupported argument type");
+                    format_ident!("dont_care")
+                }
+            };
+            let s = format!("'__mockall_{}", arg_ident);
+            let span = Span::call_site();
+            let lt = Lifetime::new(&s, span);
+            to.bounds.push(TypeParamBound::Lifetime(lt.clone()));
+            generics.lt_token.get_or_insert(Token![<](span));
+            generics.gt_token.get_or_insert(Token![>](span));
+            let gpl = GenericParam::Lifetime(LifetimeDef::new(lt));
+            generics.params.push(gpl);
+        }
+    }
+
+    fn add_to_type(generics: &mut Generics, var: &Pat, ty: &mut Type) {
+        match ty {
+            Type::Array(ta) => add_to_type(generics, var, ta.elem.as_mut()),
+            Type::BareFn(_) => (),
+            Type::ImplTrait(_) => (),
+            Type::Path(_) => (),
+            Type::Ptr(_) => (),
+            Type::Reference(tr) => {
+                match tr.elem.as_mut() {
+                    Type::Paren(tp) => {
+                        if let Type::TraitObject(to) = tp.elem.as_mut() {
+                            add_to_trait_object(generics, var, to);
+                        } else {
+                            add_to_type(generics, var, tr.elem.as_mut());
+                        }
+                    }
+                    Type::TraitObject(to) => {
+                        add_to_trait_object(generics, var, to);
+                        // We need to wrap it in a Paren.  Otherwise it won't be
+                        // syntactically valid after we add a lifetime bound,
+                        // due to a "ambiguous `+` in a type" error
+                        *tr.elem = Type::Paren(TypeParen {
+                            paren_token: token::Paren::default(),
+                            elem: Box::new(Type::TraitObject(to.clone())),
+                        });
+                    }
+                    _ => add_to_type(generics, var, tr.elem.as_mut()),
+                }
+            }
+            Type::Slice(ts) => add_to_type(generics, var, ts.elem.as_mut()),
+            Type::Tuple(tt) => {
+                for ty in tt.elems.iter_mut() {
+                    add_to_type(generics, var, ty)
+                }
+            }
+            _ => compile_error(ty.span(), "unsupported type in this position"),
+        }
+    }
+
+    for arg in sig.inputs.iter_mut() {
+        if let FnArg::Typed(pt) = arg {
+            add_to_type(&mut sig.generics, &pt.pat, &mut pt.ty)
+        }
+    }
+}
+
+/// Generate a #[derive(Debug)] Attribute
+fn derive_debug() -> Attribute {
+    Attribute {
+        pound_token: <Token![#]>::default(),
+        style: AttrStyle::Outer,
+        bracket_token: token::Bracket::default(),
+        path: Path::from(format_ident!("derive")),
+        tokens: quote!((Debug)),
+    }
+}
+
+/// Add "Mock" to the front of the named type
+fn mock_ident_in_type(ty: &mut Type) {
+    match ty {
+        Type::Path(type_path) => {
+            if type_path.path.segments.len() != 1 {
+                compile_error(
+                    type_path.path.span(),
+                    "mockall_derive only supports structs defined in the current module",
+                );
+                return;
+            }
+            let ident = &mut type_path.path.segments.last_mut().unwrap().ident;
+            *ident = gen_mock_ident(ident)
+        }
+        x => {
+            compile_error(
+                x.span(),
+                "mockall_derive only supports mocking traits and structs",
+            );
+        }
+    };
+}
+
+/// Performs transformations on the ItemImpl to make it mockable
+fn mockable_item_impl(mut impl_: ItemImpl, name: &Ident, generics: &Generics) -> ItemImpl {
+    mock_ident_in_type(&mut impl_.self_ty);
+    for item in impl_.items.iter_mut() {
+        if let ImplItem::Method(ref mut iim) = item {
+            mockable_method(iim, name, generics);
+        }
+    }
+    impl_
+}
+
+/// Performs transformations on the method to make it mockable
+fn mockable_method(meth: &mut ImplItemMethod, name: &Ident, generics: &Generics) {
+    demutify(&mut meth.sig.inputs);
+    deselfify_args(&mut meth.sig.inputs, name, generics);
+    add_lifetime_parameters(&mut meth.sig);
+    deimplify(&mut meth.sig.output);
+    dewhereselfify(&mut meth.sig.generics);
+    if let ReturnType::Type(_, ty) = &mut meth.sig.output {
+        deselfify(ty, name, generics);
+        deanonymize(ty);
+    }
+    sanity_check_sig(&meth.sig);
+}
+
+/// Performs transformations on the method to make it mockable
+fn mockable_trait_method(meth: &mut TraitItemMethod, name: &Ident, generics: &Generics) {
+    demutify(&mut meth.sig.inputs);
+    deselfify_args(&mut meth.sig.inputs, name, generics);
+    add_lifetime_parameters(&mut meth.sig);
+    deimplify(&mut meth.sig.output);
+    dewhereselfify(&mut meth.sig.generics);
+    if let ReturnType::Type(_, ty) = &mut meth.sig.output {
+        deselfify(ty, name, generics);
+        deanonymize(ty);
+    }
+    sanity_check_sig(&meth.sig);
+}
+
+/// Generates a mockable item impl from a trait method definition
+fn mockable_trait(trait_: ItemTrait, name: &Ident, generics: &Generics) -> ItemImpl {
+    let items = trait_
+        .items
+        .into_iter()
+        .map(|ti| match ti {
+            TraitItem::Method(mut tim) => {
+                mockable_trait_method(&mut tim, name, generics);
+                ImplItem::Method(tim2iim(tim, &Visibility::Inherited))
+            }
+            TraitItem::Const(tic) => ImplItem::Const(tic2iic(tic, &Visibility::Inherited)),
+            TraitItem::Type(tit) => ImplItem::Type(tit2iit(tit, &Visibility::Inherited)),
+            _ => {
+                compile_error(ti.span(), "Unsupported in this context");
+                ImplItem::Verbatim(TokenStream::new())
+            }
+        })
+        .collect::<Vec<_>>();
+    let mut trait_path = Path::from(trait_.ident);
+    let mut struct_path = Path::from(name.clone());
+    let (_, stg, _) = generics.split_for_impl();
+    let (_, ttg, _) = trait_.generics.split_for_impl();
+    if let Ok(abga) = parse2::<AngleBracketedGenericArguments>(quote!(#stg)) {
+        struct_path.segments.last_mut().unwrap().arguments = PathArguments::AngleBracketed(abga);
+    }
+    if let Ok(abga) = parse2::<AngleBracketedGenericArguments>(quote!(#ttg)) {
+        trait_path.segments.last_mut().unwrap().arguments = PathArguments::AngleBracketed(abga);
+    }
+    let self_ty = Box::new(Type::Path(TypePath {
+        qself: None,
+        path: struct_path,
+    }));
+    ItemImpl {
+        attrs: trait_.attrs,
+        defaultness: None,
+        unsafety: trait_.unsafety,
+        impl_token: <Token![impl]>::default(),
+        generics: generics.clone(),
+        trait_: Some((None, trait_path, <Token![for]>::default())),
+        self_ty,
+        brace_token: trait_.brace_token,
+        items,
+    }
+}
+
+fn sanity_check_sig(sig: &Signature) {
+    for arg in sig.inputs.iter() {
+        if let FnArg::Typed(pt) = arg {
+            if let Type::ImplTrait(it) = pt.ty.as_ref() {
+                let bounds = &it.bounds;
+                let s = format!(
+                    "Mockall does not support \"impl trait\" in argument position.  Use \"T: {}\" instead",
+                    quote!(#bounds)
+                );
+                compile_error(it.span(), &s);
+            }
+        }
+    }
+}
+
+/// Converts a TraitItemConst into an ImplItemConst
+fn tic2iic(tic: TraitItemConst, vis: &syn::Visibility) -> ImplItemConst {
+    let span = tic.span();
+    let (eq_token, expr) = tic.default.unwrap_or_else(|| {
+        compile_error(
+            span,
+            "Mocked associated consts must have a default implementation",
+        );
+        (<Token![=]>::default(), Expr::Verbatim(TokenStream::new()))
+    });
+    ImplItemConst {
+        attrs: tic.attrs,
+        vis: vis.clone(),
+        defaultness: None,
+        const_token: tic.const_token,
+        ident: tic.ident,
+        colon_token: tic.colon_token,
+        ty: tic.ty,
+        eq_token,
+        expr,
+        semi_token: tic.semi_token,
+    }
+}
+
+/// Converts a TraitItemMethod into an ImplItemMethod
+fn tim2iim(m: syn::TraitItemMethod, vis: &syn::Visibility) -> syn::ImplItemMethod {
+    let empty_block = Block {
+        brace_token: token::Brace::default(),
+        stmts: Vec::new(),
+    };
+    syn::ImplItemMethod {
+        attrs: m.attrs,
+        vis: vis.clone(),
+        defaultness: None,
+        sig: m.sig,
+        block: empty_block,
+    }
+}
+
+/// Converts a TraitItemType into an ImplItemType
+fn tit2iit(tit: TraitItemType, vis: &Visibility) -> ImplItemType {
+    let span = tit.span();
+    let (eq_token, ty) = tit.default.unwrap_or_else(|| {
+        compile_error(span, "associated types in mock! must be fully specified");
+        (token::Eq::default(), Type::Verbatim(TokenStream::new()))
+    });
+    ImplItemType {
+        attrs: tit.attrs,
+        vis: vis.clone(),
+        defaultness: None,
+        type_token: tit.type_token,
+        ident: tit.ident,
+        generics: tit.generics,
+        eq_token,
+        ty,
+        semi_token: tit.semi_token,
+    }
+}
+
+pub(crate) struct MockableStruct {
+    pub attrs: Vec<Attribute>,
+    pub consts: Vec<ImplItemConst>,
+    pub generics: Generics,
+    /// Inherent methods of the mockable struct
+    pub methods: Vec<ImplItemMethod>,
+    pub name: Ident,
+    pub vis: Visibility,
+    pub impls: Vec<ItemImpl>,
+}
+
+impl MockableStruct {
+    /// Does this struct derive Debug?
+    pub fn derives_debug(&self) -> bool {
+        self.attrs.iter().any(|attr| {
+            if let Ok(Meta::List(ml)) = attr.parse_meta() {
+                let i = ml.path.get_ident();
+                if i.map_or(false, |i| *i == "derive") {
+                    ml.nested.iter().any(|nm| {
+                        if let NestedMeta::Meta(m) = nm {
+                            let i = m.path().get_ident();
+                            i.map_or(false, |i| *i == "Debug")
+                        } else {
+                            false
+                        }
+                    })
+                } else {
+                    false
+                }
+            } else {
+                false
+            }
+        })
+    }
+}
+
+impl From<(Attrs, ItemTrait)> for MockableStruct {
+    fn from((attrs, item_trait): (Attrs, ItemTrait)) -> MockableStruct {
+        let trait_ = attrs.substitute_trait(&item_trait);
+        let mut attrs = trait_.attrs.clone();
+        attrs.push(derive_debug());
+        let vis = trait_.vis.clone();
+        let name = gen_mock_ident(&trait_.ident);
+        let generics = trait_.generics.clone();
+        let impls = vec![mockable_trait(trait_, &name, &generics)];
+        MockableStruct {
+            attrs,
+            consts: Vec::new(),
+            vis,
+            name,
+            generics,
+            methods: Vec::new(),
+            impls,
+        }
+    }
+}
+
+impl From<ItemImpl> for MockableStruct {
+    fn from(mut item_impl: ItemImpl) -> MockableStruct {
+        let name = match &*item_impl.self_ty {
+            Type::Path(type_path) => {
+                let n = find_ident_from_path(&type_path.path).0;
+                gen_mock_ident(&n)
+            }
+            x => {
+                compile_error(
+                    x.span(),
+                    "mockall_derive only supports mocking traits and structs",
+                );
+                Ident::new("", Span::call_site())
+            }
+        };
+        let mut attrs = item_impl.attrs.clone();
+        attrs.push(derive_debug());
+        let mut consts = Vec::new();
+        let generics = item_impl.generics.clone();
+        let mut methods = Vec::new();
+        let pub_token = Token![pub](Span::call_site());
+        let vis = Visibility::Public(VisPublic { pub_token });
+        let mut impls = Vec::new();
+        if let Some((bang, _path, _)) = &item_impl.trait_ {
+            if bang.is_some() {
+                compile_error(bang.span(), "Unsupported by automock");
+            }
+
+            // Substitute any associated types in this ItemImpl.
+            // NB: this would not be necessary if the user always fully
+            // qualified them, e.g. `<Self as MyTrait>::MyType`
+            let mut attrs = Attrs::default();
+            for item in item_impl.items.iter() {
+                match item {
+                    ImplItem::Const(_iic) => (),
+                    ImplItem::Method(_meth) => (),
+                    ImplItem::Type(ty) => {
+                        attrs.attrs.insert(ty.ident.clone(), ty.ty.clone());
+                    }
+                    x => compile_error(x.span(), "Unsupported by automock"),
+                }
+            }
+            attrs.substitute_item_impl(&mut item_impl);
+            impls.push(mockable_item_impl(item_impl, &name, &generics));
+        } else {
+            for item in item_impl.items.into_iter() {
+                match item {
+                    ImplItem::Method(mut meth) => {
+                        mockable_method(&mut meth, &name, &item_impl.generics);
+                        methods.push(meth)
+                    }
+                    ImplItem::Const(iic) => consts.push(iic),
+                    // Rust doesn't allow types in an inherent impl
+                    x => compile_error(x.span(), "Unsupported by Mockall in this context"),
+                }
+            }
+        };
+        MockableStruct {
+            attrs,
+            consts,
+            generics,
+            methods,
+            name,
+            vis,
+            impls,
+        }
+    }
+}
+
+impl Parse for MockableStruct {
+    fn parse(input: ParseStream) -> syn::parse::Result<Self> {
+        let attrs = input.call(syn::Attribute::parse_outer)?;
+        let vis: syn::Visibility = input.parse()?;
+        let original_name: syn::Ident = input.parse()?;
+        let mut generics: syn::Generics = input.parse()?;
+        let wc: Option<syn::WhereClause> = input.parse()?;
+        generics.where_clause = wc;
+        let name = gen_mock_ident(&original_name);
+        let impl_content;
+        let _brace_token = braced!(impl_content in input);
+        let mut consts = Vec::new();
+        let mut methods = Vec::new();
+        while !impl_content.is_empty() {
+            let item: ImplItem = impl_content.parse()?;
+            match item {
+                ImplItem::Method(mut iim) => {
+                    mockable_method(&mut iim, &name, &generics);
+                    methods.push(iim);
+                }
+                ImplItem::Const(iic) => consts.push(iic),
+                _ => {
+                    return Err(input.error("Unsupported in this context"));
+                }
+            }
+        }
+
+        let mut impls = Vec::new();
+        while !input.is_empty() {
+            let item: Item = input.parse()?;
+            match item {
+                Item::Trait(it) => {
+                    let note = "Deprecated mock! syntax.  Instead of \"trait X\", write \"impl X for Y\".  See PR #205";
+                    let mut impl_ = mockable_trait(it, &name, &generics);
+                    impl_.attrs.push(Attribute {
+                        pound_token: <token::Pound>::default(),
+                        style: AttrStyle::Outer,
+                        bracket_token: token::Bracket::default(),
+                        path: Path::from(format_ident!("deprecated")),
+                        tokens: quote!((since = "0.9.0", note = #note)),
+                    });
+                    impls.push(impl_)
+                }
+                Item::Impl(ii) => impls.push(mockable_item_impl(ii, &name, &generics)),
+                _ => return Err(input.error("Unsupported in this context")),
+            }
+        }
+
+        Ok(MockableStruct {
+            attrs,
+            consts,
+            generics,
+            methods,
+            name,
+            vis,
+            impls,
+        })
+    }
+}
+
+#[cfg(test)]
+mod t {
+    use super::*;
+
+    mod add_lifetime_parameters {
+        use super::*;
+
+        #[test]
+        fn array() {
+            let mut meth: TraitItemMethod = parse2(quote!(
+                fn foo(&self, x: [&dyn T; 1]);
+            ))
+            .unwrap();
+            add_lifetime_parameters(&mut meth.sig);
+            assert_eq!(
+                quote!(
+                    fn foo<'__mockall_x>(&self, x: [&(dyn T + '__mockall_x); 1]);
+                )
+                .to_string(),
+                quote!(#meth).to_string()
+            );
+        }
+
+        #[test]
+        fn bare_fn_with_named_args() {
+            let mut meth: TraitItemMethod = parse2(quote!(
+                fn foo(&self, x: fn(&dyn T));
+            ))
+            .unwrap();
+            add_lifetime_parameters(&mut meth.sig);
+            assert_eq!(
+                quote!(
+                    fn foo(&self, x: fn(&dyn T));
+                )
+                .to_string(),
+                quote!(#meth).to_string()
+            );
+        }
+
+        #[test]
+        fn plain() {
+            let mut meth: TraitItemMethod = parse2(quote!(
+                fn foo(&self, x: &dyn T);
+            ))
+            .unwrap();
+            add_lifetime_parameters(&mut meth.sig);
+            assert_eq!(
+                quote!(
+                    fn foo<'__mockall_x>(&self, x: &(dyn T + '__mockall_x));
+                )
+                .to_string(),
+                quote!(#meth).to_string()
+            );
+        }
+
+        #[test]
+        fn slice() {
+            let mut meth: TraitItemMethod = parse2(quote!(
+                fn foo(&self, x: &[&dyn T]);
+            ))
+            .unwrap();
+            add_lifetime_parameters(&mut meth.sig);
+            assert_eq!(
+                quote!(
+                    fn foo<'__mockall_x>(&self, x: &[&(dyn T + '__mockall_x)]);
+                )
+                .to_string(),
+                quote!(#meth).to_string()
+            );
+        }
+
+        #[test]
+        fn tuple() {
+            let mut meth: TraitItemMethod = parse2(quote!(
+                fn foo(&self, x: (&dyn T, u32));
+            ))
+            .unwrap();
+            add_lifetime_parameters(&mut meth.sig);
+            assert_eq!(
+                quote!(
+                    fn foo<'__mockall_x>(&self, x: (&(dyn T + '__mockall_x), u32));
+                )
+                .to_string(),
+                quote!(#meth).to_string()
+            );
+        }
+
+        #[test]
+        fn with_anonymous_lifetime() {
+            let mut meth: TraitItemMethod = parse2(quote!(
+                fn foo(&self, x: &(dyn T + '_));
+            ))
+            .unwrap();
+            add_lifetime_parameters(&mut meth.sig);
+            assert_eq!(
+                quote!(
+                    fn foo(&self, x: &(dyn T + '_));
+                )
+                .to_string(),
+                quote!(#meth).to_string()
+            );
+        }
+
+        #[test]
+        fn with_parens() {
+            let mut meth: TraitItemMethod = parse2(quote!(
+                fn foo(&self, x: &(dyn T));
+            ))
+            .unwrap();
+            add_lifetime_parameters(&mut meth.sig);
+            assert_eq!(
+                quote!(
+                    fn foo<'__mockall_x>(&self, x: &(dyn T + '__mockall_x));
+                )
+                .to_string(),
+                quote!(#meth).to_string()
+            );
+        }
+
+        #[test]
+        fn with_lifetime_parameter() {
+            let mut meth: TraitItemMethod = parse2(quote!(
+                fn foo<'a>(&self, x: &(dyn T + 'a));
+            ))
+            .unwrap();
+            add_lifetime_parameters(&mut meth.sig);
+            assert_eq!(
+                quote!(
+                    fn foo<'a>(&self, x: &(dyn T + 'a));
+                )
+                .to_string(),
+                quote!(#meth).to_string()
+            );
+        }
+
+        #[test]
+        fn with_static_lifetime() {
+            let mut meth: TraitItemMethod = parse2(quote!(
+                fn foo(&self, x: &(dyn T + 'static));
+            ))
+            .unwrap();
+            add_lifetime_parameters(&mut meth.sig);
+            assert_eq!(
+                quote!(
+                    fn foo(&self, x: &(dyn T + 'static));
+                )
+                .to_string(),
+                quote!(#meth).to_string()
+            );
+        }
+    }
+
+    mod sanity_check_sig {
+        use super::*;
+
+        #[test]
+        #[should_panic(
+            expected = "Mockall does not support \"impl trait\" in argument position.  Use \"T: SomeTrait\" instead."
+        )]
+        fn impl_trait() {
+            let meth: ImplItemMethod = parse2(quote!(
+                fn foo(&self, x: impl SomeTrait);
+            ))
+            .unwrap();
+            sanity_check_sig(&meth.sig);
+        }
+    }
+}
