diff --git a/engine/Cargo.toml b/engine/Cargo.toml
new file mode 100644
index 0000000..964108e
--- /dev/null
+++ b/engine/Cargo.toml
@@ -0,0 +1,62 @@
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+# https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+# <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+# option. This file may not be copied, modified, or distributed
+# except according to those terms.
+
+[package]
+name = "autocxx-engine"
+version = "0.22.0"
+authors = ["Adrian Taylor <adetaylor@chromium.org>"]
+license = "MIT OR Apache-2.0"
+description = "Safe autogenerated interop between Rust and C++"
+repository = "https://github.com/google/autocxx"
+edition = "2021"
+keywords = ["ffi"]
+categories = ["development-tools::ffi", "api-bindings"]
+
+[features]
+default = [ "reproduction_case" ]
+build = ["cc"]
+nightly = [] # for doc generation purposes only; used by docs.rs
+reproduction_case = [ "serde_json", "autocxx-parser/reproduction_case" ]
+runtime = [ "autocxx-bindgen/runtime" ]
+static = [ "autocxx-bindgen/static" ]
+
+[dependencies]
+log = "0.4"
+proc-macro2 = "1.0.11"
+quote = "1.0"
+indoc = "1.0"
+autocxx-bindgen = "=0.59.16"
+#autocxx-bindgen = { git = "https://github.com/adetaylor/rust-bindgen", branch = "pollute-fewer-typedefs" }
+itertools = "0.10.3"
+cc = { version = "1.0", optional = true }
+# Note: Keep the patch-level version of cxx-gen and cxx in sync.
+# There can be interdependencies between the code generated by cxx-gen and
+# what cxx expects to be there.
+cxx-gen = "0.7.54"
+autocxx-parser = { version = "=0.22.0", path="../parser" }
+version_check = "0.9"
+aquamarine = "0.1" # docs
+tempfile = "3.1"
+once_cell = "1.7"
+strum_macros = "0.24"
+serde_json = { version = "1.0", optional = true }
+miette = "4.3"
+thiserror = "1"
+regex = "1.5"
+indexmap = "1.8"
+
+[dependencies.syn]
+version = "1.0.39"
+features = [ "full", "printing" ]
+#features = [ "full", "printing", "extra-traits" ]
+
+[package.metadata.docs.rs]
+features = ["build", "nightly"]
+
+[dev-dependencies]
+cc = "1.0"
diff --git a/engine/README.md b/engine/README.md
new file mode 100644
index 0000000..9b91d4a
--- /dev/null
+++ b/engine/README.md
@@ -0,0 +1 @@
+This crate is a [component of autocxx](https://google.github.io/autocxx/).
diff --git a/engine/src/ast_discoverer.rs b/engine/src/ast_discoverer.rs
new file mode 100644
index 0000000..8840899
--- /dev/null
+++ b/engine/src/ast_discoverer.rs
@@ -0,0 +1,726 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::set::IndexSet as HashSet;
+
+use autocxx_parser::{
+    directive_names::{EXTERN_RUST_FUN, EXTERN_RUST_TYPE},
+    RustFun, RustPath,
+};
+use itertools::Itertools;
+use proc_macro2::Ident;
+use syn::{
+    parse_quote, punctuated::Punctuated, Attribute, Binding, Expr, ExprAssign, ExprAssignOp,
+    ExprAwait, ExprBinary, ExprBox, ExprBreak, ExprCast, ExprField, ExprGroup, ExprLet, ExprParen,
+    ExprReference, ExprTry, ExprType, ExprUnary, ImplItem, Item, ItemEnum, ItemStruct, Pat, PatBox,
+    PatReference, PatSlice, PatTuple, Path, Receiver, ReturnType, Signature, Stmt, TraitItem, Type,
+    TypeArray, TypeGroup, TypeParamBound, TypeParen, TypePtr, TypeReference, TypeSlice,
+};
+use thiserror::Error;
+
+#[derive(Default)]
+pub(super) struct Discoveries {
+    pub(super) cpp_list: HashSet<String>,
+    pub(super) extern_rust_funs: Vec<RustFun>,
+    pub(super) extern_rust_types: Vec<RustPath>,
+}
+
+#[derive(Error, Debug)]
+pub enum DiscoveryErr {
+    #[error("#[extern_rust_function] was attached to a method in an impl block that was too complex for autocxx. autocxx supports only \"impl X {{...}}\" where X is a single identifier, not a path or more complex type.")]
+    FoundExternRustFunOnTypeWithoutClearReceiver,
+    #[error("#[extern_rust_function] was attached to a method taking no parameters.")]
+    NonReferenceReceiver,
+    #[error("#[extern_rust_function] was attached to a method taking a receiver by value.")]
+    NoParameterOnMethod,
+    #[error("#[extern_rust_function] was in an impl block nested wihtin another block. This is only supported in the outermost mod of a file, alongside the include_cpp!.")]
+    FoundExternRustFunWithinMod,
+}
+
+impl Discoveries {
+    pub(super) fn search_item(
+        &mut self,
+        item: &Item,
+        mod_path: Option<RustPath>,
+    ) -> Result<(), DiscoveryErr> {
+        let mut this_mod = PerModDiscoveries {
+            discoveries: self,
+            mod_path,
+        };
+        this_mod.search_item(item)
+    }
+
+    pub(crate) fn found_allowlist(&self) -> bool {
+        !self.cpp_list.is_empty()
+    }
+
+    pub(crate) fn found_rust(&self) -> bool {
+        !self.extern_rust_funs.is_empty() || !self.extern_rust_types.is_empty()
+    }
+
+    pub(crate) fn extend(&mut self, other: Self) {
+        self.cpp_list.extend(other.cpp_list);
+        self.extern_rust_funs.extend(other.extern_rust_funs);
+        self.extern_rust_types.extend(other.extern_rust_types);
+    }
+}
+
+struct PerModDiscoveries<'a> {
+    discoveries: &'a mut Discoveries,
+    mod_path: Option<RustPath>,
+}
+
+impl<'b> PerModDiscoveries<'b> {
+    fn deeper_path(&self, id: &Ident) -> RustPath {
+        match &self.mod_path {
+            None => RustPath::new_from_ident(id.clone()),
+            Some(mod_path) => mod_path.append(id.clone()),
+        }
+    }
+
+    fn search_item(&mut self, item: &Item) -> Result<(), DiscoveryErr> {
+        match item {
+            Item::Fn(fun) => {
+                for stmt in &fun.block.stmts {
+                    self.search_stmt(stmt)?
+                }
+                self.search_return_type(&fun.sig.output)?;
+                for i in &fun.sig.inputs {
+                    match i {
+                        syn::FnArg::Receiver(_) => {}
+                        syn::FnArg::Typed(pt) => {
+                            self.search_pat(&pt.pat)?;
+                            self.search_type(&pt.ty)?;
+                        }
+                    }
+                }
+                if Self::has_attr(&fun.attrs, EXTERN_RUST_FUN) {
+                    self.discoveries.extern_rust_funs.push(RustFun {
+                        path: self.deeper_path(&fun.sig.ident),
+                        sig: fun.sig.clone(),
+                        receiver: None,
+                    });
+                }
+            }
+            Item::Impl(imp) => {
+                let receiver = match imp.trait_ {
+                    // We do not allow 'extern_rust_fun' on trait impls
+                    Some(_) => None,
+                    None => match &*imp.self_ty {
+                        Type::Path(typ) => {
+                            let mut segs = typ.path.segments.iter();
+                            let id = segs.next();
+                            if let Some(seg) = id {
+                                if segs.next().is_some() {
+                                    None
+                                } else {
+                                    Some(self.deeper_path(&seg.ident))
+                                }
+                            } else {
+                                None
+                            }
+                        }
+                        _ => None,
+                    },
+                };
+                for item in &imp.items {
+                    self.search_impl_item(item, receiver.as_ref())?
+                }
+            }
+            Item::Mod(md) => {
+                if let Some((_, items)) = &md.content {
+                    let mod_path = Some(self.deeper_path(&md.ident));
+                    let mut new_mod = PerModDiscoveries {
+                        discoveries: self.discoveries,
+                        mod_path,
+                    };
+                    for item in items {
+                        new_mod.search_item(item)?
+                    }
+                }
+            }
+            Item::Trait(tr) => {
+                for item in &tr.items {
+                    self.search_trait_item(item)?
+                }
+            }
+            Item::Struct(ItemStruct { ident, attrs, .. })
+            | Item::Enum(ItemEnum { ident, attrs, .. })
+                if Self::has_attr(attrs, EXTERN_RUST_TYPE) =>
+            {
+                self.discoveries
+                    .extern_rust_types
+                    .push(self.deeper_path(ident));
+            }
+            _ => {}
+        }
+        Ok(())
+    }
+
+    fn search_path(&mut self, path: &Path) -> Result<(), DiscoveryErr> {
+        let mut seg_iter = path.segments.iter();
+        if let Some(first_seg) = seg_iter.next() {
+            if first_seg.ident == "ffi" {
+                self.discoveries
+                    .cpp_list
+                    .insert(seg_iter.map(|seg| seg.ident.to_string()).join("::"));
+            }
+        }
+        for seg in path.segments.iter() {
+            self.search_path_arguments(&seg.arguments)?;
+        }
+        Ok(())
+    }
+
+    fn search_trait_item(&mut self, itm: &TraitItem) -> Result<(), DiscoveryErr> {
+        if let TraitItem::Method(itm) = itm {
+            if let Some(block) = &itm.default {
+                self.search_stmts(block.stmts.iter())?
+            }
+        }
+        Ok(())
+    }
+
+    fn search_stmts<'a>(
+        &mut self,
+        stmts: impl Iterator<Item = &'a Stmt>,
+    ) -> Result<(), DiscoveryErr> {
+        for stmt in stmts {
+            self.search_stmt(stmt)?
+        }
+        Ok(())
+    }
+
+    fn search_stmt(&mut self, stmt: &Stmt) -> Result<(), DiscoveryErr> {
+        match stmt {
+            Stmt::Local(lcl) => {
+                if let Some((_, expr)) = &lcl.init {
+                    self.search_expr(expr)?
+                }
+                self.search_pat(&lcl.pat)
+            }
+            Stmt::Item(itm) => self.search_item(itm),
+            Stmt::Expr(exp) | Stmt::Semi(exp, _) => self.search_expr(exp),
+        }
+    }
+
+    fn search_expr(&mut self, expr: &Expr) -> Result<(), DiscoveryErr> {
+        match expr {
+            Expr::Path(exp) => {
+                self.search_path(&exp.path)?;
+            }
+            Expr::Macro(_) => {}
+            Expr::Array(array) => self.search_exprs(array.elems.iter())?,
+            Expr::Assign(ExprAssign { left, right, .. })
+            | Expr::AssignOp(ExprAssignOp { left, right, .. })
+            | Expr::Binary(ExprBinary { left, right, .. }) => {
+                self.search_expr(left)?;
+                self.search_expr(right)?;
+            }
+            Expr::Async(ass) => self.search_stmts(ass.block.stmts.iter())?,
+            Expr::Await(ExprAwait { base, .. }) | Expr::Field(ExprField { base, .. }) => {
+                self.search_expr(base)?
+            }
+            Expr::Block(blck) => self.search_stmts(blck.block.stmts.iter())?,
+            Expr::Box(ExprBox { expr, .. })
+            | Expr::Break(ExprBreak {
+                expr: Some(expr), ..
+            })
+            | Expr::Cast(ExprCast { expr, .. })
+            | Expr::Group(ExprGroup { expr, .. })
+            | Expr::Paren(ExprParen { expr, .. })
+            | Expr::Reference(ExprReference { expr, .. })
+            | Expr::Try(ExprTry { expr, .. })
+            | Expr::Type(ExprType { expr, .. })
+            | Expr::Unary(ExprUnary { expr, .. }) => self.search_expr(expr)?,
+            Expr::Call(exc) => {
+                self.search_expr(&exc.func)?;
+                self.search_exprs(exc.args.iter())?;
+            }
+            Expr::Closure(cls) => self.search_expr(&cls.body)?,
+            Expr::Continue(_)
+            | Expr::Lit(_)
+            | Expr::Break(ExprBreak { expr: None, .. })
+            | Expr::Verbatim(_) => {}
+            Expr::ForLoop(fl) => {
+                self.search_expr(&fl.expr)?;
+                self.search_stmts(fl.body.stmts.iter())?;
+            }
+            Expr::If(exif) => {
+                self.search_expr(&exif.cond)?;
+                self.search_stmts(exif.then_branch.stmts.iter())?;
+                if let Some((_, else_branch)) = &exif.else_branch {
+                    self.search_expr(else_branch)?;
+                }
+            }
+            Expr::Index(exidx) => {
+                self.search_expr(&exidx.expr)?;
+                self.search_expr(&exidx.index)?;
+            }
+            Expr::Let(ExprLet { expr, pat, .. }) => {
+                self.search_expr(expr)?;
+                self.search_pat(pat)?;
+            }
+            Expr::Loop(exloo) => self.search_stmts(exloo.body.stmts.iter())?,
+            Expr::Match(exm) => {
+                self.search_expr(&exm.expr)?;
+                for a in &exm.arms {
+                    self.search_expr(&a.body)?;
+                    if let Some((_, guard)) = &a.guard {
+                        self.search_expr(guard)?;
+                    }
+                }
+            }
+            Expr::MethodCall(mtc) => {
+                self.search_expr(&mtc.receiver)?;
+                self.search_exprs(mtc.args.iter())?;
+            }
+            Expr::Range(exr) => {
+                self.search_option_expr(&exr.from)?;
+                self.search_option_expr(&exr.to)?;
+            }
+            Expr::Repeat(exr) => {
+                self.search_expr(&exr.expr)?;
+                self.search_expr(&exr.len)?;
+            }
+            Expr::Return(exret) => {
+                if let Some(expr) = &exret.expr {
+                    self.search_expr(expr)?;
+                }
+            }
+            Expr::Struct(exst) => {
+                for f in &exst.fields {
+                    self.search_expr(&f.expr)?;
+                }
+                self.search_option_expr(&exst.rest)?;
+            }
+            Expr::TryBlock(extb) => self.search_stmts(extb.block.stmts.iter())?,
+            Expr::Tuple(ext) => self.search_exprs(ext.elems.iter())?,
+            Expr::Unsafe(exs) => self.search_stmts(exs.block.stmts.iter())?,
+            Expr::While(exw) => {
+                self.search_expr(&exw.cond)?;
+                self.search_stmts(exw.body.stmts.iter())?;
+            }
+            Expr::Yield(exy) => self.search_option_expr(&exy.expr)?,
+            _ => {}
+        }
+        Ok(())
+    }
+
+    fn search_option_expr(&mut self, expr: &Option<Box<Expr>>) -> Result<(), DiscoveryErr> {
+        if let Some(expr) = &expr {
+            self.search_expr(expr)?;
+        }
+        Ok(())
+    }
+
+    fn search_exprs<'a>(
+        &mut self,
+        exprs: impl Iterator<Item = &'a Expr>,
+    ) -> Result<(), DiscoveryErr> {
+        for e in exprs {
+            self.search_expr(e)?;
+        }
+        Ok(())
+    }
+
+    fn search_impl_item(
+        &mut self,
+        impl_item: &ImplItem,
+        receiver: Option<&RustPath>,
+    ) -> Result<(), DiscoveryErr> {
+        if let ImplItem::Method(itm) = impl_item {
+            if Self::has_attr(&itm.attrs, EXTERN_RUST_FUN) {
+                if self.mod_path.is_some() {
+                    return Err(DiscoveryErr::FoundExternRustFunWithinMod);
+                }
+                if let Some(receiver) = receiver {
+                    // We have a method which we want to put into the cxx::bridge's
+                    // "extern Rust" block.
+                    let sig = add_receiver(&itm.sig, receiver.get_final_ident())?;
+                    assert!(receiver.len() == 1);
+                    self.discoveries.extern_rust_funs.push(RustFun {
+                        path: self.deeper_path(&itm.sig.ident),
+                        sig,
+                        receiver: Some(receiver.get_final_ident().clone()),
+                    });
+                    self.discoveries.extern_rust_types.push(receiver.clone())
+                } else {
+                    return Err(DiscoveryErr::FoundExternRustFunOnTypeWithoutClearReceiver);
+                }
+            }
+            for stmt in &itm.block.stmts {
+                self.search_stmt(stmt)?
+            }
+        }
+        Ok(())
+    }
+
+    fn search_pat(&mut self, pat: &Pat) -> Result<(), DiscoveryErr> {
+        match pat {
+            Pat::Box(PatBox { pat, .. }) | Pat::Reference(PatReference { pat, .. }) => {
+                self.search_pat(pat)
+            }
+            Pat::Ident(_) | Pat::Lit(_) | Pat::Macro(_) | Pat::Range(_) | Pat::Rest(_) => Ok(()),
+            Pat::Or(pator) => {
+                for case in &pator.cases {
+                    self.search_pat(case)?;
+                }
+                Ok(())
+            }
+            Pat::Path(pp) => self.search_path(&pp.path),
+            Pat::Slice(PatSlice { elems, .. }) | Pat::Tuple(PatTuple { elems, .. }) => {
+                for case in elems {
+                    self.search_pat(case)?;
+                }
+                Ok(())
+            }
+            Pat::Struct(ps) => {
+                self.search_path(&ps.path)?;
+                for f in &ps.fields {
+                    self.search_pat(&f.pat)?;
+                }
+                Ok(())
+            }
+            Pat::TupleStruct(tps) => {
+                self.search_path(&tps.path)?;
+                for f in &tps.pat.elems {
+                    self.search_pat(f)?;
+                }
+                Ok(())
+            }
+            Pat::Type(pt) => {
+                self.search_pat(&pt.pat)?;
+                self.search_type(&pt.ty)
+            }
+            _ => Ok(()),
+        }
+    }
+
+    fn search_type(&mut self, ty: &Type) -> Result<(), DiscoveryErr> {
+        match ty {
+            Type::Array(TypeArray { elem, .. })
+            | Type::Group(TypeGroup { elem, .. })
+            | Type::Paren(TypeParen { elem, .. })
+            | Type::Ptr(TypePtr { elem, .. })
+            | Type::Reference(TypeReference { elem, .. })
+            | Type::Slice(TypeSlice { elem, .. }) => self.search_type(elem)?,
+            Type::BareFn(tf) => {
+                for input in &tf.inputs {
+                    self.search_type(&input.ty)?;
+                }
+                self.search_return_type(&tf.output)?;
+            }
+            Type::ImplTrait(tyit) => {
+                for b in &tyit.bounds {
+                    if let syn::TypeParamBound::Trait(tyt) = b {
+                        self.search_path(&tyt.path)?
+                    }
+                }
+            }
+            Type::Infer(_) | Type::Macro(_) | Type::Never(_) => {}
+            Type::Path(typ) => self.search_path(&typ.path)?,
+            Type::TraitObject(tto) => self.search_type_param_bounds(&tto.bounds)?,
+            Type::Tuple(tt) => {
+                for e in &tt.elems {
+                    self.search_type(e)?
+                }
+            }
+            _ => {}
+        }
+        Ok(())
+    }
+
+    fn search_type_param_bounds(
+        &mut self,
+        bounds: &Punctuated<TypeParamBound, syn::token::Add>,
+    ) -> Result<(), DiscoveryErr> {
+        for b in bounds {
+            if let syn::TypeParamBound::Trait(tpbt) = b {
+                self.search_path(&tpbt.path)?
+            }
+        }
+        Ok(())
+    }
+
+    fn search_return_type(&mut self, output: &ReturnType) -> Result<(), DiscoveryErr> {
+        if let ReturnType::Type(_, ty) = &output {
+            self.search_type(ty)
+        } else {
+            Ok(())
+        }
+    }
+
+    fn search_path_arguments(
+        &mut self,
+        arguments: &syn::PathArguments,
+    ) -> Result<(), DiscoveryErr> {
+        match arguments {
+            syn::PathArguments::None => {}
+            syn::PathArguments::AngleBracketed(paab) => {
+                for arg in &paab.args {
+                    match arg {
+                        syn::GenericArgument::Lifetime(_) => {}
+                        syn::GenericArgument::Type(ty)
+                        | syn::GenericArgument::Binding(Binding { ty, .. }) => {
+                            self.search_type(ty)?
+                        }
+                        syn::GenericArgument::Constraint(c) => {
+                            self.search_type_param_bounds(&c.bounds)?
+                        }
+                        syn::GenericArgument::Const(c) => self.search_expr(c)?,
+                    }
+                }
+            }
+            syn::PathArguments::Parenthesized(pas) => {
+                self.search_return_type(&pas.output)?;
+                for t in &pas.inputs {
+                    self.search_type(t)?;
+                }
+            }
+        }
+        Ok(())
+    }
+
+    fn has_attr(attrs: &[Attribute], attr_name: &str) -> bool {
+        attrs.iter().any(|attr| {
+            attr.path
+                .segments
+                .last()
+                .map(|seg| seg.ident == attr_name)
+                .unwrap_or_default()
+        })
+    }
+}
+
+/// Take a method signature that may be `fn a(&self)`
+/// and turn it into `fn a(self: &A)` which is what we will
+/// need to specify to cxx.
+fn add_receiver(sig: &Signature, receiver: &Ident) -> Result<Signature, DiscoveryErr> {
+    let mut sig = sig.clone();
+    match sig.inputs.iter_mut().next() {
+        Some(first_arg) => match first_arg {
+            syn::FnArg::Receiver(Receiver {
+                reference: Some(_),
+                mutability: Some(_),
+                ..
+            }) => {
+                *first_arg = parse_quote! {
+                    self: &mut #receiver
+                }
+            }
+            syn::FnArg::Receiver(Receiver {
+                reference: Some(_),
+                mutability: None,
+                ..
+            }) => {
+                *first_arg = parse_quote! {
+                    self: &#receiver
+                }
+            }
+            syn::FnArg::Receiver(..) => return Err(DiscoveryErr::NonReferenceReceiver),
+            syn::FnArg::Typed(_) => {}
+        },
+        None => return Err(DiscoveryErr::NoParameterOnMethod),
+    }
+    Ok(sig)
+}
+
+#[cfg(test)]
+mod tests {
+    use quote::{quote, ToTokens};
+    use syn::{parse_quote, ImplItemMethod};
+
+    use crate::{ast_discoverer::add_receiver, types::make_ident};
+
+    use super::Discoveries;
+
+    fn assert_cpp_found(discoveries: &Discoveries) {
+        assert!(!discoveries.cpp_list.is_empty());
+        assert!(discoveries.cpp_list.iter().next().unwrap() == "xxx");
+    }
+
+    #[test]
+    fn test_mod_plain_call() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            mod foo {
+                fn bar() {
+                    ffi::xxx()
+                }
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_plain_call() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                ffi::xxx()
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_plain_call_with_semi() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                ffi::xxx();
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_in_ns() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                ffi::a::b::xxx();
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert!(!discoveries.cpp_list.is_empty());
+        assert!(discoveries.cpp_list.iter().next().unwrap() == "a::b::xxx");
+    }
+
+    #[test]
+    fn test_deep_nested_thingy() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                a + 3 * foo(ffi::xxx());
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_ty_in_let() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar() {
+                let foo: ffi::xxx = bar();
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_ty_in_fn() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar(a: &mut ffi::xxx) {
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_ty_in_fn_up() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            fn bar(a: cxx::UniquePtr<ffi::xxx>) {
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert_cpp_found(&discoveries);
+    }
+
+    #[test]
+    fn test_extern_rust_fun() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            #[autocxx::extern_rust::extern_rust_function]
+            fn bar(a: cxx::UniquePtr<ffi::xxx>) {
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert!(discoveries.extern_rust_funs.get(0).unwrap().sig.ident == "bar");
+    }
+
+    #[test]
+    fn test_extern_rust_method() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            impl A {
+                #[autocxx::extern_rust::extern_rust_function]
+                fn bar(&self) {
+                }
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert!(discoveries.extern_rust_funs.get(0).unwrap().sig.ident == "bar");
+    }
+
+    #[test]
+    fn test_extern_rust_ty() {
+        let mut discoveries = Discoveries::default();
+        let itm = parse_quote! {
+            #[autocxx::extern_rust::extern_rust_type]
+            struct Bar {
+
+            }
+        };
+        discoveries.search_item(&itm, None).unwrap();
+        assert!(
+            discoveries
+                .extern_rust_types
+                .get(0)
+                .unwrap()
+                .get_final_ident()
+                == "Bar"
+        );
+    }
+
+    #[test]
+    fn test_add_receiver() {
+        let meth: ImplItemMethod = parse_quote! {
+            fn a(&self) {}
+        };
+        let a = make_ident("A");
+        assert_eq!(
+            add_receiver(&meth.sig, &a)
+                .unwrap()
+                .to_token_stream()
+                .to_string(),
+            quote! { fn a(self: &A) }.to_string()
+        );
+
+        let meth: ImplItemMethod = parse_quote! {
+            fn a(&mut self, b: u32) -> Foo {}
+        };
+        assert_eq!(
+            add_receiver(&meth.sig, &a)
+                .unwrap()
+                .to_token_stream()
+                .to_string(),
+            quote! { fn a(self: &mut A, b: u32) -> Foo }.to_string()
+        );
+
+        let meth: ImplItemMethod = parse_quote! {
+            fn a(self) {}
+        };
+        assert!(add_receiver(&meth.sig, &a).is_err());
+
+        let meth: ImplItemMethod = parse_quote! {
+            fn a() {}
+        };
+        assert!(add_receiver(&meth.sig, &a).is_err());
+    }
+}
diff --git a/engine/src/builder.rs b/engine/src/builder.rs
new file mode 100644
index 0000000..d0b5199
--- /dev/null
+++ b/engine/src/builder.rs
@@ -0,0 +1,301 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use autocxx_parser::file_locations::FileLocationStrategy;
+use miette::Diagnostic;
+use thiserror::Error;
+
+use crate::generate_rs_single;
+use crate::{strip_system_headers, CppCodegenOptions, ParseError, RebuildDependencyRecorder};
+use std::ffi::OsStr;
+use std::ffi::OsString;
+use std::fs::File;
+use std::io::Write;
+use std::marker::PhantomData;
+use std::path::{Path, PathBuf};
+
+/// Errors returned during creation of a [`cc::Build`] from an include_cxx
+/// macro.
+#[derive(Error, Diagnostic, Debug)]
+#[cfg_attr(feature = "nightly", doc(cfg(feature = "build")))]
+pub enum BuilderError {
+    #[error("cxx couldn't handle our generated bindings - could be a bug in autocxx: {0}")]
+    InvalidCxx(cxx_gen::Error),
+    #[error(transparent)]
+    #[diagnostic(transparent)]
+    ParseError(ParseError),
+    #[error("we couldn't write the generated code to disk at {1}: {0}")]
+    FileWriteFail(std::io::Error, PathBuf),
+    #[error("no include_cpp! macro was found")]
+    NoIncludeCxxMacrosFound,
+    #[error("could not create a directory {1}: {0}")]
+    UnableToCreateDirectory(std::io::Error, PathBuf),
+}
+
+#[cfg_attr(feature = "nightly", doc(cfg(feature = "build")))]
+pub type BuilderBuild = cc::Build;
+
+/// For test purposes only, a [`cc::Build`] and lists of Rust and C++
+/// files generated.
+#[cfg_attr(feature = "nightly", doc(cfg(feature = "build")))]
+pub struct BuilderSuccess(pub BuilderBuild, pub Vec<PathBuf>, pub Vec<PathBuf>);
+
+/// Results of a build.
+#[cfg_attr(feature = "nightly", doc(cfg(feature = "build")))]
+pub type BuilderResult = Result<BuilderSuccess, BuilderError>;
+
+/// The context in which a builder object lives. Callbacks for various
+/// purposes.
+#[cfg_attr(feature = "nightly", doc(cfg(feature = "build")))]
+pub trait BuilderContext {
+    /// Perform any initialization specific to the context in which this
+    /// builder lives.
+    fn setup() {}
+
+    /// Create a dependency recorder, if any.
+    fn get_dependency_recorder() -> Option<Box<dyn RebuildDependencyRecorder>>;
+}
+
+/// An object to allow building of bindings from a `build.rs` file.
+///
+/// It would be unusual to use this directly - see the `autocxx_build` or
+/// `autocxx_gen` crates.
+#[cfg_attr(feature = "nightly", doc(cfg(feature = "build")))]
+pub struct Builder<'a, BuilderContext> {
+    rs_file: PathBuf,
+    autocxx_incs: Vec<OsString>,
+    extra_clang_args: Vec<String>,
+    dependency_recorder: Option<Box<dyn RebuildDependencyRecorder>>,
+    custom_gendir: Option<PathBuf>,
+    auto_allowlist: bool,
+    cpp_codegen_options: CppCodegenOptions<'a>,
+    // This member is to ensure that this type is parameterized
+    // by a BuilderContext. The goal is to balance three needs:
+    // (1) have most of the functionality over in autocxx_engine,
+    // (2) expose this type to users of autocxx_build and to
+    //     make it easy for callers simply to call Builder::new,
+    // (3) ensure that such a Builder does a few tasks specific to its use
+    // in a cargo environment.
+    ctx: PhantomData<BuilderContext>,
+}
+
+impl<CTX: BuilderContext> Builder<'_, CTX> {
+    /// Create a new Builder object. You'll need to pass in the Rust file
+    /// which contains the bindings (typically an `include_cpp!` macro
+    /// though `autocxx` can also handle manually-crafted `cxx::bridge`
+    /// bindings), and a list of include directories which should be searched
+    /// by autocxx as it tries to hunt for the include files specified
+    /// within the `include_cpp!` macro.
+    ///
+    /// Usually after this you'd call [`build`].
+    pub fn new(
+        rs_file: impl AsRef<Path>,
+        autocxx_incs: impl IntoIterator<Item = impl AsRef<OsStr>>,
+    ) -> Self {
+        CTX::setup();
+        Self {
+            rs_file: rs_file.as_ref().to_path_buf(),
+            autocxx_incs: autocxx_incs
+                .into_iter()
+                .map(|s| s.as_ref().to_os_string())
+                .collect(),
+            extra_clang_args: Vec::new(),
+            dependency_recorder: CTX::get_dependency_recorder(),
+            custom_gendir: None,
+            auto_allowlist: false,
+            cpp_codegen_options: CppCodegenOptions::default(),
+            ctx: PhantomData,
+        }
+    }
+
+    /// Specify extra arguments for clang.
+    pub fn extra_clang_args(mut self, extra_clang_args: &[&str]) -> Self {
+        self.extra_clang_args = extra_clang_args.iter().map(|s| s.to_string()).collect();
+        self
+    }
+
+    /// Where to generate the code.
+    pub fn custom_gendir(mut self, custom_gendir: PathBuf) -> Self {
+        self.custom_gendir = Some(custom_gendir);
+        self
+    }
+
+    /// Update C++ code generation options. See [`CppCodegenOptions`] for details.
+    pub fn cpp_codegen_options<F>(mut self, modifier: F) -> Self
+    where
+        F: FnOnce(&mut CppCodegenOptions),
+    {
+        modifier(&mut self.cpp_codegen_options);
+        self
+    }
+
+    /// Automatically discover uses of the C++ `ffi` mod and generate the allowlist
+    /// from that.
+    /// This is a highly experimental option, not currently recommended.
+    /// It doesn't work in the following cases:
+    /// * Static function calls on types within the FFI mod.
+    /// * Anything inside a macro invocation.
+    /// * You're using a different name for your `ffi` mod
+    /// * You're using multiple FFI mods
+    /// * You've got usages scattered across files beyond that with the
+    ///   `include_cpp` invocation
+    /// * You're using `use` statements to rename mods or items. If this
+    /// proves to be a promising or helpful direction, autocxx would be happy
+    /// to accept pull requests to remove some of these limitations.
+    pub fn auto_allowlist(mut self, do_it: bool) -> Self {
+        self.auto_allowlist = do_it;
+        self
+    }
+
+    /// Whether to suppress inclusion of system headers (`memory`, `string` etc.)
+    /// from generated C++ bindings code. This should not normally be used,
+    /// but can occasionally be useful if you're reducing a test case and you
+    /// have a preprocessed header file which already contains absolutely everything
+    /// that the bindings could ever need.
+    pub fn suppress_system_headers(mut self, do_it: bool) -> Self {
+        self.cpp_codegen_options.suppress_system_headers = do_it;
+        self
+    }
+
+    /// An annotation optionally to include on each C++ function.
+    /// For example to export the symbol from a library.
+    pub fn cxx_impl_annotations(mut self, cxx_impl_annotations: Option<String>) -> Self {
+        self.cpp_codegen_options.cxx_impl_annotations = cxx_impl_annotations;
+        self
+    }
+
+    /// Build autocxx C++ files and return a [`cc::Build`] you can use to build
+    /// more from a build.rs file.
+    ///
+    /// The error type returned by this function supports [`miette::Diagnostic`],
+    /// so if you use the `miette` crate and its `fancy` feature, then simply
+    /// return a `miette::Result` from your main function, you should get nicely
+    /// printed diagnostics.
+    pub fn build(self) -> Result<BuilderBuild, BuilderError> {
+        self.build_listing_files().map(|r| r.0)
+    }
+
+    /// For use in tests only, this does the build and returns additional information
+    /// about the files generated which can subsequently be examined for correctness.
+    /// In production, please use simply [`build`].
+    pub fn build_listing_files(self) -> Result<BuilderSuccess, BuilderError> {
+        let clang_args = &self
+            .extra_clang_args
+            .iter()
+            .map(|s| &s[..])
+            .collect::<Vec<_>>();
+        rust_version_check();
+        let gen_location_strategy = match self.custom_gendir {
+            None => FileLocationStrategy::new(),
+            Some(custom_dir) => FileLocationStrategy::Custom(custom_dir),
+        };
+        let incdir = gen_location_strategy.get_include_dir();
+        ensure_created(&incdir)?;
+        let cxxdir = gen_location_strategy.get_cxx_dir();
+        ensure_created(&cxxdir)?;
+        let rsdir = gen_location_strategy.get_rs_dir();
+        ensure_created(&rsdir)?;
+        // We are incredibly unsophisticated in our directory arrangement here
+        // compared to cxx. I have no doubt that we will need to replicate just
+        // about everything cxx does, in due course...
+        // Write cxx.h to that location, as it may be needed by
+        // some of our generated code.
+        write_to_file(
+            &incdir,
+            "cxx.h",
+            &Self::get_cxx_header_bytes(self.cpp_codegen_options.suppress_system_headers),
+        )?;
+
+        let autocxx_inc = build_autocxx_inc(self.autocxx_incs, &incdir);
+        gen_location_strategy.set_cargo_env_vars_for_build();
+
+        let mut parsed_file = crate::parse_file(self.rs_file, self.auto_allowlist)
+            .map_err(BuilderError::ParseError)?;
+        parsed_file
+            .resolve_all(
+                autocxx_inc,
+                clang_args,
+                self.dependency_recorder,
+                &self.cpp_codegen_options,
+            )
+            .map_err(BuilderError::ParseError)?;
+        let mut counter = 0;
+        let mut builder = cc::Build::new();
+        builder.cpp(true);
+        if std::env::var_os("AUTOCXX_ASAN").is_some() {
+            builder.flag_if_supported("-fsanitize=address");
+        }
+        let mut generated_rs = Vec::new();
+        let mut generated_cpp = Vec::new();
+        builder.includes(parsed_file.include_dirs());
+        for include_cpp in parsed_file.get_cpp_buildables() {
+            let generated_code = include_cpp
+                .generate_h_and_cxx(&self.cpp_codegen_options)
+                .map_err(BuilderError::InvalidCxx)?;
+            for filepair in generated_code.0 {
+                let fname = format!("gen{}.cxx", counter);
+                counter += 1;
+                if let Some(implementation) = &filepair.implementation {
+                    let gen_cxx_path = write_to_file(&cxxdir, &fname, implementation)?;
+                    builder.file(&gen_cxx_path);
+                    generated_cpp.push(gen_cxx_path);
+                }
+                write_to_file(&incdir, &filepair.header_name, &filepair.header)?;
+                generated_cpp.push(incdir.join(filepair.header_name));
+            }
+        }
+
+        for rs_output in parsed_file.get_rs_outputs() {
+            let rs = generate_rs_single(rs_output);
+            generated_rs.push(write_to_file(&rsdir, &rs.filename, rs.code.as_bytes())?);
+        }
+        if counter == 0 {
+            Err(BuilderError::NoIncludeCxxMacrosFound)
+        } else {
+            Ok(BuilderSuccess(builder, generated_rs, generated_cpp))
+        }
+    }
+
+    fn get_cxx_header_bytes(suppress_system_headers: bool) -> Vec<u8> {
+        strip_system_headers(crate::HEADER.as_bytes().to_vec(), suppress_system_headers)
+    }
+}
+
+fn ensure_created(dir: &Path) -> Result<(), BuilderError> {
+    std::fs::create_dir_all(dir)
+        .map_err(|e| BuilderError::UnableToCreateDirectory(e, dir.to_path_buf()))
+}
+
+fn build_autocxx_inc<I, T>(paths: I, extra_path: &Path) -> Vec<PathBuf>
+where
+    I: IntoIterator<Item = T>,
+    T: AsRef<OsStr>,
+{
+    paths
+        .into_iter()
+        .map(|p| PathBuf::from(p.as_ref()))
+        .chain(std::iter::once(extra_path.to_path_buf()))
+        .collect()
+}
+
+fn write_to_file(dir: &Path, filename: &str, content: &[u8]) -> Result<PathBuf, BuilderError> {
+    let path = dir.join(filename);
+    try_write_to_file(&path, content).map_err(|e| BuilderError::FileWriteFail(e, path.clone()))?;
+    Ok(path)
+}
+
+fn try_write_to_file(path: &Path, content: &[u8]) -> std::io::Result<()> {
+    let mut f = File::create(path)?;
+    f.write_all(content)
+}
+
+fn rust_version_check() {
+    if !version_check::is_min_version("1.54.0").unwrap_or(false) {
+        panic!("Rust 1.54 or later is required.")
+    }
+}
diff --git a/engine/src/conversion/analysis/abstract_types.rs b/engine/src/conversion/analysis/abstract_types.rs
new file mode 100644
index 0000000..dac9684
--- /dev/null
+++ b/engine/src/conversion/analysis/abstract_types.rs
@@ -0,0 +1,174 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::{
+    fun::{
+        FnAnalysis, FnKind, FnPhase, FnPrePhase2, MethodKind, PodAndConstructorAnalysis,
+        TraitMethodKind,
+    },
+    pod::PodAnalysis,
+};
+use crate::conversion::{api::Api, apivec::ApiVec};
+use crate::conversion::{
+    api::TypeKind,
+    error_reporter::{convert_apis, convert_item_apis},
+    ConvertError,
+};
+use indexmap::set::IndexSet as HashSet;
+
+/// Spot types with pure virtual functions and mark them abstract.
+pub(crate) fn mark_types_abstract(mut apis: ApiVec<FnPrePhase2>) -> ApiVec<FnPrePhase2> {
+    let mut abstract_types: HashSet<_> = apis
+        .iter()
+        .filter_map(|api| match &api {
+            Api::Function {
+                analysis:
+                    FnAnalysis {
+                        kind:
+                            FnKind::Method {
+                                impl_for: self_ty_name,
+                                method_kind: MethodKind::PureVirtual(_),
+                                ..
+                            },
+                        ..
+                    },
+                ..
+            } => Some(self_ty_name.clone()),
+            _ => None,
+        })
+        .collect();
+
+    // Spot any derived classes (recursively). Also, any types which have a base
+    // class that's not on the allowlist are presumed to be abstract, because we
+    // have no way of knowing (as they're not on the allowlist, there will be
+    // no methods associated so we won't be able to spot pure virtual methods).
+    let mut iterate = true;
+    while iterate {
+        iterate = false;
+        apis = apis
+            .into_iter()
+            .map(|api| {
+                match api {
+                    Api::Struct {
+                        analysis:
+                            PodAndConstructorAnalysis {
+                                pod:
+                                    PodAnalysis {
+                                        bases,
+                                        kind: TypeKind::Pod | TypeKind::NonPod,
+                                        castable_bases,
+                                        field_deps,
+                                        field_info,
+                                        is_generic,
+                                        in_anonymous_namespace,
+                                    },
+                                constructors,
+                            },
+                        name,
+                        details,
+                    } if abstract_types.contains(&name.name)
+                        || !abstract_types.is_disjoint(&bases) =>
+                    {
+                        abstract_types.insert(name.name.clone());
+                        // Recurse in case there are further dependent types
+                        iterate = true;
+                        Api::Struct {
+                            analysis: PodAndConstructorAnalysis {
+                                pod: PodAnalysis {
+                                    bases,
+                                    kind: TypeKind::Abstract,
+                                    castable_bases,
+                                    field_deps,
+                                    field_info,
+                                    is_generic,
+                                    in_anonymous_namespace,
+                                },
+                                constructors,
+                            },
+                            name,
+                            details,
+                        }
+                    }
+                    _ => api,
+                }
+            })
+            .collect()
+    }
+
+    // We also need to remove any constructors belonging to these
+    // abstract types.
+    apis.retain(|api| {
+        !matches!(&api,
+        Api::Function {
+            analysis:
+                FnAnalysis {
+                    kind: FnKind::Method{impl_for: self_ty, method_kind: MethodKind::Constructor{..}, ..}
+                        | FnKind::TraitMethod{ kind: TraitMethodKind::CopyConstructor | TraitMethodKind::MoveConstructor, impl_for: self_ty, ..},
+                    ..
+                },
+                ..
+        } if abstract_types.contains(self_ty))
+    });
+
+    // Finally, if there are any types which are nested inside other types,
+    // they can't be abstract. This is due to two small limitations in cxx.
+    // Imagine we have class Foo { class Bar }
+    // 1) using "type Foo = super::bindgen::root::Foo_Bar" results
+    //    in the creation of std::unique_ptr code which isn't acceptable
+    //    for an abtract class
+    // 2) using "type Foo;" isn't possible unless Foo is a top-level item
+    //    within its namespace. Any outer names will be interpreted as namespace
+    //    names and result in cxx generating "namespace Foo { class Bar }"".
+    let mut results = ApiVec::new();
+    convert_item_apis(apis, &mut results, |api| match api {
+        Api::Struct {
+            analysis:
+                PodAndConstructorAnalysis {
+                    pod:
+                        PodAnalysis {
+                            kind: TypeKind::Abstract,
+                            ..
+                        },
+                    ..
+                },
+            ..
+        } if api
+            .cpp_name()
+            .as_ref()
+            .map(|n| n.contains("::"))
+            .unwrap_or_default() =>
+        {
+            Err(ConvertError::AbstractNestedType)
+        }
+        _ => Ok(Box::new(std::iter::once(api))),
+    });
+    results
+}
+
+pub(crate) fn discard_ignored_functions(apis: ApiVec<FnPhase>) -> ApiVec<FnPhase> {
+    // Some APIs can't be generated, e.g. because they're protected.
+    // Now we've finished analyzing abstract types and constructors, we'll
+    // convert them to IgnoredItems.
+    let mut apis_new = ApiVec::new();
+    convert_apis(
+        apis,
+        &mut apis_new,
+        |name, fun, analysis| {
+            analysis.ignore_reason.clone()?;
+            Ok(Box::new(std::iter::once(Api::Function {
+                name,
+                fun,
+                analysis,
+            })))
+        },
+        Api::struct_unchanged,
+        Api::enum_unchanged,
+        Api::typedef_unchanged,
+    );
+    apis_new
+}
diff --git a/engine/src/conversion/analysis/allocators.rs b/engine/src/conversion/analysis/allocators.rs
new file mode 100644
index 0000000..3695de0
--- /dev/null
+++ b/engine/src/conversion/analysis/allocators.rs
@@ -0,0 +1,111 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Code to create functions to alloc and free while unitialized.
+
+use syn::{parse_quote, punctuated::Punctuated, token::Comma, FnArg, ReturnType};
+
+use crate::{
+    conversion::{
+        api::{Api, ApiName, CppVisibility, FuncToConvert, Provenance, References, TraitSynthesis},
+        apivec::ApiVec,
+    },
+    types::{make_ident, QualifiedName},
+};
+
+use super::{
+    fun::function_wrapper::{CppFunctionBody, CppFunctionKind},
+    pod::PodPhase,
+};
+
+pub(crate) fn create_alloc_and_frees(apis: ApiVec<PodPhase>) -> ApiVec<PodPhase> {
+    apis.into_iter()
+        .flat_map(|api| -> Box<dyn Iterator<Item = Api<PodPhase>>> {
+            match &api {
+                Api::Struct { name, .. } => {
+                    Box::new(create_alloc_and_free(name.name.clone()).chain(std::iter::once(api)))
+                }
+                Api::Subclass { name, .. } => {
+                    Box::new(create_alloc_and_free(name.cpp()).chain(std::iter::once(api)))
+                }
+                _ => Box::new(std::iter::once(api)),
+            }
+        })
+        .collect()
+}
+
+fn create_alloc_and_free(ty_name: QualifiedName) -> impl Iterator<Item = Api<PodPhase>> {
+    let typ = ty_name.to_type_path();
+    let free_inputs: Punctuated<FnArg, Comma> = parse_quote! {
+        arg0: *mut #typ
+    };
+    let alloc_return: ReturnType = parse_quote! {
+        -> *mut #typ
+    };
+    [
+        (
+            TraitSynthesis::AllocUninitialized(ty_name.clone()),
+            get_alloc_name(&ty_name),
+            Punctuated::new(),
+            alloc_return,
+            CppFunctionBody::AllocUninitialized(ty_name.clone()),
+        ),
+        (
+            TraitSynthesis::FreeUninitialized(ty_name.clone()),
+            get_free_name(&ty_name),
+            free_inputs,
+            ReturnType::Default,
+            CppFunctionBody::FreeUninitialized(ty_name.clone()),
+        ),
+    ]
+    .into_iter()
+    .map(
+        move |(synthesis, name, inputs, output, cpp_function_body)| {
+            let ident = name.get_final_ident();
+            let api_name = ApiName::new_from_qualified_name(name);
+            Api::Function {
+                name: api_name,
+                fun: Box::new(FuncToConvert {
+                    ident,
+                    doc_attrs: Vec::new(),
+                    inputs,
+                    output,
+                    vis: parse_quote! { pub },
+                    virtualness: crate::conversion::api::Virtualness::None,
+                    cpp_vis: CppVisibility::Public,
+                    special_member: None,
+                    unused_template_param: false,
+                    references: References::default(),
+                    original_name: None,
+                    self_ty: None,
+                    synthesized_this_type: None,
+                    synthetic_cpp: Some((cpp_function_body, CppFunctionKind::Function)),
+                    add_to_trait: Some(synthesis),
+                    is_deleted: false,
+                    provenance: Provenance::SynthesizedOther,
+                    variadic: false,
+                }),
+                analysis: (),
+            }
+        },
+    )
+}
+
+pub(crate) fn get_alloc_name(ty_name: &QualifiedName) -> QualifiedName {
+    get_name(ty_name, "alloc")
+}
+
+pub(crate) fn get_free_name(ty_name: &QualifiedName) -> QualifiedName {
+    get_name(ty_name, "free")
+}
+
+fn get_name(ty_name: &QualifiedName, label: &str) -> QualifiedName {
+    let name = format!("{}_{}", ty_name.get_final_item(), label);
+    let name_id = make_ident(name);
+    QualifiedName::new(ty_name.get_namespace(), name_id)
+}
diff --git a/engine/src/conversion/analysis/casts.rs b/engine/src/conversion/analysis/casts.rs
new file mode 100644
index 0000000..5f493f9
--- /dev/null
+++ b/engine/src/conversion/analysis/casts.rs
@@ -0,0 +1,141 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use itertools::Itertools;
+use quote::quote;
+use syn::{parse_quote, FnArg};
+
+use crate::{
+    conversion::{
+        api::{Api, ApiName, CastMutability, Provenance, References, TraitSynthesis},
+        apivec::ApiVec,
+    },
+    types::{make_ident, QualifiedName},
+};
+
+/// If A is a base of B, we might want to be able to cast from
+/// &B to &A, or from Pin<&mut A> to &B, or from Pin<&mut A> to &B.
+/// The first is OK; the others turn out to be hard due to all
+/// the Pin stuff. For now therefore, we simply don't allow them.
+/// But the related code may be useful in future so I'm keeping it around.
+const SUPPORT_MUTABLE_CASTS: bool = false;
+
+use super::{
+    fun::function_wrapper::{CppFunctionBody, CppFunctionKind},
+    pod::{PodAnalysis, PodPhase},
+};
+
+pub(crate) fn add_casts(apis: ApiVec<PodPhase>) -> ApiVec<PodPhase> {
+    apis.into_iter()
+        .flat_map(|api| {
+            let mut resultant_apis = match api {
+                Api::Struct {
+                    ref name,
+                    details: _,
+                    ref analysis,
+                } => create_casts(&name.name, analysis).collect_vec(),
+                _ => Vec::new(),
+            };
+            resultant_apis.push(api);
+            resultant_apis.into_iter()
+        })
+        .collect()
+}
+
+fn create_casts<'a>(
+    name: &'a QualifiedName,
+    analysis: &'a PodAnalysis,
+) -> impl Iterator<Item = Api<PodPhase>> + 'a {
+    // Create casts only to base classes which are on the allowlist
+    // because otherwise we won't know for sure whether they're abstract or not.
+    analysis
+        .castable_bases
+        .iter()
+        .flat_map(move |base| cast_types().map(|mutable| create_cast(name, base, mutable)))
+}
+
+/// Iterate through the types of cast we should make.
+fn cast_types() -> impl Iterator<Item = CastMutability> {
+    if SUPPORT_MUTABLE_CASTS {
+        vec![
+            CastMutability::ConstToConst,
+            CastMutability::MutToConst,
+            CastMutability::MutToMut,
+        ]
+        .into_iter()
+    } else {
+        vec![CastMutability::ConstToConst].into_iter()
+    }
+}
+
+fn create_cast(from: &QualifiedName, to: &QualifiedName, mutable: CastMutability) -> Api<PodPhase> {
+    let name = name_for_cast(from, to, mutable);
+    let ident = name.get_final_ident();
+    let from_typ = from.to_type_path();
+    let to_typ = to.to_type_path();
+    let return_mutability = match mutable {
+        CastMutability::ConstToConst | CastMutability::MutToConst => quote! { const },
+        CastMutability::MutToMut => quote! { mut },
+    };
+    let param_mutability = match mutable {
+        CastMutability::ConstToConst => quote! { const },
+        CastMutability::MutToConst | CastMutability::MutToMut => quote! { mut },
+    };
+    let fnarg: FnArg = parse_quote! {
+        this: * #param_mutability #from_typ
+    };
+    Api::Function {
+        name: ApiName::new_from_qualified_name(name),
+        fun: Box::new(crate::conversion::api::FuncToConvert {
+            ident,
+            doc_attrs: Vec::new(),
+            inputs: [fnarg].into_iter().collect(),
+            output: parse_quote! {
+                -> * #return_mutability #to_typ
+            },
+            vis: parse_quote! { pub },
+            virtualness: crate::conversion::api::Virtualness::None,
+            cpp_vis: crate::conversion::api::CppVisibility::Public,
+            special_member: None,
+            unused_template_param: false,
+            references: References::new_with_this_and_return_as_reference(),
+            original_name: None,
+            self_ty: Some(from.clone()),
+            synthesized_this_type: None,
+            add_to_trait: Some(TraitSynthesis::Cast {
+                to_type: to.clone(),
+                mutable,
+            }),
+            synthetic_cpp: Some((CppFunctionBody::Cast, CppFunctionKind::Function)),
+            is_deleted: false,
+            provenance: Provenance::SynthesizedOther,
+            variadic: false,
+        }),
+        analysis: (),
+    }
+}
+
+fn name_for_cast(
+    from: &QualifiedName,
+    to: &QualifiedName,
+    mutable: CastMutability,
+) -> QualifiedName {
+    let suffix = match mutable {
+        CastMutability::ConstToConst => "",
+        CastMutability::MutToConst => "_to_const",
+        CastMutability::MutToMut => "_mut",
+    };
+    let name = format!(
+        "cast_{}_to_{}{}",
+        from.get_final_item(),
+        to.get_final_item(),
+        suffix
+    );
+    let name = make_ident(name);
+    QualifiedName::new(from.get_namespace(), name)
+}
diff --git a/engine/src/conversion/analysis/constructor_deps.rs b/engine/src/conversion/analysis/constructor_deps.rs
new file mode 100644
index 0000000..63b6dbe
--- /dev/null
+++ b/engine/src/conversion/analysis/constructor_deps.rs
@@ -0,0 +1,105 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::map::IndexMap as HashMap;
+
+use crate::{
+    conversion::{
+        api::{Api, ApiName, StructDetails, TypeKind},
+        apivec::ApiVec,
+        convert_error::ConvertErrorWithContext,
+        error_reporter::convert_apis,
+    },
+    types::QualifiedName,
+};
+
+use super::fun::{
+    FnAnalysis, FnKind, FnPhase, FnPrePhase2, PodAndConstructorAnalysis, PodAndDepAnalysis,
+    TraitMethodKind,
+};
+
+/// We've now analyzed all functions (including both implicit and explicit
+/// constructors). Decorate each struct with a note of its constructors,
+/// which will later be used as edges in the garbage collection, because
+/// typically any use of a type will require us to call its copy or move
+/// constructor. The same applies to its alloc/free functions.
+pub(crate) fn decorate_types_with_constructor_deps(apis: ApiVec<FnPrePhase2>) -> ApiVec<FnPhase> {
+    let mut constructors_and_allocators_by_type = find_important_constructors(&apis);
+    let mut results = ApiVec::new();
+    convert_apis(
+        apis,
+        &mut results,
+        Api::fun_unchanged,
+        |name, details, pod| {
+            decorate_struct(name, details, pod, &mut constructors_and_allocators_by_type)
+        },
+        Api::enum_unchanged,
+        Api::typedef_unchanged,
+    );
+    results
+}
+
+fn decorate_struct(
+    name: ApiName,
+    details: Box<StructDetails>,
+    fn_struct: PodAndConstructorAnalysis,
+    constructors_and_allocators_by_type: &mut HashMap<QualifiedName, Vec<QualifiedName>>,
+) -> Result<Box<dyn Iterator<Item = Api<FnPhase>>>, ConvertErrorWithContext> {
+    let pod = fn_struct.pod;
+    let is_abstract = matches!(pod.kind, TypeKind::Abstract);
+    let constructor_and_allocator_deps = if is_abstract || pod.is_generic {
+        Vec::new()
+    } else {
+        constructors_and_allocators_by_type
+            .remove(&name.name)
+            .unwrap_or_default()
+    };
+    Ok(Box::new(std::iter::once(Api::Struct {
+        name,
+        details,
+        analysis: PodAndDepAnalysis {
+            pod,
+            constructor_and_allocator_deps,
+            constructors: fn_struct.constructors,
+        },
+    })))
+}
+
+fn find_important_constructors(
+    apis: &ApiVec<FnPrePhase2>,
+) -> HashMap<QualifiedName, Vec<QualifiedName>> {
+    let mut results: HashMap<QualifiedName, Vec<QualifiedName>> = HashMap::new();
+    for api in apis.iter() {
+        if let Api::Function {
+            name,
+            analysis:
+                FnAnalysis {
+                    kind:
+                        FnKind::TraitMethod {
+                            kind:
+                                TraitMethodKind::Alloc
+                                | TraitMethodKind::Dealloc
+                                | TraitMethodKind::CopyConstructor
+                                | TraitMethodKind::MoveConstructor,
+                            impl_for,
+                            ..
+                        },
+                    ignore_reason: Ok(_),
+                    ..
+                },
+            ..
+        } = api
+        {
+            results
+                .entry(impl_for.clone())
+                .or_default()
+                .push(name.name.clone())
+        }
+    }
+    results
+}
diff --git a/engine/src/conversion/analysis/ctypes.rs b/engine/src/conversion/analysis/ctypes.rs
new file mode 100644
index 0000000..b2ce840
--- /dev/null
+++ b/engine/src/conversion/analysis/ctypes.rs
@@ -0,0 +1,36 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::map::IndexMap as HashMap;
+
+use syn::Ident;
+
+use crate::conversion::api::ApiName;
+use crate::conversion::apivec::ApiVec;
+use crate::types::Namespace;
+use crate::{conversion::api::Api, known_types::known_types, types::QualifiedName};
+
+use super::deps::HasDependencies;
+use super::fun::FnPhase;
+
+/// Spot any variable-length C types (e.g. unsigned long)
+/// used in the [Api]s and append those as extra APIs.
+pub(crate) fn append_ctype_information(apis: &mut ApiVec<FnPhase>) {
+    let ctypes: HashMap<Ident, QualifiedName> = apis
+        .iter()
+        .flat_map(|api| api.deps())
+        .filter(|ty| known_types().is_ctype(ty))
+        .map(|ty| (ty.get_final_ident(), ty.clone()))
+        .collect();
+    for (id, typename) in ctypes {
+        apis.push(Api::CType {
+            name: ApiName::new(&Namespace::new(), id),
+            typename,
+        });
+    }
+}
diff --git a/engine/src/conversion/analysis/deps.rs b/engine/src/conversion/analysis/deps.rs
new file mode 100644
index 0000000..7aca96c
--- /dev/null
+++ b/engine/src/conversion/analysis/deps.rs
@@ -0,0 +1,116 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use itertools::Itertools;
+
+use crate::{
+    conversion::api::{Api, TypeKind},
+    types::QualifiedName,
+};
+
+use super::{
+    fun::{FnPhase, FnPrePhase1, PodAndDepAnalysis},
+    pod::PodAnalysis,
+    tdef::TypedefAnalysis,
+};
+
+pub(crate) trait HasDependencies {
+    fn name(&self) -> &QualifiedName;
+    fn deps(&self) -> Box<dyn Iterator<Item = &QualifiedName> + '_>;
+
+    fn format_deps(&self) -> String {
+        self.deps().join(",")
+    }
+}
+
+impl HasDependencies for Api<FnPrePhase1> {
+    fn deps(&self) -> Box<dyn Iterator<Item = &QualifiedName> + '_> {
+        match self {
+            Api::Typedef {
+                old_tyname,
+                analysis: TypedefAnalysis { deps, .. },
+                ..
+            } => Box::new(old_tyname.iter().chain(deps.iter())),
+            Api::Struct {
+                analysis:
+                    PodAnalysis {
+                        kind: TypeKind::Pod,
+                        bases,
+                        field_deps,
+                        ..
+                    },
+                ..
+            } => Box::new(field_deps.iter().chain(bases.iter())),
+            Api::Function { analysis, .. } => Box::new(analysis.deps.iter()),
+            Api::Subclass {
+                name: _,
+                superclass,
+            } => Box::new(std::iter::once(superclass)),
+            Api::RustSubclassFn { details, .. } => Box::new(details.dependencies.iter()),
+            Api::RustFn { receiver, .. } => Box::new(receiver.iter()),
+            _ => Box::new(std::iter::empty()),
+        }
+    }
+
+    fn name(&self) -> &QualifiedName {
+        self.name()
+    }
+}
+
+impl HasDependencies for Api<FnPhase> {
+    /// Any dependencies on other APIs which this API has.
+    fn deps(&self) -> Box<dyn Iterator<Item = &QualifiedName> + '_> {
+        match self {
+            Api::Typedef {
+                old_tyname,
+                analysis: TypedefAnalysis { deps, .. },
+                ..
+            } => Box::new(old_tyname.iter().chain(deps.iter())),
+            Api::Struct {
+                analysis:
+                    PodAndDepAnalysis {
+                        pod:
+                            PodAnalysis {
+                                kind: TypeKind::Pod,
+                                bases,
+                                field_deps,
+                                ..
+                            },
+                        constructor_and_allocator_deps,
+                        ..
+                    },
+                ..
+            } => Box::new(
+                field_deps
+                    .iter()
+                    .chain(bases.iter())
+                    .chain(constructor_and_allocator_deps.iter()),
+            ),
+            Api::Struct {
+                analysis:
+                    PodAndDepAnalysis {
+                        constructor_and_allocator_deps,
+                        ..
+                    },
+                ..
+            } => Box::new(constructor_and_allocator_deps.iter()),
+            Api::Function { analysis, .. } => Box::new(analysis.deps.iter()),
+            Api::Subclass {
+                name: _,
+                superclass,
+            } => Box::new(std::iter::once(superclass)),
+            Api::RustSubclassFn { details, .. } => Box::new(details.dependencies.iter()),
+            Api::RustFn { receiver, .. } => Box::new(receiver.iter()),
+            _ => Box::new(std::iter::empty()),
+        }
+    }
+
+    fn name(&self) -> &QualifiedName {
+        self.name()
+    }
+}
diff --git a/engine/src/conversion/analysis/depth_first.rs b/engine/src/conversion/analysis/depth_first.rs
new file mode 100644
index 0000000..02459e1
--- /dev/null
+++ b/engine/src/conversion/analysis/depth_first.rs
@@ -0,0 +1,98 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::set::IndexSet as HashSet;
+use std::collections::VecDeque;
+use std::fmt::Debug;
+
+use itertools::Itertools;
+
+use crate::types::QualifiedName;
+
+use super::deps::HasDependencies;
+
+/// Return APIs in a depth-first order, i.e. those with no dependencies first.
+pub(super) fn depth_first<'a, T: HasDependencies + Debug + 'a>(
+    inputs: impl Iterator<Item = &'a T> + 'a,
+) -> impl Iterator<Item = &'a T> {
+    let queue: VecDeque<_> = inputs.collect();
+    let yet_to_do = queue.iter().map(|api| api.name()).collect();
+    DepthFirstIter { queue, yet_to_do }
+}
+
+struct DepthFirstIter<'a, T: HasDependencies + Debug> {
+    queue: VecDeque<&'a T>,
+    yet_to_do: HashSet<&'a QualifiedName>,
+}
+
+impl<'a, T: HasDependencies + Debug> Iterator for DepthFirstIter<'a, T> {
+    type Item = &'a T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let first_candidate = self.queue.get(0).map(|api| api.name());
+        while let Some(candidate) = self.queue.pop_front() {
+            if !candidate.deps().any(|d| self.yet_to_do.contains(&d)) {
+                self.yet_to_do.remove(candidate.name());
+                return Some(candidate);
+            }
+            self.queue.push_back(candidate);
+            if self.queue.get(0).map(|api| api.name()) == first_candidate {
+                panic!(
+                    "Failed to find a candidate; there must be a circular dependency. Queue is {}",
+                    self.queue
+                        .iter()
+                        .map(|item| format!("{}: {}", item.name(), item.deps().join(",")))
+                        .join("\n")
+                );
+            }
+        }
+        None
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use crate::types::QualifiedName;
+
+    use super::{depth_first, HasDependencies};
+
+    #[derive(Debug)]
+    struct Thing(QualifiedName, Vec<QualifiedName>);
+
+    impl HasDependencies for Thing {
+        fn name(&self) -> &QualifiedName {
+            &self.0
+        }
+
+        fn deps(&self) -> Box<dyn Iterator<Item = &QualifiedName> + '_> {
+            Box::new(self.1.iter())
+        }
+    }
+
+    #[test]
+    fn test() {
+        let a = Thing(QualifiedName::new_from_cpp_name("a"), vec![]);
+        let b = Thing(
+            QualifiedName::new_from_cpp_name("b"),
+            vec![
+                QualifiedName::new_from_cpp_name("a"),
+                QualifiedName::new_from_cpp_name("c"),
+            ],
+        );
+        let c = Thing(
+            QualifiedName::new_from_cpp_name("c"),
+            vec![QualifiedName::new_from_cpp_name("a")],
+        );
+        let api_list = vec![a, b, c];
+        let mut it = depth_first(api_list.iter());
+        assert_eq!(it.next().unwrap().0, QualifiedName::new_from_cpp_name("a"));
+        assert_eq!(it.next().unwrap().0, QualifiedName::new_from_cpp_name("c"));
+        assert_eq!(it.next().unwrap().0, QualifiedName::new_from_cpp_name("b"));
+        assert!(it.next().is_none());
+    }
+}
diff --git a/engine/src/conversion/analysis/doc_label.rs b/engine/src/conversion/analysis/doc_label.rs
new file mode 100644
index 0000000..767da87
--- /dev/null
+++ b/engine/src/conversion/analysis/doc_label.rs
@@ -0,0 +1,17 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use proc_macro2::Span;
+use syn::{parse_quote, Attribute};
+
+pub(crate) fn make_doc_attrs(label: String) -> Vec<Attribute> {
+    let hexathorpe = syn::token::Pound(Span::call_site());
+    vec![parse_quote! {
+        #hexathorpe [doc = #label]
+    }]
+}
diff --git a/engine/src/conversion/analysis/fun/bridge_name_tracker.rs b/engine/src/conversion/analysis/fun/bridge_name_tracker.rs
new file mode 100644
index 0000000..7e81c59
--- /dev/null
+++ b/engine/src/conversion/analysis/fun/bridge_name_tracker.rs
@@ -0,0 +1,158 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::types::Namespace;
+use itertools::Itertools;
+use std::collections::HashMap;
+
+/// Type to generate unique names for entries in the [cxx::bridge]
+/// mod which is flat.
+///
+/// # All about the names involved in autocxx
+///
+/// A given function may have many, many names. From C++ to Rust...
+///
+/// 1. The actual C++ name. Fixed, obviously.
+/// 2. The name reported by bindgen. Not always the same, as
+///    bindgen may generate a different name for different overloads.
+///    See `overload_tracker` for the conversion here.
+/// 3. The name in the cxx::bridge mod. This is a flat namespace,
+///    and it's the responsibility of this type to generate a
+///    suitable name here.
+///    If this is different from the C++ name in (1), we'll
+///    add a #[cxx_name] attribute to the cxx::bridge declaration.
+/// 4. The name we wish to present to Rust users. Again, we have
+///    to take stock of the fact Rust doesn't support overloading
+///    so two different functions called 'get' may end up being
+///    'get' and 'get1'. Yet, this may not be the same as the
+///    bindgen name in (2) because we wish to generate such number
+///    sequences on a per-type basis, whilst bindgen does it globally.
+///
+/// This fourth name, the final Rust user name, may be finagled
+/// into place in three different ways:
+/// 1. For methods, we generate an 'impl' block where the
+///    method name is the intended name, but it calls the
+///    cxxbridge name.
+/// 2. For simple functions, we use the #[rust_name] attribute.
+/// 3. Occasionally, there can be conflicts in the rust_name
+///    namespace (if there are two identically named functions
+///    in different C++ namespaces). That's detected by
+///    rust_name_tracker.rs. In such a case, we'll omit the
+///    #[rust_name] attribute and instead generate a 'use A = B;'
+///    declaration in the mod which we generate for the output
+///    namespace.
+#[derive(Default)]
+pub(crate) struct BridgeNameTracker {
+    next_cxx_bridge_name_for_prefix: HashMap<String, usize>,
+}
+
+impl BridgeNameTracker {
+    pub(crate) fn new() -> Self {
+        Self::default()
+    }
+
+    /// Figure out the least confusing unique name for this function in the
+    /// cxx::bridge section, which has a flat namespace.
+    /// We mostly just qualify the name with the namespace_with_underscores.
+    /// It doesn't really matter; we'll rebind these things to
+    /// better Rust-side names so it's really just a matter of how it shows up
+    /// in stack traces and for our own sanity as maintainers of autocxx.
+    /// This may become unnecessary if and when cxx supports hierarchic
+    /// namespace mods.
+    /// There is a slight advantage in using the same name as either the
+    /// Rust or C++ symbols as it reduces the amount of rebinding required
+    /// by means of cxx_name or rust_name attributes. In extreme cases it
+    /// may even allow us to remove whole impl blocks. So we may wish to try
+    /// harder to find better names in future instead of always prepending
+    /// the namespace.
+    pub(crate) fn get_unique_cxx_bridge_name(
+        &mut self,
+        type_name: Option<&str>,
+        found_name: &str,
+        ns: &Namespace,
+    ) -> String {
+        let found_name = if found_name == "new" {
+            "new_autocxx"
+        } else {
+            found_name
+        };
+        let count = self
+            .next_cxx_bridge_name_for_prefix
+            .entry(found_name.to_string())
+            .or_default();
+        if *count == 0 {
+            // Oh, good, we can use this function name as-is.
+            *count += 1;
+            return found_name.to_string();
+        }
+        let prefix = ns
+            .iter()
+            .cloned()
+            .chain(type_name.iter().map(|x| x.to_string()))
+            .chain(std::iter::once(found_name.to_string()))
+            .join("_");
+        let count = self
+            .next_cxx_bridge_name_for_prefix
+            .entry(prefix.clone())
+            .or_default();
+        if *count == 0 {
+            *count += 1;
+            prefix
+        } else {
+            let r = format!("{}_autocxx{}", prefix, count);
+            *count += 1;
+            r
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::types::Namespace;
+
+    use super::BridgeNameTracker;
+
+    #[test]
+    fn test() {
+        let mut bnt = BridgeNameTracker::new();
+        let ns_root = Namespace::new();
+        let ns_a = Namespace::from_user_input("A");
+        let ns_b = Namespace::from_user_input("B");
+        let ns_ab = Namespace::from_user_input("A::B");
+        assert_eq!(bnt.get_unique_cxx_bridge_name(None, "do", &ns_root), "do");
+        assert_eq!(
+            bnt.get_unique_cxx_bridge_name(None, "do", &ns_root),
+            "do_autocxx1"
+        );
+        assert_eq!(bnt.get_unique_cxx_bridge_name(None, "did", &ns_root), "did");
+        assert_eq!(
+            bnt.get_unique_cxx_bridge_name(Some("ty1"), "do", &ns_root),
+            "ty1_do"
+        );
+        assert_eq!(
+            bnt.get_unique_cxx_bridge_name(Some("ty1"), "do", &ns_root),
+            "ty1_do_autocxx1"
+        );
+        assert_eq!(
+            bnt.get_unique_cxx_bridge_name(Some("ty2"), "do", &ns_root),
+            "ty2_do"
+        );
+        assert_eq!(
+            bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_a),
+            "A_ty_do"
+        );
+        assert_eq!(
+            bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_b),
+            "B_ty_do"
+        );
+        assert_eq!(
+            bnt.get_unique_cxx_bridge_name(Some("ty"), "do", &ns_ab),
+            "A_B_ty_do"
+        );
+    }
+}
diff --git a/engine/src/conversion/analysis/fun/function_wrapper.rs b/engine/src/conversion/analysis/fun/function_wrapper.rs
new file mode 100644
index 0000000..f2f6aaa
--- /dev/null
+++ b/engine/src/conversion/analysis/fun/function_wrapper.rs
@@ -0,0 +1,213 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::{
+    conversion::api::SubclassName,
+    types::{Namespace, QualifiedName},
+};
+use syn::{parse_quote, Ident, Type};
+
+#[derive(Clone, Debug)]
+pub(crate) enum CppConversionType {
+    None,
+    Move,
+    FromUniquePtrToValue,
+    FromPtrToValue,
+    FromValueToUniquePtr,
+    FromPtrToMove,
+    /// Ignored in the sense that it isn't passed into the C++ function.
+    IgnoredPlacementPtrParameter,
+    FromReturnValueToPlacementPtr,
+}
+
+impl CppConversionType {
+    /// If we've found a function which does X to its parameter, what
+    /// is the opposite of X? This is used for subclasses where calls
+    /// from Rust to C++ might also involve calls from C++ to Rust.
+    fn inverse(&self) -> Self {
+        match self {
+            CppConversionType::None => CppConversionType::None,
+            CppConversionType::FromUniquePtrToValue | CppConversionType::FromPtrToValue => {
+                CppConversionType::FromValueToUniquePtr
+            }
+            CppConversionType::FromValueToUniquePtr => CppConversionType::FromUniquePtrToValue,
+            _ => panic!("Did not expect to have to invert this conversion"),
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+pub(crate) enum RustConversionType {
+    None,
+    FromStr,
+    ToBoxedUpHolder(SubclassName),
+    FromPinMaybeUninitToPtr,
+    FromPinMoveRefToPtr,
+    FromTypeToPtr,
+    FromValueParamToPtr,
+    FromPlacementParamToNewReturn,
+    FromRValueParamToPtr,
+}
+
+impl RustConversionType {
+    pub(crate) fn requires_mutability(&self) -> Option<syn::token::Mut> {
+        match self {
+            Self::FromPinMoveRefToPtr => Some(parse_quote! { mut }),
+            _ => None,
+        }
+    }
+}
+
+/// A policy for converting types. Conversion may occur on both the Rust and
+/// C++ side. The most complex example is a C++ function which takes
+/// std::string by value, which might do this:
+/// * Client Rust code: `&str`
+/// * Rust wrapper function: converts `&str` to `UniquePtr<CxxString>`
+/// * cxx::bridge mod: refers to `UniquePtr<CxxString>`
+/// * C++ wrapper function converts `std::unique_ptr<std::string>` to just
+///   `std::string`
+/// * Finally, the actual C++ API receives a `std::string` by value.
+/// The implementation here is distributed across this file, and
+/// `function_wrapper_rs` and `function_wrapper_cpp`.
+#[derive(Clone)]
+pub(crate) struct TypeConversionPolicy {
+    pub(crate) unwrapped_type: Type,
+    pub(crate) cpp_conversion: CppConversionType,
+    pub(crate) rust_conversion: RustConversionType,
+}
+
+impl TypeConversionPolicy {
+    pub(crate) fn new_unconverted(ty: Type) -> Self {
+        TypeConversionPolicy {
+            unwrapped_type: ty,
+            cpp_conversion: CppConversionType::None,
+            rust_conversion: RustConversionType::None,
+        }
+    }
+
+    pub(crate) fn new_to_unique_ptr(ty: Type) -> Self {
+        TypeConversionPolicy {
+            unwrapped_type: ty,
+            cpp_conversion: CppConversionType::FromValueToUniquePtr,
+            rust_conversion: RustConversionType::None,
+        }
+    }
+
+    pub(crate) fn new_for_placement_return(ty: Type) -> Self {
+        TypeConversionPolicy {
+            unwrapped_type: ty,
+            cpp_conversion: CppConversionType::FromReturnValueToPlacementPtr,
+            // Rust conversion is marked as none here, since this policy
+            // will be applied to the return value, and the Rust-side
+            // shenanigans applies to the placement new *parameter*
+            rust_conversion: RustConversionType::None,
+        }
+    }
+
+    pub(crate) fn cpp_work_needed(&self) -> bool {
+        !matches!(self.cpp_conversion, CppConversionType::None)
+    }
+
+    pub(crate) fn unconverted_rust_type(&self) -> Type {
+        match self.cpp_conversion {
+            CppConversionType::FromValueToUniquePtr => self.make_unique_ptr_type(),
+            _ => self.unwrapped_type.clone(),
+        }
+    }
+
+    pub(crate) fn converted_rust_type(&self) -> Type {
+        match self.cpp_conversion {
+            CppConversionType::FromUniquePtrToValue => self.make_unique_ptr_type(),
+            CppConversionType::FromPtrToValue => {
+                let innerty = &self.unwrapped_type;
+                parse_quote! {
+                    *mut #innerty
+                }
+            }
+            _ => self.unwrapped_type.clone(),
+        }
+    }
+
+    fn make_unique_ptr_type(&self) -> Type {
+        let innerty = &self.unwrapped_type;
+        parse_quote! {
+            cxx::UniquePtr < #innerty >
+        }
+    }
+
+    pub(crate) fn rust_work_needed(&self) -> bool {
+        !matches!(self.rust_conversion, RustConversionType::None)
+    }
+
+    /// Subclass support involves calls from Rust -> C++, but
+    /// also from C++ -> Rust. Work out the correct argument conversion
+    /// type for the latter call, when given the former.
+    pub(crate) fn inverse(&self) -> Self {
+        Self {
+            unwrapped_type: self.unwrapped_type.clone(),
+            cpp_conversion: self.cpp_conversion.inverse(),
+            rust_conversion: self.rust_conversion.clone(),
+        }
+    }
+
+    pub(crate) fn bridge_unsafe_needed(&self) -> bool {
+        matches!(
+            self.rust_conversion,
+            RustConversionType::FromValueParamToPtr
+                | RustConversionType::FromRValueParamToPtr
+                | RustConversionType::FromPlacementParamToNewReturn
+        )
+    }
+
+    pub(crate) fn is_placement_parameter(&self) -> bool {
+        matches!(
+            self.cpp_conversion,
+            CppConversionType::IgnoredPlacementPtrParameter
+        )
+    }
+
+    pub(crate) fn populate_return_value(&self) -> bool {
+        !matches!(
+            self.cpp_conversion,
+            CppConversionType::FromReturnValueToPlacementPtr
+        )
+    }
+}
+
+#[derive(Clone)]
+pub(crate) enum CppFunctionBody {
+    FunctionCall(Namespace, Ident),
+    StaticMethodCall(Namespace, Ident, Ident),
+    PlacementNew(Namespace, Ident),
+    ConstructSuperclass(String),
+    Cast,
+    Destructor(Namespace, Ident),
+    AllocUninitialized(QualifiedName),
+    FreeUninitialized(QualifiedName),
+}
+
+#[derive(Clone)]
+pub(crate) enum CppFunctionKind {
+    Function,
+    Method,
+    Constructor,
+    ConstMethod,
+    SynthesizedConstructor,
+}
+
+#[derive(Clone)]
+pub(crate) struct CppFunction {
+    pub(crate) payload: CppFunctionBody,
+    pub(crate) wrapper_function_name: Ident,
+    pub(crate) original_cpp_name: String,
+    pub(crate) return_conversion: Option<TypeConversionPolicy>,
+    pub(crate) argument_conversion: Vec<TypeConversionPolicy>,
+    pub(crate) kind: CppFunctionKind,
+    pub(crate) pass_obs_field: bool,
+    pub(crate) qualification: Option<QualifiedName>,
+}
diff --git a/engine/src/conversion/analysis/fun/implicit_constructors.rs b/engine/src/conversion/analysis/fun/implicit_constructors.rs
new file mode 100644
index 0000000..469ed89
--- /dev/null
+++ b/engine/src/conversion/analysis/fun/implicit_constructors.rs
@@ -0,0 +1,695 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::map::IndexMap as HashMap;
+use indexmap::{map::Entry, set::IndexSet as HashSet};
+
+use syn::{Type, TypeArray};
+
+use crate::{
+    conversion::{
+        analysis::{depth_first::depth_first, pod::PodAnalysis, type_converter::TypeKind},
+        api::{Api, ApiName, CppVisibility, FuncToConvert, SpecialMemberKind},
+        apivec::ApiVec,
+        convert_error::ConvertErrorWithContext,
+        ConvertError,
+    },
+    known_types::{known_types, KnownTypeConstructorDetails},
+    types::QualifiedName,
+};
+
+use super::{FnAnalysis, FnKind, FnPrePhase1, MethodKind, ReceiverMutability, TraitMethodKind};
+
+/// Indicates what we found out about a category of special member function.
+///
+/// In the end, we only care whether it's public and exists, but we track a bit more information to
+/// support determining the information for dependent classes.
+#[derive(Debug, Copy, Clone)]
+pub(super) enum SpecialMemberFound {
+    /// This covers being deleted in any way:
+    ///   * Explicitly deleted
+    ///   * Implicitly defaulted when that means being deleted
+    ///   * Explicitly defaulted when that means being deleted
+    ///
+    /// It also covers not being either user declared or implicitly defaulted.
+    NotPresent,
+    /// Implicit special member functions, indicated by this, are always public.
+    Implicit,
+    /// This covers being explicitly defaulted (when that is not deleted) or being user-defined.
+    Explicit(CppVisibility),
+}
+
+impl SpecialMemberFound {
+    /// Returns whether code outside of subclasses can call this special member function.
+    pub fn callable_any(&self) -> bool {
+        matches!(self, Self::Explicit(CppVisibility::Public) | Self::Implicit)
+    }
+
+    /// Returns whether code in a subclass can call this special member function.
+    pub fn callable_subclass(&self) -> bool {
+        matches!(
+            self,
+            Self::Explicit(CppVisibility::Public)
+                | Self::Explicit(CppVisibility::Protected)
+                | Self::Implicit
+        )
+    }
+
+    /// Returns whether this exists at all. Note that this will return true even if it's private,
+    /// which is generally not very useful, but does come into play for some rules around which
+    /// default special member functions are deleted vs don't exist.
+    pub fn exists(&self) -> bool {
+        matches!(self, Self::Explicit(_) | Self::Implicit)
+    }
+
+    pub fn exists_implicit(&self) -> bool {
+        matches!(self, Self::Implicit)
+    }
+
+    pub fn exists_explicit(&self) -> bool {
+        matches!(self, Self::Explicit(_))
+    }
+}
+
+/// Information about which special member functions exist based on the C++ rules.
+///
+/// Not all of this information is used directly, but we need to track it to determine the
+/// information we do need for classes which are used as members or base classes.
+#[derive(Debug, Clone)]
+pub(super) struct ItemsFound {
+    pub(super) default_constructor: SpecialMemberFound,
+    pub(super) destructor: SpecialMemberFound,
+    pub(super) const_copy_constructor: SpecialMemberFound,
+    /// Remember that [`const_copy_constructor`] may be used in place of this if it exists.
+    pub(super) non_const_copy_constructor: SpecialMemberFound,
+    pub(super) move_constructor: SpecialMemberFound,
+
+    /// The full name of the type. We identify instances by [`QualifiedName`], because that's
+    /// the only thing which [`FnKind::Method`] has to tie it to, and that's unique enough for
+    /// identification.  However, when generating functions for implicit special members, we need
+    /// the extra information here.
+    ///
+    /// Will always be `Some` if any of the other fields are [`SpecialMemberFound::Implict`],
+    /// otherwise optional.
+    pub(super) name: Option<ApiName>,
+}
+
+impl ItemsFound {
+    /// Returns whether we should generate a default constructor wrapper, because bindgen won't do
+    /// one for the implicit default constructor which exists.
+    pub(super) fn implicit_default_constructor_needed(&self) -> bool {
+        self.default_constructor.exists_implicit()
+    }
+
+    /// Returns whether we should generate a copy constructor wrapper, because bindgen won't do one
+    /// for the implicit copy constructor which exists.
+    pub(super) fn implicit_copy_constructor_needed(&self) -> bool {
+        let any_implicit_copy = self.const_copy_constructor.exists_implicit()
+            || self.non_const_copy_constructor.exists_implicit();
+        let no_explicit_copy = !(self.const_copy_constructor.exists_explicit()
+            || self.non_const_copy_constructor.exists_explicit());
+        any_implicit_copy && no_explicit_copy
+    }
+
+    /// Returns whether we should generate a move constructor wrapper, because bindgen won't do one
+    /// for the implicit move constructor which exists.
+    pub(super) fn implicit_move_constructor_needed(&self) -> bool {
+        self.move_constructor.exists_implicit()
+    }
+
+    /// Returns whether we should generate a destructor wrapper, because bindgen won't do one for
+    /// the implicit destructor which exists.
+    pub(super) fn implicit_destructor_needed(&self) -> bool {
+        self.destructor.exists_implicit()
+    }
+}
+#[derive(Hash, Eq, PartialEq)]
+enum ExplicitKind {
+    DefaultConstructor,
+    ConstCopyConstructor,
+    NonConstCopyConstructor,
+    MoveConstructor,
+    OtherConstructor,
+    Destructor,
+    ConstCopyAssignmentOperator,
+    NonConstCopyAssignmentOperator,
+    MoveAssignmentOperator,
+}
+
+/// Denotes a specific kind of explicit member function that we found.
+#[derive(Hash, Eq, PartialEq)]
+struct ExplicitType {
+    ty: QualifiedName,
+    kind: ExplicitKind,
+}
+
+/// Includes information about an explicit special member function which was found.
+// TODO: Add Defaulted(CppVisibility) for https://github.com/google/autocxx/issues/815.
+#[derive(Copy, Clone, Debug)]
+enum ExplicitFound {
+    UserDefined(CppVisibility),
+    /// Note that this always means explicitly deleted, because this enum only represents
+    /// explicit declarations.
+    Deleted,
+    /// Indicates that we found more than one explicit of this kind. This is possible with most of
+    /// them, and we just bail and mostly act as if they're deleted. We'd have to decide whether
+    /// they're ambiguous to use them, which is really complicated.
+    Multiple,
+}
+
+/// Analyzes which constructors are present for each type.
+///
+/// If a type has explicit constructors, bindgen will generate corresponding
+/// constructor functions, which we'll have already converted to make_unique methods.
+/// For types with implicit constructors, we enumerate them here.
+///
+/// It is tempting to make this a separate analysis phase, to be run later than
+/// the function analysis; but that would make the code much more complex as it
+/// would need to output a `FnAnalysisBody`. By running it as part of this phase
+/// we can simply generate the sort of thing bindgen generates, then ask
+/// the existing code in this phase to figure out what to do with it.
+pub(super) fn find_constructors_present(
+    apis: &ApiVec<FnPrePhase1>,
+) -> HashMap<QualifiedName, ItemsFound> {
+    let (explicits, unknown_types) = find_explicit_items(apis);
+
+    // These contain all the classes we've seen so far with the relevant properties on their
+    // constructors of each kind. We iterate via [`depth_first`], so analyzing later classes
+    // just needs to check these.
+    //
+    // Important only to ask for a depth-first analysis of structs, because
+    // when all APIs are considered there may be reference loops and that would
+    // panic.
+    //
+    // These analyses include all bases and members of each class.
+    let mut all_items_found: HashMap<QualifiedName, ItemsFound> = HashMap::new();
+
+    for api in depth_first(apis.iter()) {
+        if let Api::Struct {
+            name,
+            analysis:
+                PodAnalysis {
+                    bases,
+                    field_info,
+                    is_generic: false,
+                    in_anonymous_namespace: false,
+                    ..
+                },
+            details,
+            ..
+        } = api
+        {
+            let find_explicit = |kind: ExplicitKind| -> Option<&ExplicitFound> {
+                explicits.get(&ExplicitType {
+                    ty: name.name.clone(),
+                    kind,
+                })
+            };
+            let get_items_found = |qn: &QualifiedName| -> Option<ItemsFound> {
+                if let Some(constructor_details) = known_types().get_constructor_details(qn) {
+                    Some(known_type_items_found(constructor_details))
+                } else {
+                    all_items_found.get(qn).cloned()
+                }
+            };
+            let bases_items_found: Vec<_> = bases.iter().map_while(get_items_found).collect();
+            let fields_items_found: Vec<_> = field_info
+                .iter()
+                .filter_map(|field_info| match field_info.type_kind {
+                    TypeKind::Regular | TypeKind::SubclassHolder(_) => match field_info.ty {
+                        Type::Path(ref qn) => get_items_found(&QualifiedName::from_type_path(qn)),
+                        Type::Array(TypeArray { ref elem, .. }) => match elem.as_ref() {
+                            Type::Path(ref qn) => {
+                                get_items_found(&QualifiedName::from_type_path(qn))
+                            }
+                            _ => None,
+                        },
+                        _ => None,
+                    },
+                    // TODO: https://github.com/google/autocxx/issues/865 Figure out how to
+                    // differentiate between pointers and references coming from C++. Pointers
+                    // have a default constructor.
+                    TypeKind::Pointer
+                    | TypeKind::Reference
+                    | TypeKind::MutableReference
+                    | TypeKind::RValueReference => Some(ItemsFound {
+                        default_constructor: SpecialMemberFound::NotPresent,
+                        destructor: SpecialMemberFound::Implicit,
+                        const_copy_constructor: SpecialMemberFound::Implicit,
+                        non_const_copy_constructor: SpecialMemberFound::NotPresent,
+                        move_constructor: SpecialMemberFound::Implicit,
+                        name: Some(name.clone()),
+                    }),
+                })
+                .collect();
+            let has_rvalue_reference_fields = details.has_rvalue_reference_fields;
+
+            // Check that all the bases and field types are known first. This combined with
+            // iterating via [`depth_first`] means we can safely search in `items_found` for all of
+            // them.
+            //
+            // Conservatively, we will not acknowledge the existence of most defaulted or implicit
+            // special member functions for any struct/class where we don't fully understand all
+            // field types.  However, we can still look for explictly declared versions and use
+            // those. See below for destructors.
+            //
+            // We need to extend our knowledge to understand the constructor behavior of things in
+            // known_types.rs, then we'll be able to cope with types which contain strings,
+            // unique_ptrs etc.
+            let items_found = if bases_items_found.len() != bases.len()
+                || fields_items_found.len() != field_info.len()
+                || unknown_types.contains(&name.name)
+            {
+                let is_explicit = |kind: ExplicitKind| -> SpecialMemberFound {
+                    // TODO: For https://github.com/google/autocxx/issues/815, map
+                    // ExplicitFound::Defaulted(_) to NotPresent.
+                    match find_explicit(kind) {
+                        None => SpecialMemberFound::NotPresent,
+                        Some(ExplicitFound::Deleted | ExplicitFound::Multiple) => {
+                            SpecialMemberFound::NotPresent
+                        }
+                        Some(ExplicitFound::UserDefined(visibility)) => {
+                            SpecialMemberFound::Explicit(*visibility)
+                        }
+                    }
+                };
+                let items_found = ItemsFound {
+                    default_constructor: is_explicit(ExplicitKind::DefaultConstructor),
+                    destructor: match find_explicit(ExplicitKind::Destructor) {
+                        // Assume that unknown types have destructors. This is common, and allows
+                        // use to generate UniquePtr wrappers with them.
+                        //
+                        // However, this will generate C++ code that doesn't compile if the unknown
+                        // type does not have an accessible destructor. Maybe we should have a way
+                        // to disable that?
+                        //
+                        // TODO: For https://github.com/google/autocxx/issues/815, map
+                        // ExplicitFound::Defaulted(_) to Explicit.
+                        None => SpecialMemberFound::Implicit,
+                        // If there are multiple destructors, assume that one of them will be
+                        // selected by overload resolution.
+                        Some(ExplicitFound::Multiple) => {
+                            SpecialMemberFound::Explicit(CppVisibility::Public)
+                        }
+                        Some(ExplicitFound::Deleted) => SpecialMemberFound::NotPresent,
+                        Some(ExplicitFound::UserDefined(visibility)) => {
+                            SpecialMemberFound::Explicit(*visibility)
+                        }
+                    },
+                    const_copy_constructor: is_explicit(ExplicitKind::ConstCopyConstructor),
+                    non_const_copy_constructor: is_explicit(ExplicitKind::NonConstCopyConstructor),
+                    move_constructor: is_explicit(ExplicitKind::MoveConstructor),
+                    name: Some(name.clone()),
+                };
+                log::info!(
+                    "Special member functions (explicits only) found for {:?}: {:?}",
+                    name,
+                    items_found
+                );
+                items_found
+            } else {
+                // If no user-declared constructors of any kind are provided for a class type (struct, class, or union),
+                // the compiler will always declare a default constructor as an inline public member of its class.
+                //
+                // The implicitly-declared or defaulted default constructor for class T is defined as deleted if any of the following is true:
+                // T has a member of reference type without a default initializer.
+                // T has a non-const-default-constructible const member without a default member initializer.
+                // T has a member (without a default member initializer) which has a deleted default constructor, or its default constructor is ambiguous or inaccessible from this constructor.
+                // T has a direct or virtual base which has a deleted default constructor, or it is ambiguous or inaccessible from this constructor.
+                // T has a direct or virtual base or a non-static data member which has a deleted destructor, or a destructor that is inaccessible from this constructor.
+                // T is a union with at least one variant member with non-trivial default constructor, and no variant member of T has a default member initializer. // we don't support unions anyway
+                // T is a non-union class with a variant member M with a non-trivial default constructor, and no variant member of the anonymous union containing M has a default member initializer.
+                // T is a union and all of its variant members are const. // we don't support unions anyway
+                //
+                // Variant members are the members of anonymous unions.
+                let default_constructor = {
+                    let explicit = find_explicit(ExplicitKind::DefaultConstructor);
+                    // TODO: For https://github.com/google/autocxx/issues/815, replace the first term with:
+                    //   explicit.map_or(true, |explicit_found| matches!(explicit_found, ExplicitFound::Defaulted(_)))
+                    let have_defaulted = explicit.is_none()
+                        && !explicits.iter().any(|(ExplicitType { ty, kind }, _)| {
+                            ty == &name.name
+                                && match *kind {
+                                    ExplicitKind::DefaultConstructor => false,
+                                    ExplicitKind::ConstCopyConstructor => true,
+                                    ExplicitKind::NonConstCopyConstructor => true,
+                                    ExplicitKind::MoveConstructor => true,
+                                    ExplicitKind::OtherConstructor => true,
+                                    ExplicitKind::Destructor => false,
+                                    ExplicitKind::ConstCopyAssignmentOperator => false,
+                                    ExplicitKind::NonConstCopyAssignmentOperator => false,
+                                    ExplicitKind::MoveAssignmentOperator => false,
+                                }
+                        });
+                    if have_defaulted {
+                        let bases_allow = bases_items_found.iter().all(|items_found| {
+                            items_found.destructor.callable_subclass()
+                                && items_found.default_constructor.callable_subclass()
+                        });
+                        // TODO: Allow member initializers for
+                        // https://github.com/google/autocxx/issues/816.
+                        let members_allow = fields_items_found.iter().all(|items_found| {
+                            items_found.destructor.callable_any()
+                                && items_found.default_constructor.callable_any()
+                        });
+                        if !has_rvalue_reference_fields && bases_allow && members_allow {
+                            // TODO: For https://github.com/google/autocxx/issues/815, grab the
+                            // visibility from an explicit default if present.
+                            SpecialMemberFound::Implicit
+                        } else {
+                            SpecialMemberFound::NotPresent
+                        }
+                    } else if let Some(ExplicitFound::UserDefined(visibility)) = explicit {
+                        SpecialMemberFound::Explicit(*visibility)
+                    } else {
+                        SpecialMemberFound::NotPresent
+                    }
+                };
+
+                // If no user-declared prospective destructor is provided for a class type (struct, class, or union), the compiler will always declare a destructor as an inline public member of its class.
+                //
+                // The implicitly-declared or explicitly defaulted destructor for class T is defined as deleted if any of the following is true:
+                // T has a non-static data member that cannot be destructed (has deleted or inaccessible destructor)
+                // T has direct or virtual base class that cannot be destructed (has deleted or inaccessible destructors)
+                // T is a union and has a variant member with non-trivial destructor. // we don't support unions anyway
+                // The implicitly-declared destructor is virtual (because the base class has a virtual destructor) and the lookup for the deallocation function (operator delete()) results in a call to ambiguous, deleted, or inaccessible function.
+                let destructor = {
+                    let explicit = find_explicit(ExplicitKind::Destructor);
+                    // TODO: For https://github.com/google/autocxx/issues/815, replace the condition with:
+                    //   explicit.map_or(true, |explicit_found| matches!(explicit_found, ExplicitFound::Defaulted(_)))
+                    if explicit.is_none() {
+                        let bases_allow = bases_items_found
+                            .iter()
+                            .all(|items_found| items_found.destructor.callable_subclass());
+                        let members_allow = fields_items_found
+                            .iter()
+                            .all(|items_found| items_found.destructor.callable_any());
+                        if bases_allow && members_allow {
+                            // TODO: For https://github.com/google/autocxx/issues/815, grab the
+                            // visibility from an explicit default if present.
+                            SpecialMemberFound::Implicit
+                        } else {
+                            SpecialMemberFound::NotPresent
+                        }
+                    } else if let Some(ExplicitFound::UserDefined(visibility)) = explicit {
+                        SpecialMemberFound::Explicit(*visibility)
+                    } else {
+                        SpecialMemberFound::NotPresent
+                    }
+                };
+
+                // If no user-defined copy constructors are provided for a class type (struct, class, or union),
+                // the compiler will always declare a copy constructor as a non-explicit inline public member of its class.
+                // This implicitly-declared copy constructor has the form T::T(const T&) if all of the following are true:
+                //  each direct and virtual base B of T has a copy constructor whose parameters are const B& or const volatile B&;
+                //  each non-static data member M of T of class type or array of class type has a copy constructor whose parameters are const M& or const volatile M&.
+                //
+                // The implicitly-declared or defaulted copy constructor for class T is defined as deleted if any of the following conditions are true:
+                // T is a union-like class and has a variant member with non-trivial copy constructor; // we don't support unions anyway
+                // T has a user-defined move constructor or move assignment operator (this condition only causes the implicitly-declared, not the defaulted, copy constructor to be deleted).
+                // T has non-static data members that cannot be copied (have deleted, inaccessible, or ambiguous copy constructors);
+                // T has direct or virtual base class that cannot be copied (has deleted, inaccessible, or ambiguous copy constructors);
+                // T has direct or virtual base class or a non-static data member with a deleted or inaccessible destructor;
+                // T has a data member of rvalue reference type;
+                let (const_copy_constructor, non_const_copy_constructor) = {
+                    let explicit_const = find_explicit(ExplicitKind::ConstCopyConstructor);
+                    let explicit_non_const = find_explicit(ExplicitKind::NonConstCopyConstructor);
+                    let explicit_move = find_explicit(ExplicitKind::MoveConstructor);
+
+                    // TODO: For https://github.com/google/autocxx/issues/815, replace both terms with something like:
+                    //   explicit.map_or(true, |explicit_found| matches!(explicit_found, ExplicitFound::Defaulted(_)))
+                    let have_defaulted = explicit_const.is_none() && explicit_non_const.is_none();
+                    if have_defaulted {
+                        // TODO: For https://github.com/google/autocxx/issues/815, ignore this if
+                        // the relevant (based on bases_are_const) copy constructor is explicitly defaulted.
+                        let class_allows = explicit_move.is_none() && !has_rvalue_reference_fields;
+                        let bases_allow = bases_items_found.iter().all(|items_found| {
+                            items_found.destructor.callable_subclass()
+                                && (items_found.const_copy_constructor.callable_subclass()
+                                    || items_found.non_const_copy_constructor.callable_subclass())
+                        });
+                        let members_allow = fields_items_found.iter().all(|items_found| {
+                            items_found.destructor.callable_any()
+                                && (items_found.const_copy_constructor.callable_any()
+                                    || items_found.non_const_copy_constructor.callable_any())
+                        });
+                        if class_allows && bases_allow && members_allow {
+                            // TODO: For https://github.com/google/autocxx/issues/815, grab the
+                            // visibility and existence of const and non-const from an explicit default if present.
+                            let dependencies_are_const = bases_items_found
+                                .iter()
+                                .chain(fields_items_found.iter())
+                                .all(|items_found| items_found.const_copy_constructor.exists());
+                            if dependencies_are_const {
+                                (SpecialMemberFound::Implicit, SpecialMemberFound::NotPresent)
+                            } else {
+                                (SpecialMemberFound::NotPresent, SpecialMemberFound::Implicit)
+                            }
+                        } else {
+                            (
+                                SpecialMemberFound::NotPresent,
+                                SpecialMemberFound::NotPresent,
+                            )
+                        }
+                    } else {
+                        (
+                            if let Some(ExplicitFound::UserDefined(visibility)) = explicit_const {
+                                SpecialMemberFound::Explicit(*visibility)
+                            } else {
+                                SpecialMemberFound::NotPresent
+                            },
+                            if let Some(ExplicitFound::UserDefined(visibility)) = explicit_non_const
+                            {
+                                SpecialMemberFound::Explicit(*visibility)
+                            } else {
+                                SpecialMemberFound::NotPresent
+                            },
+                        )
+                    }
+                };
+
+                // If no user-defined move constructors are provided for a class type (struct, class, or union), and all of the following is true:
+                // there are no user-declared copy constructors;
+                // there are no user-declared copy assignment operators;
+                // there are no user-declared move assignment operators;
+                // there is no user-declared destructor.
+                // then the compiler will declare a move constructor as a non-explicit inline public member of its class with the signature T::T(T&&).
+                //
+                // A class can have multiple move constructors, e.g. both T::T(const T&&) and T::T(T&&). If some user-defined move constructors are present, the user may still force the generation of the implicitly declared move constructor with the keyword default.
+                //
+                // The implicitly-declared or defaulted move constructor for class T is defined as deleted if any of the following is true:
+                // T has non-static data members that cannot be moved (have deleted, inaccessible, or ambiguous move constructors);
+                // T has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors);
+                // T has direct or virtual base class with a deleted or inaccessible destructor;
+                // T is a union-like class and has a variant member with non-trivial move constructor. // we don't support unions anyway
+                let move_constructor = {
+                    let explicit = find_explicit(ExplicitKind::MoveConstructor);
+                    // TODO: For https://github.com/google/autocxx/issues/815, replace relevant terms with something like:
+                    //   explicit.map_or(true, |explicit_found| matches!(explicit_found, ExplicitFound::Defaulted(_)))
+                    let have_defaulted = !(explicit.is_some()
+                        || find_explicit(ExplicitKind::ConstCopyConstructor).is_some()
+                        || find_explicit(ExplicitKind::NonConstCopyConstructor).is_some()
+                        || find_explicit(ExplicitKind::ConstCopyAssignmentOperator).is_some()
+                        || find_explicit(ExplicitKind::NonConstCopyAssignmentOperator).is_some()
+                        || find_explicit(ExplicitKind::MoveAssignmentOperator).is_some()
+                        || find_explicit(ExplicitKind::Destructor).is_some());
+                    if have_defaulted {
+                        let bases_allow = bases_items_found.iter().all(|items_found| {
+                            items_found.destructor.callable_subclass()
+                                && items_found.move_constructor.callable_subclass()
+                        });
+                        let members_allow = fields_items_found
+                            .iter()
+                            .all(|items_found| items_found.move_constructor.callable_any());
+                        if bases_allow && members_allow {
+                            // TODO: For https://github.com/google/autocxx/issues/815, grab the
+                            // visibility from an explicit default if present.
+                            SpecialMemberFound::Implicit
+                        } else {
+                            SpecialMemberFound::NotPresent
+                        }
+                    } else if let Some(ExplicitFound::UserDefined(visibility)) = explicit {
+                        SpecialMemberFound::Explicit(*visibility)
+                    } else {
+                        SpecialMemberFound::NotPresent
+                    }
+                };
+
+                let items_found = ItemsFound {
+                    default_constructor,
+                    destructor,
+                    const_copy_constructor,
+                    non_const_copy_constructor,
+                    move_constructor,
+                    name: Some(name.clone()),
+                };
+                log::info!(
+                    "Special member items found for {:?}: {:?}",
+                    name,
+                    items_found
+                );
+                items_found
+            };
+            assert!(
+                all_items_found
+                    .insert(name.name.clone(), items_found)
+                    .is_none(),
+                "Duplicate struct: {:?}",
+                name
+            );
+        }
+    }
+
+    all_items_found
+}
+
+fn find_explicit_items(
+    apis: &ApiVec<FnPrePhase1>,
+) -> (HashMap<ExplicitType, ExplicitFound>, HashSet<QualifiedName>) {
+    let mut result = HashMap::new();
+    let mut merge_fun = |ty: QualifiedName, kind: ExplicitKind, fun: &FuncToConvert| match result
+        .entry(ExplicitType { ty, kind })
+    {
+        Entry::Vacant(entry) => {
+            entry.insert(if fun.is_deleted {
+                ExplicitFound::Deleted
+            } else {
+                ExplicitFound::UserDefined(fun.cpp_vis)
+            });
+        }
+        Entry::Occupied(mut entry) => {
+            entry.insert(ExplicitFound::Multiple);
+        }
+    };
+    let mut unknown_types = HashSet::new();
+    for api in apis.iter() {
+        match api {
+            Api::Function {
+                analysis:
+                    FnAnalysis {
+                        kind: FnKind::Method { impl_for, .. },
+                        param_details,
+                        ignore_reason:
+                            Ok(()) | Err(ConvertErrorWithContext(ConvertError::AssignmentOperator, _)),
+                        ..
+                    },
+                fun,
+                ..
+            } if matches!(
+                fun.special_member,
+                Some(SpecialMemberKind::AssignmentOperator)
+            ) =>
+            {
+                let is_move_assignment_operator = !fun.references.rvalue_ref_params.is_empty();
+                merge_fun(
+                    impl_for.clone(),
+                    if is_move_assignment_operator {
+                        ExplicitKind::MoveAssignmentOperator
+                    } else {
+                        let receiver_mutability = &param_details
+                            .iter()
+                            .next()
+                            .unwrap()
+                            .self_type
+                            .as_ref()
+                            .unwrap()
+                            .1;
+                        match receiver_mutability {
+                            ReceiverMutability::Const => ExplicitKind::ConstCopyAssignmentOperator,
+                            ReceiverMutability::Mutable => {
+                                ExplicitKind::NonConstCopyAssignmentOperator
+                            }
+                        }
+                    },
+                    fun,
+                )
+            }
+            Api::Function {
+                analysis:
+                    FnAnalysis {
+                        kind: FnKind::Method { impl_for, .. },
+                        ..
+                    },
+                fun,
+                ..
+            } if matches!(
+                fun.special_member,
+                Some(SpecialMemberKind::AssignmentOperator)
+            ) =>
+            {
+                unknown_types.insert(impl_for.clone());
+            }
+            Api::Function {
+                analysis:
+                    FnAnalysis {
+                        kind:
+                            FnKind::Method {
+                                impl_for,
+                                method_kind,
+                                ..
+                            },
+                        ..
+                    },
+                fun,
+                ..
+            } => match method_kind {
+                MethodKind::Constructor { is_default: true } => {
+                    Some(ExplicitKind::DefaultConstructor)
+                }
+                MethodKind::Constructor { is_default: false } => {
+                    Some(ExplicitKind::OtherConstructor)
+                }
+                _ => None,
+            }
+            .map_or((), |explicit_kind| {
+                merge_fun(impl_for.clone(), explicit_kind, fun)
+            }),
+            Api::Function {
+                analysis:
+                    FnAnalysis {
+                        kind: FnKind::TraitMethod { impl_for, kind, .. },
+                        ..
+                    },
+                fun,
+                ..
+            } => match kind {
+                TraitMethodKind::Destructor => Some(ExplicitKind::Destructor),
+                // In `analyze_foreign_fn` we mark non-const copy constructors as not being copy
+                // constructors for now, so we don't have to worry about them.
+                TraitMethodKind::CopyConstructor => Some(ExplicitKind::ConstCopyConstructor),
+                TraitMethodKind::MoveConstructor => Some(ExplicitKind::MoveConstructor),
+                _ => None,
+            }
+            .map_or((), |explicit_kind| {
+                merge_fun(impl_for.clone(), explicit_kind, fun)
+            }),
+            _ => (),
+        }
+    }
+    (result, unknown_types)
+}
+
+/// Returns the information for a given known type.
+fn known_type_items_found(constructor_details: KnownTypeConstructorDetails) -> ItemsFound {
+    let exists_public = SpecialMemberFound::Explicit(CppVisibility::Public);
+    let exists_public_if = |exists| {
+        if exists {
+            exists_public
+        } else {
+            SpecialMemberFound::NotPresent
+        }
+    };
+    ItemsFound {
+        default_constructor: exists_public,
+        destructor: exists_public,
+        const_copy_constructor: exists_public_if(constructor_details.has_const_copy_constructor),
+        non_const_copy_constructor: SpecialMemberFound::NotPresent,
+        move_constructor: exists_public_if(constructor_details.has_move_constructor),
+        name: None,
+    }
+}
diff --git a/engine/src/conversion/analysis/fun/mod.rs b/engine/src/conversion/analysis/fun/mod.rs
new file mode 100644
index 0000000..19340f9
--- /dev/null
+++ b/engine/src/conversion/analysis/fun/mod.rs
@@ -0,0 +1,2140 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod bridge_name_tracker;
+pub(crate) mod function_wrapper;
+mod implicit_constructors;
+mod overload_tracker;
+mod subclass;
+
+use crate::{
+    conversion::{
+        analysis::{
+            fun::function_wrapper::{CppConversionType, CppFunctionKind},
+            type_converter::{self, add_analysis, TypeConversionContext, TypeConverter},
+        },
+        api::{
+            ApiName, CastMutability, CppVisibility, FuncToConvert, NullPhase, Provenance,
+            References, SpecialMemberKind, SubclassName, TraitImplSignature, TraitSynthesis,
+            UnsafetyNeeded, Virtualness,
+        },
+        apivec::ApiVec,
+        convert_error::ErrorContext,
+        convert_error::{ConvertErrorWithContext, ErrorContextType},
+        error_reporter::{convert_apis, report_any_error},
+    },
+    known_types::known_types,
+    types::validate_ident_ok_for_rust,
+};
+use indexmap::map::IndexMap as HashMap;
+use indexmap::set::IndexSet as HashSet;
+
+use autocxx_parser::{ExternCppType, IncludeCppConfig, UnsafePolicy};
+use function_wrapper::{CppFunction, CppFunctionBody, TypeConversionPolicy};
+use itertools::Itertools;
+use proc_macro2::Span;
+use quote::quote;
+use syn::{
+    parse_quote, punctuated::Punctuated, token::Comma, FnArg, Ident, Pat, ReturnType, Type,
+    TypePtr, Visibility,
+};
+
+use crate::{
+    conversion::{
+        api::{AnalysisPhase, Api, TypeKind},
+        ConvertError,
+    },
+    types::{make_ident, validate_ident_ok_for_cxx, Namespace, QualifiedName},
+};
+
+use self::{
+    bridge_name_tracker::BridgeNameTracker,
+    function_wrapper::RustConversionType,
+    implicit_constructors::{find_constructors_present, ItemsFound},
+    overload_tracker::OverloadTracker,
+    subclass::{
+        create_subclass_constructor, create_subclass_fn_wrapper, create_subclass_function,
+        create_subclass_trait_item,
+    },
+};
+
+use super::{
+    doc_label::make_doc_attrs,
+    pod::{PodAnalysis, PodPhase},
+    tdef::TypedefAnalysis,
+    type_converter::{Annotated, PointerTreatment},
+};
+
+#[derive(Clone, Debug)]
+pub(crate) enum ReceiverMutability {
+    Const,
+    Mutable,
+}
+
+#[derive(Clone, Debug)]
+pub(crate) enum MethodKind {
+    Normal(ReceiverMutability),
+    Constructor { is_default: bool },
+    Static,
+    Virtual(ReceiverMutability),
+    PureVirtual(ReceiverMutability),
+}
+
+#[derive(Clone)]
+pub(crate) enum TraitMethodKind {
+    CopyConstructor,
+    MoveConstructor,
+    Cast,
+    Destructor,
+    Alloc,
+    Dealloc,
+}
+
+#[derive(Clone)]
+pub(crate) struct TraitMethodDetails {
+    pub(crate) trt: TraitImplSignature,
+    pub(crate) avoid_self: bool,
+    pub(crate) method_name: Ident,
+    /// For traits, where we're trying to implement a specific existing
+    /// interface, we may need to reorder the parameters to fit that
+    /// interface.
+    pub(crate) parameter_reordering: Option<Vec<usize>>,
+    /// The function we're calling from the trait requires unsafe even
+    /// though the trait and its function aren't.
+    pub(crate) trait_call_is_unsafe: bool,
+}
+
+#[derive(Clone)]
+pub(crate) enum FnKind {
+    Function,
+    Method {
+        method_kind: MethodKind,
+        impl_for: QualifiedName,
+    },
+    TraitMethod {
+        kind: TraitMethodKind,
+        /// The name of the type T for which we're implementing a trait,
+        /// though we may be actually implementing the trait for &mut T or
+        /// similar, so we store more details of both the type and the
+        /// method in `details`
+        impl_for: QualifiedName,
+        details: Box<TraitMethodDetails>,
+    },
+}
+
+/// Strategy for ensuring that the final, callable, Rust name
+/// is what the user originally expected.
+#[derive(Clone)]
+
+pub(crate) enum RustRenameStrategy {
+    /// cxx::bridge name matches user expectations
+    None,
+    /// Even the #[rust_name] attribute would cause conflicts, and we need
+    /// to use a 'use XYZ as ABC'
+    RenameInOutputMod(Ident),
+    /// This function requires us to generate a Rust function to do
+    /// parameter conversion.
+    RenameUsingWrapperFunction,
+}
+
+#[derive(Clone)]
+pub(crate) struct FnAnalysis {
+    /// Each entry in the cxx::bridge needs to have a unique name, even if
+    /// (from the perspective of Rust and C++) things are in different
+    /// namespaces/mods.
+    pub(crate) cxxbridge_name: Ident,
+    /// ... so record also the name under which we wish to expose it in Rust.
+    pub(crate) rust_name: String,
+    pub(crate) rust_rename_strategy: RustRenameStrategy,
+    pub(crate) params: Punctuated<FnArg, Comma>,
+    pub(crate) kind: FnKind,
+    pub(crate) ret_type: ReturnType,
+    pub(crate) param_details: Vec<ArgumentAnalysis>,
+    pub(crate) ret_conversion: Option<TypeConversionPolicy>,
+    pub(crate) requires_unsafe: UnsafetyNeeded,
+    pub(crate) vis: Visibility,
+    pub(crate) cpp_wrapper: Option<CppFunction>,
+    pub(crate) deps: HashSet<QualifiedName>,
+    /// Some methods still need to be recorded because we want
+    /// to (a) generate the ability to call superclasses, (b) create
+    /// subclass entries for them. But we do not want to have them
+    /// be externally callable.
+    pub(crate) ignore_reason: Result<(), ConvertErrorWithContext>,
+    /// Whether this can be called by external code. Not so for
+    /// protected methods.
+    pub(crate) externally_callable: bool,
+    /// Whether we need to generate a Rust-side calling function
+    pub(crate) rust_wrapper_needed: bool,
+}
+
+#[derive(Clone)]
+pub(crate) struct ArgumentAnalysis {
+    pub(crate) conversion: TypeConversionPolicy,
+    pub(crate) name: Pat,
+    pub(crate) self_type: Option<(QualifiedName, ReceiverMutability)>,
+    pub(crate) has_lifetime: bool,
+    pub(crate) deps: HashSet<QualifiedName>,
+    pub(crate) requires_unsafe: UnsafetyNeeded,
+    pub(crate) is_placement_return_destination: bool,
+}
+
+struct ReturnTypeAnalysis {
+    rt: ReturnType,
+    conversion: Option<TypeConversionPolicy>,
+    was_reference: bool,
+    deps: HashSet<QualifiedName>,
+    placement_param_needed: Option<(FnArg, ArgumentAnalysis)>,
+}
+
+impl Default for ReturnTypeAnalysis {
+    fn default() -> Self {
+        Self {
+            rt: parse_quote! {},
+            conversion: None,
+            was_reference: false,
+            deps: Default::default(),
+            placement_param_needed: None,
+        }
+    }
+}
+
+pub(crate) struct PodAndConstructorAnalysis {
+    pub(crate) pod: PodAnalysis,
+    pub(crate) constructors: PublicConstructors,
+}
+
+/// An analysis phase where we've analyzed each function, but
+/// haven't yet determined which constructors/etc. belong to each type.
+pub(crate) struct FnPrePhase1;
+
+impl AnalysisPhase for FnPrePhase1 {
+    type TypedefAnalysis = TypedefAnalysis;
+    type StructAnalysis = PodAnalysis;
+    type FunAnalysis = FnAnalysis;
+}
+
+/// An analysis phase where we've analyzed each function, and identified
+/// what implicit constructors/destructors are present in each type.
+pub(crate) struct FnPrePhase2;
+
+impl AnalysisPhase for FnPrePhase2 {
+    type TypedefAnalysis = TypedefAnalysis;
+    type StructAnalysis = PodAndConstructorAnalysis;
+    type FunAnalysis = FnAnalysis;
+}
+
+pub(crate) struct PodAndDepAnalysis {
+    pub(crate) pod: PodAnalysis,
+    pub(crate) constructor_and_allocator_deps: Vec<QualifiedName>,
+    pub(crate) constructors: PublicConstructors,
+}
+
+/// Analysis phase after we've finished analyzing functions and determined
+/// which constructors etc. belong to them.
+pub(crate) struct FnPhase;
+
+/// Indicates which kinds of public constructors are known to exist for a type.
+#[derive(Debug, Default, Copy, Clone)]
+pub(crate) struct PublicConstructors {
+    pub(crate) move_constructor: bool,
+    pub(crate) destructor: bool,
+}
+
+impl PublicConstructors {
+    fn from_items_found(items_found: &ItemsFound) -> Self {
+        Self {
+            move_constructor: items_found.move_constructor.callable_any(),
+            destructor: items_found.destructor.callable_any(),
+        }
+    }
+}
+
+impl AnalysisPhase for FnPhase {
+    type TypedefAnalysis = TypedefAnalysis;
+    type StructAnalysis = PodAndDepAnalysis;
+    type FunAnalysis = FnAnalysis;
+}
+
+/// Whether to allow highly optimized calls because this is a simple Rust->C++ call,
+/// or to use a simpler set of policies because this is a subclass call where
+/// we may have C++->Rust->C++ etc.
+#[derive(Copy, Clone)]
+enum TypeConversionSophistication {
+    Regular,
+    SimpleForSubclasses,
+}
+
+pub(crate) struct FnAnalyzer<'a> {
+    unsafe_policy: UnsafePolicy,
+    extra_apis: ApiVec<NullPhase>,
+    type_converter: TypeConverter<'a>,
+    bridge_name_tracker: BridgeNameTracker,
+    pod_safe_types: HashSet<QualifiedName>,
+    moveit_safe_types: HashSet<QualifiedName>,
+    config: &'a IncludeCppConfig,
+    overload_trackers_by_mod: HashMap<Namespace, OverloadTracker>,
+    subclasses_by_superclass: HashMap<QualifiedName, Vec<SubclassName>>,
+    nested_type_name_map: HashMap<QualifiedName, String>,
+    generic_types: HashSet<QualifiedName>,
+    types_in_anonymous_namespace: HashSet<QualifiedName>,
+    existing_superclass_trait_api_names: HashSet<QualifiedName>,
+}
+
+impl<'a> FnAnalyzer<'a> {
+    pub(crate) fn analyze_functions(
+        apis: ApiVec<PodPhase>,
+        unsafe_policy: UnsafePolicy,
+        config: &'a IncludeCppConfig,
+    ) -> ApiVec<FnPrePhase2> {
+        let mut me = Self {
+            unsafe_policy,
+            extra_apis: ApiVec::new(),
+            type_converter: TypeConverter::new(config, &apis),
+            bridge_name_tracker: BridgeNameTracker::new(),
+            config,
+            overload_trackers_by_mod: HashMap::new(),
+            pod_safe_types: Self::build_pod_safe_type_set(&apis),
+            moveit_safe_types: Self::build_correctly_sized_type_set(&apis),
+            subclasses_by_superclass: subclass::subclasses_by_superclass(&apis),
+            nested_type_name_map: Self::build_nested_type_map(&apis),
+            generic_types: Self::build_generic_type_set(&apis),
+            existing_superclass_trait_api_names: HashSet::new(),
+            types_in_anonymous_namespace: Self::build_types_in_anonymous_namespace(&apis),
+        };
+        let mut results = ApiVec::new();
+        convert_apis(
+            apis,
+            &mut results,
+            |name, fun, _| me.analyze_foreign_fn_and_subclasses(name, fun),
+            Api::struct_unchanged,
+            Api::enum_unchanged,
+            Api::typedef_unchanged,
+        );
+        let mut results = me.add_constructors_present(results);
+        me.add_subclass_constructors(&mut results);
+        results.extend(me.extra_apis.into_iter().map(add_analysis));
+        results
+    }
+
+    fn build_pod_safe_type_set(apis: &ApiVec<PodPhase>) -> HashSet<QualifiedName> {
+        apis.iter()
+            .filter_map(|api| match api {
+                Api::Struct {
+                    analysis:
+                        PodAnalysis {
+                            kind: TypeKind::Pod,
+                            ..
+                        },
+                    ..
+                } => Some(api.name().clone()),
+                Api::Enum { .. } => Some(api.name().clone()),
+                Api::ExternCppType { pod: true, .. } => Some(api.name().clone()),
+                _ => None,
+            })
+            .chain(
+                known_types()
+                    .get_pod_safe_types()
+                    .filter_map(
+                        |(tn, is_pod_safe)| {
+                            if is_pod_safe {
+                                Some(tn)
+                            } else {
+                                None
+                            }
+                        },
+                    ),
+            )
+            .collect()
+    }
+
+    /// Return the set of 'moveit safe' types. That must include only types where
+    /// the size is known to be correct.
+    fn build_correctly_sized_type_set(apis: &ApiVec<PodPhase>) -> HashSet<QualifiedName> {
+        apis.iter()
+            .filter(|api| {
+                matches!(
+                    api,
+                    Api::Struct { .. }
+                        | Api::Enum { .. }
+                        | Api::ExternCppType {
+                            details: ExternCppType { opaque: false, .. },
+                            ..
+                        }
+                )
+            })
+            .map(|api| api.name().clone())
+            .chain(known_types().get_moveit_safe_types())
+            .collect()
+    }
+
+    fn build_generic_type_set(apis: &ApiVec<PodPhase>) -> HashSet<QualifiedName> {
+        apis.iter()
+            .filter_map(|api| match api {
+                Api::Struct {
+                    analysis:
+                        PodAnalysis {
+                            is_generic: true, ..
+                        },
+                    ..
+                } => Some(api.name().clone()),
+                _ => None,
+            })
+            .collect()
+    }
+
+    fn build_types_in_anonymous_namespace(apis: &ApiVec<PodPhase>) -> HashSet<QualifiedName> {
+        apis.iter()
+            .filter_map(|api| match api {
+                Api::Struct {
+                    analysis:
+                        PodAnalysis {
+                            in_anonymous_namespace: true,
+                            ..
+                        },
+                    ..
+                } => Some(api.name().clone()),
+                _ => None,
+            })
+            .collect()
+    }
+
+    /// Builds a mapping from a qualified type name to the last 'nest'
+    /// of its name, if it has multiple elements.
+    fn build_nested_type_map(apis: &ApiVec<PodPhase>) -> HashMap<QualifiedName, String> {
+        apis.iter()
+            .filter_map(|api| match api {
+                Api::Struct { name, .. } | Api::Enum { name, .. } => {
+                    let cpp_name = name
+                        .cpp_name_if_present()
+                        .cloned()
+                        .unwrap_or_else(|| name.name.get_final_item().to_string());
+                    cpp_name
+                        .rsplit_once("::")
+                        .map(|(_, suffix)| (name.name.clone(), suffix.to_string()))
+                }
+                _ => None,
+            })
+            .collect()
+    }
+
+    fn convert_boxed_type(
+        &mut self,
+        ty: Box<Type>,
+        ns: &Namespace,
+        pointer_treatment: PointerTreatment,
+    ) -> Result<Annotated<Box<Type>>, ConvertError> {
+        let ctx = TypeConversionContext::OuterType { pointer_treatment };
+        let mut annotated = self.type_converter.convert_boxed_type(ty, ns, &ctx)?;
+        self.extra_apis.append(&mut annotated.extra_apis);
+        Ok(annotated)
+    }
+
+    fn get_cxx_bridge_name(
+        &mut self,
+        type_name: Option<&str>,
+        found_name: &str,
+        ns: &Namespace,
+    ) -> String {
+        self.bridge_name_tracker
+            .get_unique_cxx_bridge_name(type_name, found_name, ns)
+    }
+
+    fn is_on_allowlist(&self, type_name: &QualifiedName) -> bool {
+        self.config.is_on_allowlist(&type_name.to_cpp_name())
+    }
+
+    fn is_generic_type(&self, type_name: &QualifiedName) -> bool {
+        self.generic_types.contains(type_name)
+    }
+
+    #[allow(clippy::if_same_then_else)] // clippy bug doesn't notice the two
+                                        // closures below are different.
+    fn should_be_unsafe(
+        &self,
+        param_details: &[ArgumentAnalysis],
+        kind: &FnKind,
+    ) -> UnsafetyNeeded {
+        let unsafest_non_placement_param = UnsafetyNeeded::from_param_details(param_details, true);
+        let unsafest_param = UnsafetyNeeded::from_param_details(param_details, false);
+        match kind {
+            // Trait unsafety must always correspond to the norms for the
+            // trait we're implementing.
+            FnKind::TraitMethod {
+                kind:
+                    TraitMethodKind::CopyConstructor
+                    | TraitMethodKind::MoveConstructor
+                    | TraitMethodKind::Alloc
+                    | TraitMethodKind::Dealloc,
+                ..
+            } => UnsafetyNeeded::Always,
+            FnKind::TraitMethod { .. } => match unsafest_param {
+                UnsafetyNeeded::Always => UnsafetyNeeded::JustBridge,
+                _ => unsafest_param,
+            },
+            _ if self.unsafe_policy == UnsafePolicy::AllFunctionsUnsafe => UnsafetyNeeded::Always,
+            _ => match unsafest_non_placement_param {
+                UnsafetyNeeded::Always => UnsafetyNeeded::Always,
+                UnsafetyNeeded::JustBridge => match unsafest_param {
+                    UnsafetyNeeded::Always => UnsafetyNeeded::JustBridge,
+                    _ => unsafest_non_placement_param,
+                },
+                UnsafetyNeeded::None => match unsafest_param {
+                    UnsafetyNeeded::Always => UnsafetyNeeded::JustBridge,
+                    _ => unsafest_param,
+                },
+            },
+        }
+    }
+
+    fn add_subclass_constructors(&mut self, apis: &mut ApiVec<FnPrePhase2>) {
+        let mut results = ApiVec::new();
+
+        // Pre-assemble a list of types with known destructors, to avoid having to
+        // do a O(n^2) nested loop.
+        let types_with_destructors: HashSet<_> = apis
+            .iter()
+            .filter_map(|api| match api {
+                Api::Function {
+                    fun,
+                    analysis:
+                        FnAnalysis {
+                            kind: FnKind::TraitMethod { impl_for, .. },
+                            ..
+                        },
+                    ..
+                } if matches!(
+                    **fun,
+                    FuncToConvert {
+                        special_member: Some(SpecialMemberKind::Destructor),
+                        is_deleted: false,
+                        cpp_vis: CppVisibility::Public,
+                        ..
+                    }
+                ) =>
+                {
+                    Some(impl_for)
+                }
+                _ => None,
+            })
+            .cloned()
+            .collect();
+
+        for api in apis.iter() {
+            if let Api::Function {
+                fun,
+                analysis:
+                    analysis @ FnAnalysis {
+                        kind:
+                            FnKind::Method {
+                                impl_for: sup,
+                                method_kind: MethodKind::Constructor { .. },
+                                ..
+                            },
+                        ..
+                    },
+                ..
+            } = api
+            {
+                // If we don't have an accessible destructor, then std::unique_ptr cannot be
+                // instantiated for this C++ type.
+                if !types_with_destructors.contains(sup) {
+                    continue;
+                }
+
+                for sub in self.subclasses_by_superclass(sup) {
+                    // Create a subclass constructor. This is a synthesized function
+                    // which didn't exist in the original C++.
+                    let (subclass_constructor_func, subclass_constructor_name) =
+                        create_subclass_constructor(sub, analysis, sup, fun);
+                    self.analyze_and_add(
+                        subclass_constructor_name.clone(),
+                        subclass_constructor_func.clone(),
+                        &mut results,
+                        TypeConversionSophistication::Regular,
+                    );
+                }
+            }
+        }
+        apis.extend(results.into_iter());
+    }
+
+    /// Analyze a given function, and any permutations of that function which
+    /// we might additionally generate (e.g. for subclasses.)
+    ///
+    /// Leaves the [`FnKind::Method::type_constructors`] at its default for [`add_constructors_present`]
+    /// to fill out.
+    fn analyze_foreign_fn_and_subclasses(
+        &mut self,
+        name: ApiName,
+        fun: Box<FuncToConvert>,
+    ) -> Result<Box<dyn Iterator<Item = Api<FnPrePhase1>>>, ConvertErrorWithContext> {
+        let (analysis, name) =
+            self.analyze_foreign_fn(name, &fun, TypeConversionSophistication::Regular, None);
+        let mut results = ApiVec::new();
+
+        // Consider whether we need to synthesize subclass items.
+        if let FnKind::Method {
+            impl_for: sup,
+            method_kind:
+                MethodKind::Virtual(receiver_mutability) | MethodKind::PureVirtual(receiver_mutability),
+            ..
+        } = &analysis.kind
+        {
+            let (simpler_analysis, _) = self.analyze_foreign_fn(
+                name.clone(),
+                &fun,
+                TypeConversionSophistication::SimpleForSubclasses,
+                Some(analysis.rust_name.clone()),
+            );
+            for sub in self.subclasses_by_superclass(sup) {
+                // For each subclass, we need to create a plain-C++ method to call its superclass
+                // and a Rust/C++ bridge API to call _that_.
+                // What we're generating here is entirely about the subclass, so the
+                // superclass's namespace is irrelevant. We generate
+                // all subclasses in the root namespace.
+                let is_pure_virtual = matches!(
+                    &simpler_analysis.kind,
+                    FnKind::Method {
+                        method_kind: MethodKind::PureVirtual(..),
+                        ..
+                    }
+                );
+
+                let super_fn_call_name =
+                    SubclassName::get_super_fn_name(&Namespace::new(), &analysis.rust_name);
+                let super_fn_api_name = SubclassName::get_super_fn_name(
+                    &Namespace::new(),
+                    &analysis.cxxbridge_name.to_string(),
+                );
+                let trait_api_name = SubclassName::get_trait_api_name(sup, &analysis.rust_name);
+
+                let mut subclass_fn_deps = vec![trait_api_name.clone()];
+                if !is_pure_virtual {
+                    // Create a C++ API representing the superclass implementation (allowing
+                    // calls from Rust->C++)
+                    let maybe_wrap = create_subclass_fn_wrapper(&sub, &super_fn_call_name, &fun);
+                    let super_fn_name = ApiName::new_from_qualified_name(super_fn_api_name);
+                    let super_fn_call_api_name = self.analyze_and_add(
+                        super_fn_name,
+                        maybe_wrap,
+                        &mut results,
+                        TypeConversionSophistication::SimpleForSubclasses,
+                    );
+                    subclass_fn_deps.push(super_fn_call_api_name);
+                }
+
+                // Create the Rust API representing the subclass implementation (allowing calls
+                // from C++ -> Rust)
+                results.push(create_subclass_function(
+                    // RustSubclassFn
+                    &sub,
+                    &simpler_analysis,
+                    &name,
+                    receiver_mutability,
+                    sup,
+                    subclass_fn_deps,
+                ));
+
+                // Create the trait item for the <superclass>_methods and <superclass>_supers
+                // traits. This is required per-superclass, not per-subclass, so don't
+                // create it if it already exists.
+                if !self
+                    .existing_superclass_trait_api_names
+                    .contains(&trait_api_name)
+                {
+                    self.existing_superclass_trait_api_names
+                        .insert(trait_api_name.clone());
+                    results.push(create_subclass_trait_item(
+                        ApiName::new_from_qualified_name(trait_api_name),
+                        &simpler_analysis,
+                        receiver_mutability,
+                        sup.clone(),
+                        is_pure_virtual,
+                    ));
+                }
+            }
+        }
+
+        results.push(Api::Function {
+            fun,
+            analysis,
+            name,
+        });
+
+        Ok(Box::new(results.into_iter()))
+    }
+
+    /// Adds an API, usually a synthesized API. Returns the final calculated API name, which can be used
+    /// for others to depend on this.
+    fn analyze_and_add<P: AnalysisPhase<FunAnalysis = FnAnalysis>>(
+        &mut self,
+        name: ApiName,
+        new_func: Box<FuncToConvert>,
+        results: &mut ApiVec<P>,
+        sophistication: TypeConversionSophistication,
+    ) -> QualifiedName {
+        let (analysis, name) = self.analyze_foreign_fn(name, &new_func, sophistication, None);
+        results.push(Api::Function {
+            fun: new_func,
+            analysis,
+            name: name.clone(),
+        });
+        name.name
+    }
+
+    /// Determine how to materialize a function.
+    ///
+    /// The main job here is to determine whether a function can simply be noted
+    /// in the [cxx::bridge] mod and passed directly to cxx, or if it needs a Rust-side
+    /// wrapper function, or if it needs a C++-side wrapper function, or both.
+    /// We aim for the simplest case but, for example:
+    /// * We'll need a C++ wrapper for static methods
+    /// * We'll need a C++ wrapper for parameters which need to be wrapped and unwrapped
+    ///   to [cxx::UniquePtr]
+    /// * We'll need a Rust wrapper if we've got a C++ wrapper and it's a method.
+    /// * We may need wrappers if names conflict.
+    /// etc.
+    /// The other major thing we do here is figure out naming for the function.
+    /// This depends on overloads, and what other functions are floating around.
+    /// The output of this analysis phase is used by both Rust and C++ codegen.
+    fn analyze_foreign_fn(
+        &mut self,
+        name: ApiName,
+        fun: &FuncToConvert,
+        sophistication: TypeConversionSophistication,
+        predetermined_rust_name: Option<String>,
+    ) -> (FnAnalysis, ApiName) {
+        let mut cpp_name = name.cpp_name_if_present().cloned();
+        let ns = name.name.get_namespace();
+
+        // Let's gather some pre-wisdom about the name of the function.
+        // We're shortly going to plunge into analyzing the parameters,
+        // and it would be nice to have some idea of the function name
+        // for diagnostics whilst we do that.
+        let initial_rust_name = fun.ident.to_string();
+        let diagnostic_display_name = cpp_name.as_ref().unwrap_or(&initial_rust_name);
+
+        // Now let's analyze all the parameters.
+        // See if any have annotations which our fork of bindgen has craftily inserted...
+        let (param_details, bads): (Vec<_>, Vec<_>) = fun
+            .inputs
+            .iter()
+            .map(|i| {
+                self.convert_fn_arg(
+                    i,
+                    ns,
+                    diagnostic_display_name,
+                    &fun.synthesized_this_type,
+                    &fun.references,
+                    true,
+                    false,
+                    None,
+                    sophistication,
+                    false,
+                )
+            })
+            .partition(Result::is_ok);
+        let (mut params, mut param_details): (Punctuated<_, Comma>, Vec<_>) =
+            param_details.into_iter().map(Result::unwrap).unzip();
+
+        let params_deps: HashSet<_> = param_details
+            .iter()
+            .flat_map(|p| p.deps.iter().cloned())
+            .collect();
+        let self_ty = param_details
+            .iter()
+            .filter_map(|pd| pd.self_type.as_ref())
+            .next()
+            .cloned();
+
+        // End of parameter processing.
+        // Work out naming, part one.
+        // bindgen may have mangled the name either because it's invalid Rust
+        // syntax (e.g. a keyword like 'async') or it's an overload.
+        // If the former, we respect that mangling. If the latter, we don't,
+        // because we'll add our own overload counting mangling later.
+        // Cases:
+        //   function, IRN=foo,    CN=<none>                    output: foo    case 1
+        //   function, IRN=move_,  CN=move   (keyword problem)  output: move_  case 2
+        //   function, IRN=foo1,   CN=foo    (overload)         output: foo    case 3
+        //   method,   IRN=A_foo,  CN=foo                       output: foo    case 4
+        //   method,   IRN=A_move, CN=move   (keyword problem)  output: move_  case 5
+        //   method,   IRN=A_foo1, CN=foo    (overload)         output: foo    case 6
+        let ideal_rust_name = match &cpp_name {
+            None => initial_rust_name, // case 1
+            Some(cpp_name) => {
+                if initial_rust_name.ends_with('_') {
+                    initial_rust_name // case 2
+                } else if validate_ident_ok_for_rust(cpp_name).is_err() {
+                    format!("{}_", cpp_name) // case 5
+                } else {
+                    cpp_name.to_string() // cases 3, 4, 6
+                }
+            }
+        };
+
+        // Let's spend some time figuring out the kind of this function (i.e. method,
+        // virtual function, etc.)
+        // Part one, work out if this is a static method.
+        let (is_static_method, self_ty, receiver_mutability) = match self_ty {
+            None => {
+                // Even if we can't find a 'self' parameter this could conceivably
+                // be a static method.
+                let self_ty = fun.self_ty.clone();
+                (self_ty.is_some(), self_ty, None)
+            }
+            Some((self_ty, receiver_mutability)) => {
+                (false, Some(self_ty), Some(receiver_mutability))
+            }
+        };
+
+        // Part two, work out if this is a function, or method, or whatever.
+        // First determine if this is actually a trait implementation.
+        let trait_details = self.trait_creation_details_for_synthetic_function(
+            &fun.add_to_trait,
+            ns,
+            &ideal_rust_name,
+            &self_ty,
+        );
+        let (kind, error_context, rust_name) = if let Some(trait_details) = trait_details {
+            trait_details
+        } else if let Some(self_ty) = self_ty {
+            // Some kind of method or static method.
+            let type_ident = self_ty.get_final_item();
+            // bindgen generates methods with the name:
+            // {class}_{method name}
+            // It then generates an impl section for the Rust type
+            // with the original name, but we currently discard that impl section.
+            // We want to feed cxx methods with just the method name, so let's
+            // strip off the class name.
+            let mut rust_name = ideal_rust_name;
+            let nested_type_ident = self
+                .nested_type_name_map
+                .get(&self_ty)
+                .map(|s| s.as_str())
+                .unwrap_or_else(|| self_ty.get_final_item());
+            if matches!(
+                fun.special_member,
+                Some(SpecialMemberKind::CopyConstructor | SpecialMemberKind::MoveConstructor)
+            ) {
+                let is_move =
+                    matches!(fun.special_member, Some(SpecialMemberKind::MoveConstructor));
+                if let Some(constructor_suffix) = rust_name.strip_prefix(nested_type_ident) {
+                    rust_name = format!("new{}", constructor_suffix);
+                }
+                rust_name = predetermined_rust_name
+                    .unwrap_or_else(|| self.get_overload_name(ns, type_ident, rust_name));
+                let error_context = self.error_context_for_method(&self_ty, &rust_name);
+
+                // If this is 'None', then something weird is going on. We'll check for that
+                // later when we have enough context to generate useful errors.
+                let arg_is_reference = matches!(
+                    param_details
+                        .get(1)
+                        .map(|param| &param.conversion.unwrapped_type),
+                    Some(Type::Reference(_))
+                );
+                // Some exotic forms of copy constructor have const and/or volatile qualifiers.
+                // These are not sufficient to implement CopyNew, so we just treat them as regular
+                // constructors. We detect them by their argument being translated to Pin at this
+                // point.
+                if is_move || arg_is_reference {
+                    let (kind, method_name, trait_id) = if is_move {
+                        (
+                            TraitMethodKind::MoveConstructor,
+                            "move_new",
+                            quote! { MoveNew },
+                        )
+                    } else {
+                        (
+                            TraitMethodKind::CopyConstructor,
+                            "copy_new",
+                            quote! { CopyNew },
+                        )
+                    };
+                    let ty = Type::Path(self_ty.to_type_path());
+                    (
+                        FnKind::TraitMethod {
+                            kind,
+                            impl_for: self_ty,
+                            details: Box::new(TraitMethodDetails {
+                                trt: TraitImplSignature {
+                                    ty,
+                                    trait_signature: parse_quote! {
+                                        autocxx::moveit::new:: #trait_id
+                                    },
+                                    unsafety: Some(parse_quote! { unsafe }),
+                                },
+                                avoid_self: true,
+                                method_name: make_ident(method_name),
+                                parameter_reordering: Some(vec![1, 0]),
+                                trait_call_is_unsafe: false,
+                            }),
+                        },
+                        error_context,
+                        rust_name,
+                    )
+                } else {
+                    (
+                        FnKind::Method {
+                            impl_for: self_ty,
+                            method_kind: MethodKind::Constructor { is_default: false },
+                        },
+                        error_context,
+                        rust_name,
+                    )
+                }
+            } else if matches!(fun.special_member, Some(SpecialMemberKind::Destructor)) {
+                rust_name = predetermined_rust_name
+                    .unwrap_or_else(|| self.get_overload_name(ns, type_ident, rust_name));
+                let error_context = self.error_context_for_method(&self_ty, &rust_name);
+                let ty = Type::Path(self_ty.to_type_path());
+                (
+                    FnKind::TraitMethod {
+                        kind: TraitMethodKind::Destructor,
+                        impl_for: self_ty,
+                        details: Box::new(TraitMethodDetails {
+                            trt: TraitImplSignature {
+                                ty,
+                                trait_signature: parse_quote! {
+                                    Drop
+                                },
+                                unsafety: None,
+                            },
+                            avoid_self: false,
+                            method_name: make_ident("drop"),
+                            parameter_reordering: None,
+                            trait_call_is_unsafe: false,
+                        }),
+                    },
+                    error_context,
+                    rust_name,
+                )
+            } else {
+                let method_kind = if let Some(constructor_suffix) =
+                    constructor_with_suffix(&rust_name, nested_type_ident)
+                {
+                    // It's a constructor. bindgen generates
+                    // fn Type(this: *mut Type, ...args)
+                    // We want
+                    // fn new(this: *mut Type, ...args)
+                    // Later code will spot this and re-enter us, and we'll make
+                    // a duplicate function in the above 'if' clause like this:
+                    // fn make_unique(...args) -> Type
+                    // which later code will convert to
+                    // fn make_unique(...args) -> UniquePtr<Type>
+                    // If there are multiple constructors, bindgen generates
+                    // new, new1, new2 etc. and we'll keep those suffixes.
+                    rust_name = format!("new{}", constructor_suffix);
+                    MethodKind::Constructor {
+                        is_default: matches!(
+                            fun.special_member,
+                            Some(SpecialMemberKind::DefaultConstructor)
+                        ),
+                    }
+                } else if is_static_method {
+                    MethodKind::Static
+                } else {
+                    let receiver_mutability =
+                        receiver_mutability.expect("Failed to find receiver details");
+                    match fun.virtualness {
+                        Virtualness::None => MethodKind::Normal(receiver_mutability),
+                        Virtualness::Virtual => MethodKind::Virtual(receiver_mutability),
+                        Virtualness::PureVirtual => MethodKind::PureVirtual(receiver_mutability),
+                    }
+                };
+                // Disambiguate overloads.
+                let rust_name = predetermined_rust_name
+                    .unwrap_or_else(|| self.get_overload_name(ns, type_ident, rust_name));
+                let error_context = self.error_context_for_method(&self_ty, &rust_name);
+                (
+                    FnKind::Method {
+                        impl_for: self_ty,
+                        method_kind,
+                    },
+                    error_context,
+                    rust_name,
+                )
+            }
+        } else {
+            // Not a method.
+            // What shall we call this function? It may be overloaded.
+            let rust_name = self.get_function_overload_name(ns, ideal_rust_name);
+            (
+                FnKind::Function,
+                ErrorContext::new_for_item(make_ident(&rust_name)),
+                rust_name,
+            )
+        };
+
+        // If we encounter errors from here on, we can give some context around
+        // where the error occurred such that we can put a marker in the output
+        // Rust code to indicate that a problem occurred (benefiting people using
+        // rust-analyzer or similar). Make a closure to make this easy.
+        let mut ignore_reason = Ok(());
+        let mut set_ignore_reason =
+            |err| ignore_reason = Err(ConvertErrorWithContext(err, Some(error_context.clone())));
+
+        // Now we have figured out the type of function (from its parameters)
+        // we might have determined that we have a constructor. If so,
+        // annoyingly, we need to go back and fiddle with the parameters in a
+        // different way. This is because we want the first parameter to be a
+        // pointer not a reference. For copy + move constructors, we also
+        // enforce Rust-side conversions to comply with moveit traits.
+        match kind {
+            FnKind::Method {
+                method_kind: MethodKind::Constructor { .. },
+                ..
+            } => {
+                self.reanalyze_parameter(
+                    0,
+                    fun,
+                    ns,
+                    &rust_name,
+                    &mut params,
+                    &mut param_details,
+                    None,
+                    sophistication,
+                    true,
+                    false,
+                )
+                .unwrap_or_else(&mut set_ignore_reason);
+            }
+
+            FnKind::TraitMethod {
+                kind: TraitMethodKind::Destructor,
+                ..
+            } => {
+                self.reanalyze_parameter(
+                    0,
+                    fun,
+                    ns,
+                    &rust_name,
+                    &mut params,
+                    &mut param_details,
+                    Some(RustConversionType::FromTypeToPtr),
+                    sophistication,
+                    false,
+                    false,
+                )
+                .unwrap_or_else(&mut set_ignore_reason);
+            }
+            FnKind::TraitMethod {
+                kind: TraitMethodKind::CopyConstructor,
+                ..
+            } => {
+                if param_details.len() < 2 {
+                    set_ignore_reason(ConvertError::ConstructorWithOnlyOneParam);
+                }
+                if param_details.len() > 2 {
+                    set_ignore_reason(ConvertError::ConstructorWithMultipleParams);
+                }
+                self.reanalyze_parameter(
+                    0,
+                    fun,
+                    ns,
+                    &rust_name,
+                    &mut params,
+                    &mut param_details,
+                    Some(RustConversionType::FromPinMaybeUninitToPtr),
+                    sophistication,
+                    false,
+                    false,
+                )
+                .unwrap_or_else(&mut set_ignore_reason);
+            }
+
+            FnKind::TraitMethod {
+                kind: TraitMethodKind::MoveConstructor,
+                ..
+            } => {
+                if param_details.len() < 2 {
+                    set_ignore_reason(ConvertError::ConstructorWithOnlyOneParam);
+                }
+                if param_details.len() > 2 {
+                    set_ignore_reason(ConvertError::ConstructorWithMultipleParams);
+                }
+                self.reanalyze_parameter(
+                    0,
+                    fun,
+                    ns,
+                    &rust_name,
+                    &mut params,
+                    &mut param_details,
+                    Some(RustConversionType::FromPinMaybeUninitToPtr),
+                    sophistication,
+                    false,
+                    false,
+                )
+                .unwrap_or_else(&mut set_ignore_reason);
+                self.reanalyze_parameter(
+                    1,
+                    fun,
+                    ns,
+                    &rust_name,
+                    &mut params,
+                    &mut param_details,
+                    Some(RustConversionType::FromPinMoveRefToPtr),
+                    sophistication,
+                    false,
+                    true,
+                )
+                .unwrap_or_else(&mut set_ignore_reason);
+            }
+            _ => {}
+        }
+
+        // Now we can add context to the error, check for a variety of error
+        // cases. In each case, we continue to record the API, because it might
+        // influence our later decisions to generate synthetic constructors
+        // or note whether the type is abstract.
+        let externally_callable = match fun.cpp_vis {
+            CppVisibility::Private => {
+                set_ignore_reason(ConvertError::PrivateMethod);
+                false
+            }
+            CppVisibility::Protected => false,
+            CppVisibility::Public => true,
+        };
+        if fun.variadic {
+            set_ignore_reason(ConvertError::Variadic);
+        }
+        if let Some(problem) = bads.into_iter().next() {
+            match problem {
+                Ok(_) => panic!("No error in the error"),
+                Err(problem) => set_ignore_reason(problem),
+            }
+        } else if fun.unused_template_param {
+            // This indicates that bindgen essentially flaked out because templates
+            // were too complex.
+            set_ignore_reason(ConvertError::UnusedTemplateParam)
+        } else if matches!(
+            fun.special_member,
+            Some(SpecialMemberKind::AssignmentOperator)
+        ) {
+            // Be careful with the order of this if-else tree. Anything above here means we won't
+            // treat it as an assignment operator, but anything below we still consider when
+            // deciding which other C++ special member functions are implicitly defined.
+            set_ignore_reason(ConvertError::AssignmentOperator)
+        } else if fun.references.rvalue_ref_return {
+            set_ignore_reason(ConvertError::RValueReturn)
+        } else if fun.is_deleted {
+            set_ignore_reason(ConvertError::Deleted)
+        } else {
+            match kind {
+                FnKind::Method {
+                    ref impl_for,
+                    method_kind:
+                        MethodKind::Constructor { .. }
+                        | MethodKind::Normal(..)
+                        | MethodKind::PureVirtual(..)
+                        | MethodKind::Virtual(..),
+                    ..
+                } if !known_types().is_cxx_acceptable_receiver(impl_for) => {
+                    set_ignore_reason(ConvertError::UnsupportedReceiver);
+                }
+                FnKind::Method { ref impl_for, .. } if !self.is_on_allowlist(impl_for) => {
+                    // Bindgen will output methods for types which have been encountered
+                    // virally as arguments on other allowlisted types. But we don't want
+                    // to generate methods unless the user has specifically asked us to.
+                    // It may, for instance, be a private type.
+                    set_ignore_reason(ConvertError::MethodOfNonAllowlistedType);
+                }
+                FnKind::Method { ref impl_for, .. } | FnKind::TraitMethod { ref impl_for, .. } => {
+                    if self.is_generic_type(impl_for) {
+                        set_ignore_reason(ConvertError::MethodOfGenericType);
+                    }
+                    if self.types_in_anonymous_namespace.contains(impl_for) {
+                        set_ignore_reason(ConvertError::MethodInAnonymousNamespace);
+                    }
+                }
+                _ => {}
+            }
+        };
+
+        // The name we use within the cxx::bridge mod may be different
+        // from both the C++ name and the Rust name, because it's a flat
+        // namespace so we might need to prepend some stuff to make it unique.
+        let cxxbridge_name = self.get_cxx_bridge_name(
+            match kind {
+                FnKind::Method { ref impl_for, .. } => Some(impl_for.get_final_item()),
+                FnKind::Function => None,
+                FnKind::TraitMethod { ref impl_for, .. } => Some(impl_for.get_final_item()),
+            },
+            &rust_name,
+            ns,
+        );
+        if cxxbridge_name != rust_name && cpp_name.is_none() {
+            cpp_name = Some(rust_name.clone());
+        }
+        let mut cxxbridge_name = make_ident(&cxxbridge_name);
+
+        // Analyze the return type, just as we previously did for the
+        // parameters.
+        let mut return_analysis = self
+            .convert_return_type(&fun.output, ns, &fun.references, sophistication)
+            .unwrap_or_else(|err| {
+                set_ignore_reason(err);
+                ReturnTypeAnalysis::default()
+            });
+        let mut deps = params_deps;
+        deps.extend(return_analysis.deps.drain(..));
+
+        // Sometimes, the return type will actually be a value type
+        // for which we instead want to _pass_ a pointer into which the value
+        // can be constructed. Handle that case here.
+        if let Some((extra_param, extra_param_details)) = return_analysis.placement_param_needed {
+            param_details.push(extra_param_details);
+            params.push(extra_param);
+        }
+
+        let requires_unsafe = self.should_be_unsafe(&param_details, &kind);
+
+        let num_input_references = param_details.iter().filter(|pd| pd.has_lifetime).count();
+        if num_input_references != 1 && return_analysis.was_reference {
+            // cxx only allows functions to return a reference if they take exactly
+            // one reference as a parameter. Let's see...
+            set_ignore_reason(ConvertError::NotOneInputReference(rust_name.clone()));
+        }
+        let mut ret_type = return_analysis.rt;
+        let ret_type_conversion = return_analysis.conversion;
+
+        // Do we need to convert either parameters or return type?
+        let param_conversion_needed = param_details.iter().any(|b| b.conversion.cpp_work_needed());
+        let ret_type_conversion_needed = ret_type_conversion
+            .as_ref()
+            .map_or(false, |x| x.cpp_work_needed());
+        // See https://github.com/dtolnay/cxx/issues/878 for the reason for this next line.
+        let effective_cpp_name = cpp_name.as_ref().unwrap_or(&rust_name);
+        let cpp_name_incompatible_with_cxx =
+            validate_ident_ok_for_rust(effective_cpp_name).is_err();
+        // If possible, we'll put knowledge of the C++ API directly into the cxx::bridge
+        // mod. However, there are various circumstances where cxx can't work with the existing
+        // C++ API and we need to create a C++ wrapper function which is more cxx-compliant.
+        // That wrapper function is included in the cxx::bridge, and calls through to the
+        // original function.
+        let wrapper_function_needed = match kind {
+            FnKind::Method {
+                method_kind:
+                    MethodKind::Static
+                    | MethodKind::Constructor { .. }
+                    | MethodKind::Virtual(_)
+                    | MethodKind::PureVirtual(_),
+                ..
+            }
+            | FnKind::TraitMethod {
+                kind:
+                    TraitMethodKind::CopyConstructor
+                    | TraitMethodKind::MoveConstructor
+                    | TraitMethodKind::Destructor,
+                ..
+            } => true,
+            FnKind::Method { .. } if cxxbridge_name != rust_name => true,
+            _ if param_conversion_needed => true,
+            _ if ret_type_conversion_needed => true,
+            _ if cpp_name_incompatible_with_cxx => true,
+            _ if fun.synthetic_cpp.is_some() => true,
+            _ => false,
+        };
+
+        let cpp_wrapper = if wrapper_function_needed {
+            // Generate a new layer of C++ code to wrap/unwrap parameters
+            // and return values into/out of std::unique_ptrs.
+            let cpp_construction_ident = make_ident(&effective_cpp_name);
+            let joiner = if cxxbridge_name.to_string().ends_with('_') {
+                ""
+            } else {
+                "_"
+            };
+            cxxbridge_name = make_ident(&format!("{}{}autocxx_wrapper", cxxbridge_name, joiner));
+            let (payload, cpp_function_kind) = match fun.synthetic_cpp.as_ref().cloned() {
+                Some((payload, cpp_function_kind)) => (payload, cpp_function_kind),
+                None => match kind {
+                    FnKind::Method {
+                        ref impl_for,
+                        method_kind: MethodKind::Constructor { .. },
+                        ..
+                    }
+                    | FnKind::TraitMethod {
+                        kind: TraitMethodKind::CopyConstructor | TraitMethodKind::MoveConstructor,
+                        ref impl_for,
+                        ..
+                    } => (
+                        CppFunctionBody::PlacementNew(ns.clone(), impl_for.get_final_ident()),
+                        CppFunctionKind::Constructor,
+                    ),
+                    FnKind::TraitMethod {
+                        kind: TraitMethodKind::Destructor,
+                        ref impl_for,
+                        ..
+                    } => (
+                        CppFunctionBody::Destructor(ns.clone(), impl_for.get_final_ident()),
+                        CppFunctionKind::Function,
+                    ),
+                    FnKind::Method {
+                        ref impl_for,
+                        method_kind: MethodKind::Static,
+                        ..
+                    } => (
+                        CppFunctionBody::StaticMethodCall(
+                            ns.clone(),
+                            impl_for.get_final_ident(),
+                            cpp_construction_ident,
+                        ),
+                        CppFunctionKind::Function,
+                    ),
+                    FnKind::Method { .. } => (
+                        CppFunctionBody::FunctionCall(ns.clone(), cpp_construction_ident),
+                        CppFunctionKind::Method,
+                    ),
+                    _ => (
+                        CppFunctionBody::FunctionCall(ns.clone(), cpp_construction_ident),
+                        CppFunctionKind::Function,
+                    ),
+                },
+            };
+            // Now modify the cxx::bridge entry we're going to make.
+            if let Some(ref conversion) = ret_type_conversion {
+                if conversion.populate_return_value() {
+                    let new_ret_type = conversion.unconverted_rust_type();
+                    ret_type = parse_quote!(
+                        -> #new_ret_type
+                    );
+                }
+            }
+
+            // Amend parameters for the function which we're asking cxx to generate.
+            params.clear();
+            for pd in &param_details {
+                let type_name = pd.conversion.converted_rust_type();
+                let arg_name = if pd.self_type.is_some() {
+                    parse_quote!(autocxx_gen_this)
+                } else {
+                    pd.name.clone()
+                };
+                params.push(parse_quote!(
+                    #arg_name: #type_name
+                ));
+            }
+
+            Some(CppFunction {
+                payload,
+                wrapper_function_name: cxxbridge_name.clone(),
+                original_cpp_name: cpp_name
+                    .as_ref()
+                    .cloned()
+                    .unwrap_or_else(|| cxxbridge_name.to_string()),
+                return_conversion: ret_type_conversion.clone(),
+                argument_conversion: param_details.iter().map(|d| d.conversion.clone()).collect(),
+                kind: cpp_function_kind,
+                pass_obs_field: false,
+                qualification: None,
+            })
+        } else {
+            None
+        };
+
+        let vis = fun.vis.clone();
+
+        let any_param_needs_rust_conversion = param_details
+            .iter()
+            .any(|pd| pd.conversion.rust_work_needed());
+
+        let rust_wrapper_needed = match kind {
+            FnKind::TraitMethod { .. } => true,
+            FnKind::Method { .. } => any_param_needs_rust_conversion || cxxbridge_name != rust_name,
+            _ => any_param_needs_rust_conversion,
+        };
+
+        // Naming, part two.
+        // Work out our final naming strategy.
+        validate_ident_ok_for_cxx(&cxxbridge_name.to_string()).unwrap_or_else(set_ignore_reason);
+        let rust_name_ident = make_ident(&rust_name);
+        let rust_rename_strategy = match kind {
+            _ if rust_wrapper_needed => RustRenameStrategy::RenameUsingWrapperFunction,
+            FnKind::Function if cxxbridge_name != rust_name => {
+                RustRenameStrategy::RenameInOutputMod(rust_name_ident)
+            }
+            _ => RustRenameStrategy::None,
+        };
+
+        let analysis = FnAnalysis {
+            cxxbridge_name: cxxbridge_name.clone(),
+            rust_name: rust_name.clone(),
+            rust_rename_strategy,
+            params,
+            ret_conversion: ret_type_conversion,
+            kind,
+            ret_type,
+            param_details,
+            requires_unsafe,
+            vis,
+            cpp_wrapper,
+            deps,
+            ignore_reason,
+            externally_callable,
+            rust_wrapper_needed,
+        };
+        let name = ApiName::new_with_cpp_name(ns, cxxbridge_name, cpp_name);
+        (analysis, name)
+    }
+
+    fn error_context_for_method(&self, self_ty: &QualifiedName, rust_name: &str) -> ErrorContext {
+        if self.is_generic_type(self_ty) {
+            // A 'method' error context would end up in an
+            //   impl A {
+            //      fn error_thingy
+            //   }
+            // block. We can't impl A if it would need to be impl A<B>
+            ErrorContext::new_for_item(make_ident(rust_name))
+        } else {
+            ErrorContext::new_for_method(self_ty.get_final_ident(), make_ident(rust_name))
+        }
+    }
+
+    /// Applies a specific `force_rust_conversion` to the parameter at index
+    /// `param_idx`. Modifies `param_details` and `params` in place.
+    #[allow(clippy::too_many_arguments)] // it's true, but sticking with it for now
+    fn reanalyze_parameter(
+        &mut self,
+        param_idx: usize,
+        fun: &FuncToConvert,
+        ns: &Namespace,
+        rust_name: &str,
+        params: &mut Punctuated<FnArg, Comma>,
+        param_details: &mut [ArgumentAnalysis],
+        force_rust_conversion: Option<RustConversionType>,
+        sophistication: TypeConversionSophistication,
+        construct_into_self: bool,
+        is_move_constructor: bool,
+    ) -> Result<(), ConvertError> {
+        self.convert_fn_arg(
+            fun.inputs.iter().nth(param_idx).unwrap(),
+            ns,
+            rust_name,
+            &fun.synthesized_this_type,
+            &fun.references,
+            false,
+            is_move_constructor,
+            force_rust_conversion,
+            sophistication,
+            construct_into_self,
+        )
+        .map(|(new_arg, new_analysis)| {
+            param_details[param_idx] = new_analysis;
+            let mut params_before = params.clone().into_iter();
+            let prefix = params_before
+                .by_ref()
+                .take(param_idx)
+                .collect_vec()
+                .into_iter();
+            let suffix = params_before.skip(1);
+            *params = prefix
+                .chain(std::iter::once(new_arg))
+                .chain(suffix)
+                .collect()
+        })
+    }
+
+    fn get_overload_name(&mut self, ns: &Namespace, type_ident: &str, rust_name: String) -> String {
+        let overload_tracker = self.overload_trackers_by_mod.entry(ns.clone()).or_default();
+        overload_tracker.get_method_real_name(type_ident, rust_name)
+    }
+
+    /// Determine if this synthetic function should actually result in the implementation
+    /// of a trait, rather than a function/method.
+    fn trait_creation_details_for_synthetic_function(
+        &mut self,
+        synthesis: &Option<TraitSynthesis>,
+        ns: &Namespace,
+        ideal_rust_name: &str,
+        self_ty: &Option<QualifiedName>,
+    ) -> Option<(FnKind, ErrorContext, String)> {
+        synthesis.as_ref().and_then(|synthesis| match synthesis {
+            TraitSynthesis::Cast { to_type, mutable } => {
+                let rust_name = self.get_function_overload_name(ns, ideal_rust_name.to_string());
+                let from_type = self_ty.as_ref().unwrap();
+                let from_type_path = from_type.to_type_path();
+                let to_type = to_type.to_type_path();
+                let (trait_signature, ty, method_name) = match *mutable {
+                    CastMutability::ConstToConst => (
+                        parse_quote! {
+                            AsRef < #to_type >
+                        },
+                        Type::Path(from_type_path),
+                        "as_ref",
+                    ),
+                    CastMutability::MutToConst => (
+                        parse_quote! {
+                            AsRef < #to_type >
+                        },
+                        parse_quote! {
+                            &'a mut ::std::pin::Pin < &'a mut #from_type_path >
+                        },
+                        "as_ref",
+                    ),
+                    CastMutability::MutToMut => (
+                        parse_quote! {
+                            autocxx::PinMut < #to_type >
+                        },
+                        parse_quote! {
+                            ::std::pin::Pin < &'a mut #from_type_path >
+                        },
+                        "pin_mut",
+                    ),
+                };
+                let method_name = make_ident(method_name);
+                Some((
+                    FnKind::TraitMethod {
+                        kind: TraitMethodKind::Cast,
+                        impl_for: from_type.clone(),
+                        details: Box::new(TraitMethodDetails {
+                            trt: TraitImplSignature {
+                                ty,
+                                trait_signature,
+                                unsafety: None,
+                            },
+                            avoid_self: false,
+                            method_name,
+                            parameter_reordering: None,
+                            trait_call_is_unsafe: false,
+                        }),
+                    },
+                    ErrorContext::new_for_item(make_ident(&rust_name)),
+                    rust_name,
+                ))
+            }
+            TraitSynthesis::AllocUninitialized(ty) => self.generate_alloc_or_deallocate(
+                ideal_rust_name,
+                ty,
+                "allocate_uninitialized_cpp_storage",
+                TraitMethodKind::Alloc,
+            ),
+            TraitSynthesis::FreeUninitialized(ty) => self.generate_alloc_or_deallocate(
+                ideal_rust_name,
+                ty,
+                "free_uninitialized_cpp_storage",
+                TraitMethodKind::Dealloc,
+            ),
+        })
+    }
+
+    fn generate_alloc_or_deallocate(
+        &mut self,
+        ideal_rust_name: &str,
+        ty: &QualifiedName,
+        method_name: &str,
+        kind: TraitMethodKind,
+    ) -> Option<(FnKind, ErrorContext, String)> {
+        let rust_name =
+            self.get_function_overload_name(ty.get_namespace(), ideal_rust_name.to_string());
+        let typ = ty.to_type_path();
+        Some((
+            FnKind::TraitMethod {
+                impl_for: ty.clone(),
+                details: Box::new(TraitMethodDetails {
+                    trt: TraitImplSignature {
+                        ty: Type::Path(typ),
+                        trait_signature: parse_quote! { autocxx::moveit::MakeCppStorage },
+                        unsafety: Some(parse_quote! { unsafe }),
+                    },
+                    avoid_self: false,
+                    method_name: make_ident(method_name),
+                    parameter_reordering: None,
+                    trait_call_is_unsafe: false,
+                }),
+                kind,
+            },
+            ErrorContext::new_for_item(make_ident(&rust_name)),
+            rust_name,
+        ))
+    }
+
+    fn get_function_overload_name(&mut self, ns: &Namespace, ideal_rust_name: String) -> String {
+        let overload_tracker = self.overload_trackers_by_mod.entry(ns.clone()).or_default();
+        overload_tracker.get_function_real_name(ideal_rust_name)
+    }
+
+    fn subclasses_by_superclass(&self, sup: &QualifiedName) -> impl Iterator<Item = SubclassName> {
+        match self.subclasses_by_superclass.get(sup) {
+            Some(subs) => subs.clone().into_iter(),
+            None => Vec::new().into_iter(),
+        }
+    }
+
+    #[allow(clippy::too_many_arguments)] // currently reasonably clear
+    fn convert_fn_arg(
+        &mut self,
+        arg: &FnArg,
+        ns: &Namespace,
+        fn_name: &str,
+        virtual_this: &Option<QualifiedName>,
+        references: &References,
+        treat_this_as_reference: bool,
+        is_move_constructor: bool,
+        force_rust_conversion: Option<RustConversionType>,
+        sophistication: TypeConversionSophistication,
+        construct_into_self: bool,
+    ) -> Result<(FnArg, ArgumentAnalysis), ConvertError> {
+        Ok(match arg {
+            FnArg::Typed(pt) => {
+                let mut pt = pt.clone();
+                let mut self_type = None;
+                let old_pat = *pt.pat;
+                let mut pointer_treatment = PointerTreatment::Pointer;
+                let mut is_placement_return_destination = false;
+                let new_pat = match old_pat {
+                    syn::Pat::Ident(mut pp) if pp.ident == "this" => {
+                        let this_type = match pt.ty.as_ref() {
+                            Type::Ptr(TypePtr {
+                                elem, mutability, ..
+                            }) => match elem.as_ref() {
+                                Type::Path(typ) => {
+                                    let receiver_mutability = if mutability.is_some() {
+                                        ReceiverMutability::Mutable
+                                    } else {
+                                        ReceiverMutability::Const
+                                    };
+
+                                    let this_type = if let Some(virtual_this) = virtual_this {
+                                        let this_type_path = virtual_this.to_type_path();
+                                        let const_token = if mutability.is_some() {
+                                            None
+                                        } else {
+                                            Some(syn::Token![const](Span::call_site()))
+                                        };
+                                        pt.ty = Box::new(parse_quote! {
+                                            * #mutability #const_token #this_type_path
+                                        });
+                                        virtual_this.clone()
+                                    } else {
+                                        QualifiedName::from_type_path(typ)
+                                    };
+                                    Ok((this_type, receiver_mutability))
+                                }
+                                _ => Err(ConvertError::UnexpectedThisType(QualifiedName::new(
+                                    ns,
+                                    make_ident(fn_name),
+                                ))),
+                            },
+                            _ => Err(ConvertError::UnexpectedThisType(QualifiedName::new(
+                                ns,
+                                make_ident(fn_name),
+                            ))),
+                        }?;
+                        self_type = Some(this_type);
+                        is_placement_return_destination = construct_into_self;
+                        if treat_this_as_reference {
+                            pp.ident = Ident::new("self", pp.ident.span());
+                            pointer_treatment = PointerTreatment::Reference;
+                        }
+                        syn::Pat::Ident(pp)
+                    }
+                    syn::Pat::Ident(pp) => {
+                        validate_ident_ok_for_cxx(&pp.ident.to_string())?;
+                        pointer_treatment = references.param_treatment(&pp.ident);
+                        syn::Pat::Ident(pp)
+                    }
+                    _ => old_pat,
+                };
+                let is_placement_return_destination = is_placement_return_destination
+                    || matches!(
+                        force_rust_conversion,
+                        Some(RustConversionType::FromPlacementParamToNewReturn)
+                    );
+                let annotated_type = self.convert_boxed_type(pt.ty, ns, pointer_treatment)?;
+                let conversion = self.argument_conversion_details(
+                    &annotated_type,
+                    is_move_constructor,
+                    force_rust_conversion,
+                    sophistication,
+                );
+                let new_ty = annotated_type.ty;
+                pt.pat = Box::new(new_pat.clone());
+                pt.ty = new_ty;
+                let requires_unsafe =
+                    if matches!(annotated_type.kind, type_converter::TypeKind::Pointer)
+                        && !is_placement_return_destination
+                    {
+                        UnsafetyNeeded::Always
+                    } else if conversion.bridge_unsafe_needed() || is_placement_return_destination {
+                        UnsafetyNeeded::JustBridge
+                    } else {
+                        UnsafetyNeeded::None
+                    };
+                (
+                    FnArg::Typed(pt),
+                    ArgumentAnalysis {
+                        self_type,
+                        name: new_pat,
+                        conversion,
+                        has_lifetime: matches!(
+                            annotated_type.kind,
+                            type_converter::TypeKind::Reference
+                                | type_converter::TypeKind::MutableReference
+                        ),
+                        deps: annotated_type.types_encountered,
+                        requires_unsafe,
+                        is_placement_return_destination,
+                    },
+                )
+            }
+            _ => panic!("Did not expect FnArg::Receiver to be generated by bindgen"),
+        })
+    }
+
+    fn argument_conversion_details(
+        &self,
+        annotated_type: &Annotated<Box<Type>>,
+        is_move_constructor: bool,
+        force_rust_conversion: Option<RustConversionType>,
+        sophistication: TypeConversionSophistication,
+    ) -> TypeConversionPolicy {
+        let is_subclass_holder = match &annotated_type.kind {
+            type_converter::TypeKind::SubclassHolder(holder) => Some(holder),
+            _ => None,
+        };
+        let is_rvalue_ref = matches!(
+            annotated_type.kind,
+            type_converter::TypeKind::RValueReference
+        );
+        let ty = &*annotated_type.ty;
+        if let Some(holder_id) = is_subclass_holder {
+            let subclass = SubclassName::from_holder_name(holder_id);
+            return {
+                let ty = parse_quote! {
+                    rust::Box<#holder_id>
+                };
+                TypeConversionPolicy {
+                    unwrapped_type: ty,
+                    cpp_conversion: CppConversionType::Move,
+                    rust_conversion: RustConversionType::ToBoxedUpHolder(subclass),
+                }
+            };
+        } else if matches!(
+            force_rust_conversion,
+            Some(RustConversionType::FromPlacementParamToNewReturn)
+        ) && matches!(sophistication, TypeConversionSophistication::Regular)
+        {
+            return TypeConversionPolicy {
+                unwrapped_type: ty.clone(),
+                cpp_conversion: CppConversionType::IgnoredPlacementPtrParameter,
+                rust_conversion: RustConversionType::FromPlacementParamToNewReturn,
+            };
+        }
+        match ty {
+            Type::Path(p) => {
+                let ty = ty.clone();
+                let tn = QualifiedName::from_type_path(p);
+                if self.pod_safe_types.contains(&tn) {
+                    if known_types().lacks_copy_constructor(&tn) {
+                        TypeConversionPolicy {
+                            unwrapped_type: ty,
+                            cpp_conversion: CppConversionType::Move,
+                            rust_conversion: RustConversionType::None,
+                        }
+                    } else {
+                        TypeConversionPolicy::new_unconverted(ty)
+                    }
+                } else if known_types().convertible_from_strs(&tn)
+                    && !self.config.exclude_utilities()
+                {
+                    TypeConversionPolicy {
+                        unwrapped_type: ty,
+                        cpp_conversion: CppConversionType::FromUniquePtrToValue,
+                        rust_conversion: RustConversionType::FromStr,
+                    }
+                } else if matches!(
+                    sophistication,
+                    TypeConversionSophistication::SimpleForSubclasses
+                ) {
+                    TypeConversionPolicy {
+                        unwrapped_type: ty,
+                        cpp_conversion: CppConversionType::FromUniquePtrToValue,
+                        rust_conversion: RustConversionType::None,
+                    }
+                } else {
+                    TypeConversionPolicy {
+                        unwrapped_type: ty,
+                        cpp_conversion: CppConversionType::FromPtrToValue,
+                        rust_conversion: RustConversionType::FromValueParamToPtr,
+                    }
+                }
+            }
+            Type::Ptr(tp) => {
+                let rust_conversion = force_rust_conversion.unwrap_or(RustConversionType::None);
+                if is_move_constructor {
+                    TypeConversionPolicy {
+                        unwrapped_type: ty.clone(),
+                        cpp_conversion: CppConversionType::FromPtrToMove,
+                        rust_conversion,
+                    }
+                } else if is_rvalue_ref {
+                    TypeConversionPolicy {
+                        unwrapped_type: *tp.elem.clone(),
+                        cpp_conversion: CppConversionType::FromPtrToValue,
+                        rust_conversion: RustConversionType::FromRValueParamToPtr,
+                    }
+                } else {
+                    TypeConversionPolicy {
+                        unwrapped_type: ty.clone(),
+                        cpp_conversion: CppConversionType::None,
+                        rust_conversion,
+                    }
+                }
+            }
+            _ => {
+                let rust_conversion = force_rust_conversion.unwrap_or(RustConversionType::None);
+                TypeConversionPolicy {
+                    unwrapped_type: ty.clone(),
+                    cpp_conversion: CppConversionType::None,
+                    rust_conversion,
+                }
+            }
+        }
+    }
+
+    fn convert_return_type(
+        &mut self,
+        rt: &ReturnType,
+        ns: &Namespace,
+        references: &References,
+        sophistication: TypeConversionSophistication,
+    ) -> Result<ReturnTypeAnalysis, ConvertError> {
+        Ok(match rt {
+            ReturnType::Default => ReturnTypeAnalysis::default(),
+            ReturnType::Type(rarrow, boxed_type) => {
+                let annotated_type =
+                    self.convert_boxed_type(boxed_type.clone(), ns, references.return_treatment())?;
+                let boxed_type = annotated_type.ty;
+                let ty: &Type = boxed_type.as_ref();
+                match ty {
+                    Type::Path(p)
+                        if !self
+                            .pod_safe_types
+                            .contains(&QualifiedName::from_type_path(p)) =>
+                    {
+                        let tn = QualifiedName::from_type_path(p);
+                        if self.moveit_safe_types.contains(&tn)
+                            && matches!(sophistication, TypeConversionSophistication::Regular)
+                        {
+                            // This is a non-POD type we want to return to Rust as an `impl New` so that callers
+                            // can decide whether to store this on the stack or heap.
+                            // That means, we do not literally _return_ it from C++ to Rust. Instead, our call
+                            // from Rust to C++ will include an extra placement parameter into which the object
+                            // is constructed.
+                            let fnarg = parse_quote! {
+                                placement_return_type: *mut #ty
+                            };
+                            let (fnarg, analysis) = self.convert_fn_arg(
+                                &fnarg,
+                                ns,
+                                "",
+                                &None,
+                                &References::default(),
+                                false,
+                                false,
+                                Some(RustConversionType::FromPlacementParamToNewReturn),
+                                TypeConversionSophistication::Regular,
+                                false,
+                            )?;
+                            ReturnTypeAnalysis {
+                                rt: ReturnType::Default,
+                                conversion: Some(TypeConversionPolicy::new_for_placement_return(
+                                    ty.clone(),
+                                )),
+                                was_reference: false,
+                                deps: annotated_type.types_encountered,
+                                placement_param_needed: Some((fnarg, analysis)),
+                            }
+                        } else {
+                            // There are some types which we can't currently represent within a moveit::new::New.
+                            // That's either because we are obliged to stick to existing protocols for compatibility
+                            // (CxxString) or because they're a concrete type where we haven't attempted to do
+                            // the analysis to work out the type's size. For these, we always return a plain old
+                            // UniquePtr<T>. These restrictions may be fixed in future.
+                            let conversion =
+                                Some(TypeConversionPolicy::new_to_unique_ptr(ty.clone()));
+                            ReturnTypeAnalysis {
+                                rt: ReturnType::Type(*rarrow, boxed_type),
+                                conversion,
+                                was_reference: false,
+                                deps: annotated_type.types_encountered,
+                                placement_param_needed: None,
+                            }
+                        }
+                    }
+                    _ => {
+                        let was_reference = matches!(boxed_type.as_ref(), Type::Reference(_));
+                        let conversion = Some(TypeConversionPolicy::new_unconverted(ty.clone()));
+                        ReturnTypeAnalysis {
+                            rt: ReturnType::Type(*rarrow, boxed_type),
+                            conversion,
+                            was_reference,
+                            deps: annotated_type.types_encountered,
+                            placement_param_needed: None,
+                        }
+                    }
+                }
+            }
+        })
+    }
+
+    /// If a type has explicit constructors, bindgen will generate corresponding
+    /// constructor functions, which we'll have already converted to make_unique methods.
+    /// C++ mandates the synthesis of certain implicit constructors, to which we
+    /// need to create bindings too. We do that here.
+    /// It is tempting to make this a separate analysis phase, to be run later than
+    /// the function analysis; but that would make the code much more complex as it
+    /// would need to output a `FnAnalysisBody`. By running it as part of this phase
+    /// we can simply generate the sort of thing bindgen generates, then ask
+    /// the existing code in this phase to figure out what to do with it.
+    ///
+    /// Also fills out the [`PodAndConstructorAnalysis::constructors`] fields with information useful
+    /// for further analysis phases.
+    fn add_constructors_present(&mut self, mut apis: ApiVec<FnPrePhase1>) -> ApiVec<FnPrePhase2> {
+        let all_items_found = find_constructors_present(&apis);
+        for (self_ty, items_found) in all_items_found.iter() {
+            if self.config.exclude_impls {
+                // Remember that `find_constructors_present` mutates `apis`, so we always have to
+                // call that, even if we don't do anything with the return value. This is kind of
+                // messy, see the comment on this function for why.
+                continue;
+            }
+            if self
+                .config
+                .is_on_constructor_blocklist(&self_ty.to_cpp_name())
+            {
+                continue;
+            }
+            let path = self_ty.to_type_path();
+            if items_found.implicit_default_constructor_needed() {
+                self.synthesize_special_member(
+                    items_found,
+                    "default_ctor",
+                    &mut apis,
+                    SpecialMemberKind::DefaultConstructor,
+                    parse_quote! { this: *mut #path },
+                    References::default(),
+                );
+            }
+            if items_found.implicit_move_constructor_needed() {
+                self.synthesize_special_member(
+                    items_found,
+                    "move_ctor",
+                    &mut apis,
+                    SpecialMemberKind::MoveConstructor,
+                    parse_quote! { this: *mut #path, other: *mut #path },
+                    References {
+                        rvalue_ref_params: [make_ident("other")].into_iter().collect(),
+                        ..Default::default()
+                    },
+                )
+            }
+            if items_found.implicit_copy_constructor_needed() {
+                self.synthesize_special_member(
+                    items_found,
+                    "const_copy_ctor",
+                    &mut apis,
+                    SpecialMemberKind::CopyConstructor,
+                    parse_quote! { this: *mut #path, other: *const #path },
+                    References {
+                        ref_params: [make_ident("other")].into_iter().collect(),
+                        ..Default::default()
+                    },
+                )
+            }
+            if items_found.implicit_destructor_needed() {
+                self.synthesize_special_member(
+                    items_found,
+                    "destructor",
+                    &mut apis,
+                    SpecialMemberKind::Destructor,
+                    parse_quote! { this: *mut #path },
+                    References::default(),
+                );
+            }
+        }
+
+        // Also, annotate each type with the constructors we found.
+        let mut results = ApiVec::new();
+        convert_apis(
+            apis,
+            &mut results,
+            Api::fun_unchanged,
+            |name, details, analysis| {
+                let items_found = all_items_found.get(&name.name);
+                Ok(Box::new(std::iter::once(Api::Struct {
+                    name,
+                    details,
+                    analysis: PodAndConstructorAnalysis {
+                        pod: analysis,
+                        constructors: if let Some(items_found) = items_found {
+                            PublicConstructors::from_items_found(items_found)
+                        } else {
+                            PublicConstructors::default()
+                        },
+                    },
+                })))
+            },
+            Api::enum_unchanged,
+            Api::typedef_unchanged,
+        );
+        results
+    }
+
+    #[allow(clippy::too_many_arguments)] // it's true, but sticking with it for now
+    fn synthesize_special_member(
+        &mut self,
+        items_found: &ItemsFound,
+        label: &str,
+        apis: &mut ApiVec<FnPrePhase1>,
+        special_member: SpecialMemberKind,
+        inputs: Punctuated<FnArg, Comma>,
+        references: References,
+    ) {
+        let self_ty = items_found.name.as_ref().unwrap();
+        let ident = make_ident(self.config.uniquify_name_per_mod(&format!(
+            "{}_synthetic_{}",
+            self_ty.name.get_final_item(),
+            label
+        )));
+        let cpp_name = if matches!(special_member, SpecialMemberKind::DefaultConstructor) {
+            // Constructors (other than move or copy) are identified in `analyze_foreign_fn` by
+            // being suffixed with the cpp_name, so we have to produce that.
+            self.nested_type_name_map
+                .get(&self_ty.name)
+                .cloned()
+                .or_else(|| Some(self_ty.name.get_final_item().to_string()))
+        } else {
+            None
+        };
+        let fake_api_name =
+            ApiName::new_with_cpp_name(self_ty.name.get_namespace(), ident.clone(), cpp_name);
+        let self_ty = &self_ty.name;
+        let ns = self_ty.get_namespace().clone();
+        let mut any_errors = ApiVec::new();
+        apis.extend(
+            report_any_error(&ns, &mut any_errors, || {
+                self.analyze_foreign_fn_and_subclasses(
+                    fake_api_name,
+                    Box::new(FuncToConvert {
+                        self_ty: Some(self_ty.clone()),
+                        ident,
+                        doc_attrs: make_doc_attrs(format!("Synthesized {}.", special_member)),
+                        inputs,
+                        output: ReturnType::Default,
+                        vis: parse_quote! { pub },
+                        virtualness: Virtualness::None,
+                        cpp_vis: CppVisibility::Public,
+                        special_member: Some(special_member),
+                        unused_template_param: false,
+                        references,
+                        original_name: None,
+                        synthesized_this_type: None,
+                        is_deleted: false,
+                        add_to_trait: None,
+                        synthetic_cpp: None,
+                        provenance: Provenance::SynthesizedOther,
+                        variadic: false,
+                    }),
+                )
+            })
+            .into_iter()
+            .flatten(),
+        );
+        apis.append(&mut any_errors);
+    }
+}
+
+/// Attempts to determine whether this function name is a constructor, and if so,
+/// returns the suffix.
+fn constructor_with_suffix<'a>(rust_name: &'a str, nested_type_ident: &str) -> Option<&'a str> {
+    let suffix = rust_name.strip_prefix(nested_type_ident);
+    suffix.and_then(|suffix| {
+        if suffix.is_empty() || suffix.parse::<u32>().is_ok() {
+            Some(suffix)
+        } else {
+            None
+        }
+    })
+}
+
+impl Api<FnPhase> {
+    pub(crate) fn name_for_allowlist(&self) -> QualifiedName {
+        match &self {
+            Api::Function { analysis, .. } => match analysis.kind {
+                FnKind::Method { ref impl_for, .. } => impl_for.clone(),
+                FnKind::TraitMethod { ref impl_for, .. } => impl_for.clone(),
+                FnKind::Function => {
+                    QualifiedName::new(self.name().get_namespace(), make_ident(&analysis.rust_name))
+                }
+            },
+            Api::RustSubclassFn { subclass, .. } => subclass.0.name.clone(),
+            Api::IgnoredItem {
+                name,
+                ctx: Some(ctx),
+                ..
+            } => match ctx.get_type() {
+                ErrorContextType::Method { self_ty, .. } => {
+                    QualifiedName::new(name.name.get_namespace(), self_ty.clone())
+                }
+                ErrorContextType::Item(id) => {
+                    QualifiedName::new(name.name.get_namespace(), id.clone())
+                }
+                _ => name.name.clone(),
+            },
+            _ => self.name().clone(),
+        }
+    }
+
+    /// Whether this API requires generation of additional C++.
+    /// This seems an odd place for this function (as opposed to in the [codegen_cpp]
+    /// module) but, as it happens, even our Rust codegen phase needs to know if
+    /// more C++ is needed (so it can add #includes in the cxx mod).
+    /// And we can't answer the question _prior_ to this function analysis phase.
+    pub(crate) fn needs_cpp_codegen(&self) -> bool {
+        matches!(
+            &self,
+            Api::Function {
+                analysis: FnAnalysis {
+                    cpp_wrapper: Some(..),
+                    ignore_reason: Ok(_),
+                    externally_callable: true,
+                    ..
+                },
+                ..
+            } | Api::StringConstructor { .. }
+                | Api::ConcreteType { .. }
+                | Api::CType { .. }
+                | Api::RustSubclassFn { .. }
+                | Api::Subclass { .. }
+                | Api::Struct {
+                    analysis: PodAndDepAnalysis {
+                        pod: PodAnalysis {
+                            kind: TypeKind::Pod,
+                            ..
+                        },
+                        ..
+                    },
+                    ..
+                }
+        )
+    }
+
+    pub(crate) fn cxxbridge_name(&self) -> Option<Ident> {
+        match self {
+            Api::Function { ref analysis, .. } => Some(analysis.cxxbridge_name.clone()),
+            Api::StringConstructor { .. }
+            | Api::Const { .. }
+            | Api::IgnoredItem { .. }
+            | Api::RustSubclassFn { .. } => None,
+            _ => Some(self.name().get_final_ident()),
+        }
+    }
+}
diff --git a/engine/src/conversion/analysis/fun/overload_tracker.rs b/engine/src/conversion/analysis/fun/overload_tracker.rs
new file mode 100644
index 0000000..6fc532c
--- /dev/null
+++ b/engine/src/conversion/analysis/fun/overload_tracker.rs
@@ -0,0 +1,77 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::collections::HashMap;
+
+type Offsets = HashMap<String, usize>;
+
+/// Registry of all the overloads of a function found within a given
+/// namespace (i.e. mod in bindgen's output). If necessary we'll append
+/// a _nnn suffix to a function's Rust name to disambiguate overloads.
+/// Note that this is NOT necessarily the same as the suffix added by
+/// bindgen to disambiguate overloads it discovers. Its suffix is
+/// global across all functions, whereas ours is local within a given
+/// type.
+/// If bindgen adds a suffix it will be included in 'found_name'
+/// but not 'original_name' which is an annotation added by our autocxx-bindgen
+/// fork.
+#[derive(Default)]
+pub(crate) struct OverloadTracker {
+    offset_by_name: Offsets,
+    offset_by_type_and_name: HashMap<String, Offsets>,
+}
+
+impl OverloadTracker {
+    pub(crate) fn get_function_real_name(&mut self, found_name: String) -> String {
+        self.get_name(None, found_name)
+    }
+
+    pub(crate) fn get_method_real_name(&mut self, type_name: &str, found_name: String) -> String {
+        self.get_name(Some(type_name), found_name)
+    }
+
+    fn get_name(&mut self, type_name: Option<&str>, cpp_method_name: String) -> String {
+        let registry = match type_name {
+            Some(type_name) => self
+                .offset_by_type_and_name
+                .entry(type_name.to_string())
+                .or_default(),
+            None => &mut self.offset_by_name,
+        };
+        let offset = registry.entry(cpp_method_name.clone()).or_default();
+        let this_offset = *offset;
+        *offset += 1;
+        if this_offset == 0 {
+            cpp_method_name
+        } else {
+            format!("{}{}", cpp_method_name, this_offset)
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::OverloadTracker;
+
+    #[test]
+    fn test_by_function() {
+        let mut ot = OverloadTracker::default();
+        assert_eq!(ot.get_function_real_name("bob".into()), "bob");
+        assert_eq!(ot.get_function_real_name("bob".into()), "bob1");
+        assert_eq!(ot.get_function_real_name("bob".into()), "bob2");
+    }
+
+    #[test]
+    fn test_by_method() {
+        let mut ot = OverloadTracker::default();
+        assert_eq!(ot.get_method_real_name("Ty1", "bob".into()), "bob");
+        assert_eq!(ot.get_method_real_name("Ty1", "bob".into()), "bob1");
+        assert_eq!(ot.get_method_real_name("Ty2", "bob".into()), "bob");
+        assert_eq!(ot.get_method_real_name("Ty2", "bob".into()), "bob1");
+    }
+}
diff --git a/engine/src/conversion/analysis/fun/subclass.rs b/engine/src/conversion/analysis/fun/subclass.rs
new file mode 100644
index 0000000..c017249
--- /dev/null
+++ b/engine/src/conversion/analysis/fun/subclass.rs
@@ -0,0 +1,249 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::map::IndexMap as HashMap;
+
+use syn::{parse_quote, FnArg, PatType, Type, TypePtr};
+
+use crate::conversion::analysis::fun::{FnKind, MethodKind, ReceiverMutability};
+use crate::conversion::analysis::pod::PodPhase;
+use crate::conversion::api::{
+    CppVisibility, FuncToConvert, Provenance, RustSubclassFnDetails, SubclassConstructorDetails,
+    SubclassName, SuperclassMethod, UnsafetyNeeded, Virtualness,
+};
+use crate::conversion::apivec::ApiVec;
+use crate::{
+    conversion::{
+        analysis::fun::function_wrapper::{
+            CppFunction, CppFunctionBody, CppFunctionKind, TypeConversionPolicy,
+        },
+        api::{Api, ApiName},
+    },
+    types::{make_ident, Namespace, QualifiedName},
+};
+
+use super::{FnAnalysis, FnPrePhase1};
+
+pub(super) fn subclasses_by_superclass(
+    apis: &ApiVec<PodPhase>,
+) -> HashMap<QualifiedName, Vec<SubclassName>> {
+    let mut subclasses_per_superclass: HashMap<QualifiedName, Vec<SubclassName>> = HashMap::new();
+
+    for api in apis.iter() {
+        if let Api::Subclass { name, superclass } = api {
+            subclasses_per_superclass
+                .entry(superclass.clone())
+                .or_default()
+                .push(name.clone());
+        }
+    }
+    subclasses_per_superclass
+}
+
+pub(super) fn create_subclass_fn_wrapper(
+    sub: &SubclassName,
+    super_fn_name: &QualifiedName,
+    fun: &FuncToConvert,
+) -> Box<FuncToConvert> {
+    let self_ty = Some(sub.cpp());
+    Box::new(FuncToConvert {
+        synthesized_this_type: self_ty.clone(),
+        self_ty,
+        ident: super_fn_name.get_final_ident(),
+        doc_attrs: fun.doc_attrs.clone(),
+        inputs: fun.inputs.clone(),
+        output: fun.output.clone(),
+        vis: fun.vis.clone(),
+        virtualness: Virtualness::None,
+        cpp_vis: CppVisibility::Public,
+        special_member: None,
+        unused_template_param: fun.unused_template_param,
+        original_name: None,
+        references: fun.references.clone(),
+        add_to_trait: fun.add_to_trait.clone(),
+        is_deleted: fun.is_deleted,
+        synthetic_cpp: None,
+        provenance: Provenance::SynthesizedOther,
+        variadic: fun.variadic,
+    })
+}
+
+pub(super) fn create_subclass_trait_item(
+    name: ApiName,
+    analysis: &FnAnalysis,
+    receiver_mutability: &ReceiverMutability,
+    receiver: QualifiedName,
+    is_pure_virtual: bool,
+) -> Api<FnPrePhase1> {
+    let param_names = analysis
+        .param_details
+        .iter()
+        .map(|pd| pd.name.clone())
+        .collect();
+    Api::SubclassTraitItem {
+        name,
+        details: SuperclassMethod {
+            name: make_ident(&analysis.rust_name),
+            params: analysis.params.clone(),
+            ret_type: analysis.ret_type.clone(),
+            param_names,
+            receiver_mutability: receiver_mutability.clone(),
+            requires_unsafe: UnsafetyNeeded::from_param_details(&analysis.param_details, false),
+            is_pure_virtual,
+            receiver,
+        },
+    }
+}
+
+pub(super) fn create_subclass_function(
+    sub: &SubclassName,
+    analysis: &super::FnAnalysis,
+    name: &ApiName,
+    receiver_mutability: &ReceiverMutability,
+    superclass: &QualifiedName,
+    dependencies: Vec<QualifiedName>,
+) -> Api<FnPrePhase1> {
+    let cpp = sub.cpp();
+    let holder_name = sub.holder();
+    let rust_call_name = make_ident(format!(
+        "{}_{}",
+        sub.0.name.get_final_item(),
+        name.name.get_final_item()
+    ));
+    let params = std::iter::once(parse_quote! {
+        me: & #holder_name
+    })
+    .chain(analysis.params.iter().skip(1).cloned())
+    .collect();
+    let kind = if matches!(receiver_mutability, ReceiverMutability::Mutable) {
+        CppFunctionKind::Method
+    } else {
+        CppFunctionKind::ConstMethod
+    };
+    let argument_conversion = analysis
+        .param_details
+        .iter()
+        .skip(1)
+        .map(|p| p.conversion.clone())
+        .collect();
+    Api::RustSubclassFn {
+        name: ApiName::new_in_root_namespace(rust_call_name.clone()),
+        subclass: sub.clone(),
+        details: Box::new(RustSubclassFnDetails {
+            params,
+            ret: analysis.ret_type.clone(),
+            method_name: make_ident(&analysis.rust_name),
+            cpp_impl: CppFunction {
+                payload: CppFunctionBody::FunctionCall(Namespace::new(), rust_call_name),
+                wrapper_function_name: make_ident(&analysis.rust_name),
+                original_cpp_name: name.cpp_name(),
+                return_conversion: analysis.ret_conversion.clone(),
+                argument_conversion,
+                kind,
+                pass_obs_field: true,
+                qualification: Some(cpp),
+            },
+            superclass: superclass.clone(),
+            receiver_mutability: receiver_mutability.clone(),
+            dependencies,
+            requires_unsafe: UnsafetyNeeded::from_param_details(&analysis.param_details, false),
+            is_pure_virtual: matches!(
+                analysis.kind,
+                FnKind::Method {
+                    method_kind: MethodKind::PureVirtual(..),
+                    ..
+                }
+            ),
+        }),
+    }
+}
+
+pub(super) fn create_subclass_constructor(
+    sub: SubclassName,
+    analysis: &FnAnalysis,
+    sup: &QualifiedName,
+    fun: &FuncToConvert,
+) -> (Box<FuncToConvert>, ApiName) {
+    let holder = sub.holder();
+    let cpp = sub.cpp();
+    let wrapper_function_name = cpp.get_final_ident();
+    let initial_arg = TypeConversionPolicy::new_unconverted(parse_quote! {
+        rust::Box< #holder >
+    });
+    let args = std::iter::once(initial_arg).chain(
+        analysis
+            .param_details
+            .iter()
+            .skip(1) // skip placement new destination
+            .map(|aa| aa.conversion.clone()),
+    );
+    let cpp_impl = CppFunction {
+        payload: CppFunctionBody::ConstructSuperclass(sup.to_cpp_name()),
+        wrapper_function_name,
+        return_conversion: None,
+        argument_conversion: args.collect(),
+        kind: CppFunctionKind::SynthesizedConstructor,
+        pass_obs_field: false,
+        qualification: Some(cpp.clone()),
+        original_cpp_name: cpp.to_cpp_name(),
+    };
+    let subclass_constructor_details = Box::new(SubclassConstructorDetails {
+        subclass: sub.clone(),
+        is_trivial: analysis.param_details.len() == 1, // just placement new
+        // destination, no other parameters
+        cpp_impl,
+    });
+    let subclass_constructor_name =
+        make_ident(format!("{}_{}", cpp.get_final_item(), cpp.get_final_item()));
+    let mut existing_params = fun.inputs.clone();
+    if let Some(FnArg::Typed(PatType { ty, .. })) = existing_params.first_mut() {
+        if let Type::Ptr(TypePtr { elem, .. }) = &mut **ty {
+            *elem = Box::new(Type::Path(sub.cpp().to_type_path()));
+        } else {
+            panic!("Unexpected self type parameter when creating subclass constructor");
+        }
+    } else {
+        panic!("Unexpected self type parameter when creating subclass constructor");
+    }
+    let mut existing_params = existing_params.into_iter();
+    let self_param = existing_params.next();
+    let boxed_holder_param: FnArg = parse_quote! {
+        peer: rust::Box<#holder>
+    };
+    let inputs = self_param
+        .into_iter()
+        .chain(std::iter::once(boxed_holder_param))
+        .chain(existing_params)
+        .collect();
+    let maybe_wrap = Box::new(FuncToConvert {
+        ident: subclass_constructor_name.clone(),
+        doc_attrs: fun.doc_attrs.clone(),
+        inputs,
+        output: fun.output.clone(),
+        vis: fun.vis.clone(),
+        virtualness: Virtualness::None,
+        cpp_vis: CppVisibility::Public,
+        special_member: fun.special_member.clone(),
+        original_name: None,
+        unused_template_param: fun.unused_template_param,
+        references: fun.references.clone(),
+        synthesized_this_type: Some(cpp.clone()),
+        self_ty: Some(cpp),
+        add_to_trait: None,
+        is_deleted: fun.is_deleted,
+        synthetic_cpp: None,
+        provenance: Provenance::SynthesizedSubclassConstructor(subclass_constructor_details),
+        variadic: fun.variadic,
+    });
+    let subclass_constructor_name = ApiName::new_with_cpp_name(
+        &Namespace::new(),
+        subclass_constructor_name,
+        Some(sub.cpp().get_final_item().to_string()),
+    );
+    (maybe_wrap, subclass_constructor_name)
+}
diff --git a/engine/src/conversion/analysis/gc.rs b/engine/src/conversion/analysis/gc.rs
new file mode 100644
index 0000000..0734f15
--- /dev/null
+++ b/engine/src/conversion/analysis/gc.rs
@@ -0,0 +1,70 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::map::IndexMap as HashMap;
+use indexmap::set::IndexSet as HashSet;
+
+use autocxx_parser::IncludeCppConfig;
+
+use crate::{
+    conversion::{api::Api, apivec::ApiVec},
+    types::QualifiedName,
+};
+
+use super::{deps::HasDependencies, fun::FnPhase};
+
+/// This is essentially mark-and-sweep garbage collection of the
+/// [Api]s that we've discovered. Why do we do this, you might wonder?
+/// It seems a bit strange given that we pass an explicit allowlist
+/// to bindgen.
+/// There are two circumstances under which we want to discard
+/// some of the APIs we encounter parsing the bindgen.
+/// 1) We simplify some struct to be non-POD. In this case, we'll
+///    discard all the fields within it. Those fields can be, and
+///    in fact often _are_, stuff which we have trouble converting
+///    e.g. std::string or std::string::value_type or
+///    my_derived_thing<std::basic_string::value_type> or some
+///    other permutation. In such cases, we want to discard those
+///    field types with prejudice.
+/// 2) block! may be used to ban certain APIs. This often eliminates
+///    some methods from a given struct/class. In which case, we
+///    don't care about the other parameter types passed into those
+///    APIs either.
+pub(crate) fn filter_apis_by_following_edges_from_allowlist(
+    apis: ApiVec<FnPhase>,
+    config: &IncludeCppConfig,
+) -> ApiVec<FnPhase> {
+    let mut todos: Vec<QualifiedName> = apis
+        .iter()
+        .filter(|api| {
+            let tnforal = api.name_for_allowlist();
+            config.is_on_allowlist(&tnforal.to_cpp_name())
+        })
+        .map(Api::name)
+        .cloned()
+        .collect();
+    let mut by_typename: HashMap<QualifiedName, ApiVec<FnPhase>> = HashMap::new();
+    for api in apis.into_iter() {
+        let tn = api.name().clone();
+        by_typename.entry(tn).or_default().push(api);
+    }
+    let mut done = HashSet::new();
+    let mut output = ApiVec::new();
+    while !todos.is_empty() {
+        let todo = todos.remove(0);
+        if done.contains(&todo) {
+            continue;
+        }
+        if let Some(mut these_apis) = by_typename.remove(&todo) {
+            todos.extend(these_apis.iter().flat_map(|api| api.deps().cloned()));
+            output.append(&mut these_apis);
+        } // otherwise, probably an intrinsic e.g. uint32_t.
+        done.insert(todo);
+    }
+    output
+}
diff --git a/engine/src/conversion/analysis/mod.rs b/engine/src/conversion/analysis/mod.rs
new file mode 100644
index 0000000..d733011
--- /dev/null
+++ b/engine/src/conversion/analysis/mod.rs
@@ -0,0 +1,28 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub(crate) mod abstract_types;
+pub(crate) mod allocators;
+pub(crate) mod casts;
+pub(crate) mod constructor_deps;
+pub(crate) mod ctypes;
+pub(crate) mod deps;
+mod depth_first;
+mod doc_label;
+pub(crate) mod fun;
+pub(crate) mod gc;
+mod name_check;
+pub(crate) mod pod; // hey, that rhymes
+pub(crate) mod remove_ignored;
+mod replace_hopeless_typedef_targets;
+pub(crate) mod tdef;
+mod type_converter;
+
+pub(crate) use name_check::check_names;
+pub(crate) use replace_hopeless_typedef_targets::replace_hopeless_typedef_targets;
+pub(crate) use type_converter::PointerTreatment;
diff --git a/engine/src/conversion/analysis/name_check.rs b/engine/src/conversion/analysis/name_check.rs
new file mode 100644
index 0000000..7547c7c
--- /dev/null
+++ b/engine/src/conversion/analysis/name_check.rs
@@ -0,0 +1,115 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::map::IndexMap as HashMap;
+
+use syn::Ident;
+
+use crate::{
+    conversion::{
+        api::{Api, SubclassName},
+        apivec::ApiVec,
+        error_reporter::convert_item_apis,
+        ConvertError,
+    },
+    types::{validate_ident_ok_for_cxx, QualifiedName},
+};
+
+use super::fun::FnPhase;
+
+/// Do some final checks that the names we've come up with can be represented
+/// within cxx.
+pub(crate) fn check_names(apis: ApiVec<FnPhase>) -> ApiVec<FnPhase> {
+    // If any items have names which can't be represented by cxx,
+    // abort. This check should ideally be done at the times we fill in the
+    // `name` field of each `api` in the first place, at parse time, though
+    // as the `name` field of each API may change during various analysis phases,
+    // currently it seems better to do it here to ensure we respect
+    // the output of any such changes.
+    let mut intermediate = ApiVec::new();
+    convert_item_apis(apis, &mut intermediate, |api| match api {
+        Api::Typedef { ref name, .. }
+        | Api::ForwardDeclaration { ref name, .. }
+        | Api::OpaqueTypedef { ref name, .. }
+        | Api::Const { ref name, .. }
+        | Api::Enum { ref name, .. }
+        | Api::Struct { ref name, .. } => {
+            validate_all_segments_ok_for_cxx(name.name.segment_iter())?;
+            if let Some(cpp_name) = name.cpp_name_if_present() {
+                // The C++ name might itself be outer_type::inner_type and thus may
+                // have multiple segments.
+                validate_all_segments_ok_for_cxx(
+                    QualifiedName::new_from_cpp_name(cpp_name).segment_iter(),
+                )?;
+            }
+            Ok(Box::new(std::iter::once(api)))
+        }
+        Api::Subclass {
+            name: SubclassName(ref name),
+            ref superclass,
+        } => {
+            validate_all_segments_ok_for_cxx(name.name.segment_iter())?;
+            validate_all_segments_ok_for_cxx(superclass.segment_iter())?;
+            Ok(Box::new(std::iter::once(api)))
+        }
+        Api::Function { ref name, .. } => {
+            // we don't handle function names here because
+            // the function analysis does an equivalent check. Instead of just rejecting
+            // the function, it creates a wrapper function instead with a more
+            // palatable name. That's preferable to rejecting the API entirely.
+            validate_all_segments_ok_for_cxx(name.name.segment_iter())?;
+            Ok(Box::new(std::iter::once(api)))
+        }
+        Api::ConcreteType { .. }
+        | Api::CType { .. }
+        | Api::StringConstructor { .. }
+        | Api::RustType { .. }
+        | Api::RustSubclassFn { .. }
+        | Api::RustFn { .. }
+        | Api::SubclassTraitItem { .. }
+        | Api::ExternCppType { .. }
+        | Api::IgnoredItem { .. } => Ok(Box::new(std::iter::once(api))),
+    });
+
+    // Reject any names which are duplicates within the cxx bridge mod,
+    // that has a flat namespace.
+    let mut names_found: HashMap<Ident, Vec<String>> = HashMap::new();
+    for api in intermediate.iter() {
+        let my_name = api.cxxbridge_name();
+        if let Some(name) = my_name {
+            let e = names_found.entry(name).or_default();
+            e.push(api.name_info().name.to_string());
+        }
+    }
+    let mut results = ApiVec::new();
+    convert_item_apis(intermediate, &mut results, |api| {
+        let my_name = api.cxxbridge_name();
+        if let Some(name) = my_name {
+            let symbols_for_this_name = names_found.entry(name).or_default();
+            if symbols_for_this_name.len() > 1usize {
+                Err(ConvertError::DuplicateCxxBridgeName(
+                    symbols_for_this_name.clone(),
+                ))
+            } else {
+                Ok(Box::new(std::iter::once(api)))
+            }
+        } else {
+            Ok(Box::new(std::iter::once(api)))
+        }
+    });
+    results
+}
+
+fn validate_all_segments_ok_for_cxx(
+    items: impl Iterator<Item = String>,
+) -> Result<(), ConvertError> {
+    for seg in items {
+        validate_ident_ok_for_cxx(&seg)?;
+    }
+    Ok(())
+}
diff --git a/engine/src/conversion/analysis/pod/byvalue_checker.rs b/engine/src/conversion/analysis/pod/byvalue_checker.rs
new file mode 100644
index 0000000..de72eec
--- /dev/null
+++ b/engine/src/conversion/analysis/pod/byvalue_checker.rs
@@ -0,0 +1,343 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::conversion::apivec::ApiVec;
+use crate::{conversion::ConvertError, known_types::known_types};
+use crate::{
+    conversion::{
+        analysis::tdef::TypedefPhase,
+        api::{Api, TypedefKind},
+    },
+    types::{Namespace, QualifiedName},
+};
+use autocxx_parser::IncludeCppConfig;
+use std::collections::HashMap;
+use syn::{ItemStruct, Type};
+
+#[derive(Clone)]
+enum PodState {
+    UnsafeToBePod(String),
+    SafeToBePod,
+    IsPod,
+    IsAlias(QualifiedName),
+}
+
+#[derive(Clone)]
+struct StructDetails {
+    state: PodState,
+    dependent_structs: Vec<QualifiedName>,
+}
+
+impl StructDetails {
+    fn new(state: PodState) -> Self {
+        StructDetails {
+            state,
+            dependent_structs: Vec::new(),
+        }
+    }
+}
+
+/// Type which is able to check whether it's safe to make a type
+/// fully representable by cxx. For instance if it is a struct containing
+/// a struct containing a std::string, the answer is no, because that
+/// std::string contains a self-referential pointer.
+/// It is possible that this is duplicative of the information stored
+/// elsewhere in the `Api` list and could possibly be removed or simplified.
+pub struct ByValueChecker {
+    // Mapping from type name to whether it is safe to be POD
+    results: HashMap<QualifiedName, StructDetails>,
+}
+
+impl ByValueChecker {
+    pub fn new() -> Self {
+        let mut results = HashMap::new();
+        for (tn, by_value_safe) in known_types().get_pod_safe_types() {
+            let safety = if by_value_safe {
+                PodState::IsPod
+            } else {
+                PodState::UnsafeToBePod(format!("type {} is not safe for POD", tn))
+            };
+            results.insert(tn.clone(), StructDetails::new(safety));
+        }
+        ByValueChecker { results }
+    }
+
+    /// Scan APIs to work out which are by-value safe. Constructs a [ByValueChecker]
+    /// that others can use to query the results.
+    pub(crate) fn new_from_apis(
+        apis: &ApiVec<TypedefPhase>,
+        config: &IncludeCppConfig,
+    ) -> Result<ByValueChecker, ConvertError> {
+        let mut byvalue_checker = ByValueChecker::new();
+        for blocklisted in config.get_blocklist() {
+            let tn = QualifiedName::new_from_cpp_name(blocklisted);
+            let safety = PodState::UnsafeToBePod(format!("type {} is on the blocklist", &tn));
+            byvalue_checker
+                .results
+                .insert(tn, StructDetails::new(safety));
+        }
+        for api in apis.iter() {
+            match api {
+                Api::Typedef { analysis, .. } => {
+                    let name = api.name();
+                    let typedef_type = match analysis.kind {
+                        TypedefKind::Type(ref type_item) => match type_item.ty.as_ref() {
+                            Type::Path(typ) => {
+                                let target_tn = QualifiedName::from_type_path(typ);
+                                known_types().consider_substitution(&target_tn)
+                            }
+                            _ => None,
+                        },
+                        TypedefKind::Use(_, ref ty) => match **ty {
+                            Type::Path(ref typ) => {
+                                let target_tn = QualifiedName::from_type_path(typ);
+                                known_types().consider_substitution(&target_tn)
+                            }
+                            _ => None,
+                        },
+                    };
+                    match &typedef_type {
+                        Some(typ) => {
+                            byvalue_checker.results.insert(
+                                name.clone(),
+                                StructDetails::new(PodState::IsAlias(
+                                    QualifiedName::from_type_path(typ),
+                                )),
+                            );
+                        }
+                        None => byvalue_checker.ingest_nonpod_type(name.clone()),
+                    }
+                }
+                Api::Struct { details, .. } => {
+                    byvalue_checker.ingest_struct(&details.item, api.name().get_namespace())
+                }
+                Api::Enum { .. } => {
+                    byvalue_checker
+                        .results
+                        .insert(api.name().clone(), StructDetails::new(PodState::IsPod));
+                }
+                Api::ExternCppType { pod: true, .. } => {
+                    byvalue_checker
+                        .results
+                        .insert(api.name().clone(), StructDetails::new(PodState::IsPod));
+                }
+                _ => {}
+            }
+        }
+        let pod_requests = config
+            .get_pod_requests()
+            .iter()
+            .map(|ty| QualifiedName::new_from_cpp_name(ty))
+            .collect();
+        byvalue_checker
+            .satisfy_requests(pod_requests)
+            .map_err(ConvertError::UnsafePodType)?;
+        Ok(byvalue_checker)
+    }
+
+    fn ingest_struct(&mut self, def: &ItemStruct, ns: &Namespace) {
+        // For this struct, work out whether it _could_ be safe as a POD.
+        let tyname = QualifiedName::new(ns, def.ident.clone());
+        let mut field_safety_problem = PodState::SafeToBePod;
+        let fieldlist = Self::get_field_types(def);
+        for ty_id in &fieldlist {
+            match self.results.get(ty_id) {
+                None => {
+                    field_safety_problem = PodState::UnsafeToBePod(format!(
+                        "Type {} could not be POD because its dependent type {} isn't known",
+                        tyname, ty_id
+                    ));
+                    break;
+                }
+                Some(deets) => {
+                    if let PodState::UnsafeToBePod(reason) = &deets.state {
+                        let new_reason = format!("Type {} could not be POD because its dependent type {} isn't safe to be POD. Because: {}", tyname, ty_id, reason);
+                        field_safety_problem = PodState::UnsafeToBePod(new_reason);
+                        break;
+                    }
+                }
+            }
+        }
+        if Self::has_vtable(def) {
+            let reason = format!(
+                "Type {} could not be POD because it has virtual functions.",
+                tyname
+            );
+            field_safety_problem = PodState::UnsafeToBePod(reason);
+        }
+        let mut my_details = StructDetails::new(field_safety_problem);
+        my_details.dependent_structs = fieldlist;
+        self.results.insert(tyname, my_details);
+    }
+
+    fn ingest_nonpod_type(&mut self, tyname: QualifiedName) {
+        let new_reason = format!("Type {} is a typedef to a complex type", tyname);
+        self.results.insert(
+            tyname,
+            StructDetails::new(PodState::UnsafeToBePod(new_reason)),
+        );
+    }
+
+    fn satisfy_requests(&mut self, mut requests: Vec<QualifiedName>) -> Result<(), String> {
+        while !requests.is_empty() {
+            let ty_id = requests.remove(requests.len() - 1);
+            let deets = self.results.get_mut(&ty_id);
+            let mut alias_to_consider = None;
+            match deets {
+                None => {
+                    return Err(format!(
+                        "Unable to make {} POD because we never saw a struct definition",
+                        ty_id
+                    ))
+                }
+                Some(deets) => match &deets.state {
+                    PodState::UnsafeToBePod(error_msg) => return Err(error_msg.clone()),
+                    PodState::IsPod => {}
+                    PodState::SafeToBePod => {
+                        deets.state = PodState::IsPod;
+                        requests.extend_from_slice(&deets.dependent_structs);
+                    }
+                    PodState::IsAlias(target_type) => {
+                        alias_to_consider = Some(target_type.clone());
+                    }
+                },
+            }
+            // Do the following outside the match to avoid borrow checker violation.
+            if let Some(alias) = alias_to_consider {
+                match self.results.get(&alias) {
+                    None => requests.extend_from_slice(&[alias, ty_id]), // try again after resolving alias target
+                    Some(alias_target_deets) => {
+                        self.results.get_mut(&ty_id).unwrap().state =
+                            alias_target_deets.state.clone();
+                    }
+                }
+            }
+        }
+        Ok(())
+    }
+
+    /// Return whether a given type is POD (i.e. can be represented by value in Rust) or not.
+    /// Unless we've got a definite record that it _is_, we return false.
+    /// Some types won't be in our `results` map. For example: (a) AutocxxConcrete types
+    /// which we've synthesized; (b) types we couldn't parse but returned ignorable
+    /// errors so that we could continue. Assume non-POD for all such cases.
+    pub fn is_pod(&self, ty_id: &QualifiedName) -> bool {
+        matches!(
+            self.results.get(ty_id),
+            Some(StructDetails {
+                state: PodState::IsPod,
+                dependent_structs: _,
+            })
+        )
+    }
+
+    fn get_field_types(def: &ItemStruct) -> Vec<QualifiedName> {
+        let mut results = Vec::new();
+        for f in &def.fields {
+            let fty = &f.ty;
+            if let Type::Path(p) = fty {
+                results.push(QualifiedName::from_type_path(p));
+            }
+            // TODO handle anything else which bindgen might spit out, e.g. arrays?
+        }
+        results
+    }
+
+    fn has_vtable(def: &ItemStruct) -> bool {
+        for f in &def.fields {
+            if f.ident.as_ref().map(|id| id == "vtable_").unwrap_or(false) {
+                return true;
+            }
+        }
+        false
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::ByValueChecker;
+    use crate::types::{Namespace, QualifiedName};
+    use syn::{parse_quote, Ident, ItemStruct};
+
+    fn ty_from_ident(id: &Ident) -> QualifiedName {
+        QualifiedName::new_from_cpp_name(&id.to_string())
+    }
+
+    #[test]
+    fn test_primitive_by_itself() {
+        let bvc = ByValueChecker::new();
+        let t_id = QualifiedName::new_from_cpp_name("u32");
+        assert!(bvc.is_pod(&t_id));
+    }
+
+    #[test]
+    fn test_primitives() {
+        let mut bvc = ByValueChecker::new();
+        let t: ItemStruct = parse_quote! {
+            struct Foo {
+                a: i32,
+                b: i64,
+            }
+        };
+        let t_id = ty_from_ident(&t.ident);
+        bvc.ingest_struct(&t, &Namespace::new());
+        bvc.satisfy_requests(vec![t_id.clone()]).unwrap();
+        assert!(bvc.is_pod(&t_id));
+    }
+
+    #[test]
+    fn test_nested_primitives() {
+        let mut bvc = ByValueChecker::new();
+        let t: ItemStruct = parse_quote! {
+            struct Foo {
+                a: i32,
+                b: i64,
+            }
+        };
+        bvc.ingest_struct(&t, &Namespace::new());
+        let t: ItemStruct = parse_quote! {
+            struct Bar {
+                a: Foo,
+                b: i64,
+            }
+        };
+        let t_id = ty_from_ident(&t.ident);
+        bvc.ingest_struct(&t, &Namespace::new());
+        bvc.satisfy_requests(vec![t_id.clone()]).unwrap();
+        assert!(bvc.is_pod(&t_id));
+    }
+
+    #[test]
+    fn test_with_up() {
+        let mut bvc = ByValueChecker::new();
+        let t: ItemStruct = parse_quote! {
+            struct Bar {
+                a: cxx::UniquePtr<CxxString>,
+                b: i64,
+            }
+        };
+        let t_id = ty_from_ident(&t.ident);
+        bvc.ingest_struct(&t, &Namespace::new());
+        bvc.satisfy_requests(vec![t_id.clone()]).unwrap();
+        assert!(bvc.is_pod(&t_id));
+    }
+
+    #[test]
+    fn test_with_cxxstring() {
+        let mut bvc = ByValueChecker::new();
+        let t: ItemStruct = parse_quote! {
+            struct Bar {
+                a: CxxString,
+                b: i64,
+            }
+        };
+        let t_id = ty_from_ident(&t.ident);
+        bvc.ingest_struct(&t, &Namespace::new());
+        assert!(bvc.satisfy_requests(vec![t_id]).is_err());
+    }
+}
diff --git a/engine/src/conversion/analysis/pod/mod.rs b/engine/src/conversion/analysis/pod/mod.rs
new file mode 100644
index 0000000..6722c23
--- /dev/null
+++ b/engine/src/conversion/analysis/pod/mod.rs
@@ -0,0 +1,257 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod byvalue_checker;
+
+use indexmap::map::IndexMap as HashMap;
+use indexmap::set::IndexSet as HashSet;
+
+use autocxx_parser::IncludeCppConfig;
+use byvalue_checker::ByValueChecker;
+use syn::{ItemEnum, ItemStruct, Type, Visibility};
+
+use crate::{
+    conversion::{
+        analysis::type_converter::{self, add_analysis, TypeConversionContext, TypeConverter},
+        api::{AnalysisPhase, Api, ApiName, CppVisibility, NullPhase, StructDetails, TypeKind},
+        apivec::ApiVec,
+        convert_error::{ConvertErrorWithContext, ErrorContext},
+        error_reporter::convert_apis,
+        parse::BindgenSemanticAttributes,
+        ConvertError,
+    },
+    types::{Namespace, QualifiedName},
+};
+
+use super::tdef::{TypedefAnalysis, TypedefPhase};
+
+pub(crate) struct FieldInfo {
+    pub(crate) ty: Type,
+    pub(crate) type_kind: type_converter::TypeKind,
+}
+
+pub(crate) struct PodAnalysis {
+    pub(crate) kind: TypeKind,
+    pub(crate) bases: HashSet<QualifiedName>,
+    /// Base classes for which we should create casts.
+    /// That's just those which are on the allowlist,
+    /// because otherwise we don't know whether they're
+    /// abstract or not.
+    pub(crate) castable_bases: HashSet<QualifiedName>,
+    pub(crate) field_deps: HashSet<QualifiedName>,
+    pub(crate) field_info: Vec<FieldInfo>,
+    pub(crate) is_generic: bool,
+    pub(crate) in_anonymous_namespace: bool,
+}
+
+pub(crate) struct PodPhase;
+
+impl AnalysisPhase for PodPhase {
+    type TypedefAnalysis = TypedefAnalysis;
+    type StructAnalysis = PodAnalysis;
+    type FunAnalysis = ();
+}
+
+/// In our set of APIs, work out which ones are safe to represent
+/// by value in Rust (e.g. they don't have a destructor) and record
+/// as such. Return a set of APIs annotated with extra metadata,
+/// and an object which can be used to query the POD status of any
+/// type whether or not it's one of the [Api]s.
+pub(crate) fn analyze_pod_apis(
+    apis: ApiVec<TypedefPhase>,
+    config: &IncludeCppConfig,
+) -> Result<ApiVec<PodPhase>, ConvertError> {
+    // This next line will return an error if any of the 'generate_pod'
+    // directives from the user can't be met because, for instance,
+    // a type contains a std::string or some other type which can't be
+    // held safely by value in Rust.
+    let byvalue_checker = ByValueChecker::new_from_apis(&apis, config)?;
+    let mut extra_apis = ApiVec::new();
+    let mut type_converter = TypeConverter::new(config, &apis);
+    let mut results = ApiVec::new();
+    convert_apis(
+        apis,
+        &mut results,
+        Api::fun_unchanged,
+        |name, details, _| {
+            analyze_struct(
+                &byvalue_checker,
+                &mut type_converter,
+                &mut extra_apis,
+                name,
+                details,
+                config,
+            )
+        },
+        analyze_enum,
+        Api::typedef_unchanged,
+    );
+    // Conceivably, the process of POD-analysing the first set of APIs could result
+    // in us creating new APIs to concretize generic types.
+    let extra_apis: ApiVec<PodPhase> = extra_apis.into_iter().map(add_analysis).collect();
+    let mut more_extra_apis = ApiVec::new();
+    convert_apis(
+        extra_apis,
+        &mut results,
+        Api::fun_unchanged,
+        |name, details, _| {
+            analyze_struct(
+                &byvalue_checker,
+                &mut type_converter,
+                &mut more_extra_apis,
+                name,
+                details,
+                config,
+            )
+        },
+        analyze_enum,
+        Api::typedef_unchanged,
+    );
+    assert!(more_extra_apis.is_empty());
+    Ok(results)
+}
+
+fn analyze_enum(
+    name: ApiName,
+    mut item: ItemEnum,
+) -> Result<Box<dyn Iterator<Item = Api<PodPhase>>>, ConvertErrorWithContext> {
+    let metadata = BindgenSemanticAttributes::new_retaining_others(&mut item.attrs);
+    metadata.check_for_fatal_attrs(&name.name.get_final_ident())?;
+    Ok(Box::new(std::iter::once(Api::Enum { name, item })))
+}
+
+fn analyze_struct(
+    byvalue_checker: &ByValueChecker,
+    type_converter: &mut TypeConverter,
+    extra_apis: &mut ApiVec<NullPhase>,
+    name: ApiName,
+    mut details: Box<StructDetails>,
+    config: &IncludeCppConfig,
+) -> Result<Box<dyn Iterator<Item = Api<PodPhase>>>, ConvertErrorWithContext> {
+    let id = name.name.get_final_ident();
+    if details.vis != CppVisibility::Public {
+        return Err(ConvertErrorWithContext(
+            ConvertError::NonPublicNestedType,
+            Some(ErrorContext::new_for_item(id)),
+        ));
+    }
+    let metadata = BindgenSemanticAttributes::new_retaining_others(&mut details.item.attrs);
+    metadata.check_for_fatal_attrs(&id)?;
+    let bases = get_bases(&details.item);
+    let mut field_deps = HashSet::new();
+    let mut field_info = Vec::new();
+    let field_conversion_errors = get_struct_field_types(
+        type_converter,
+        name.name.get_namespace(),
+        &details.item,
+        &mut field_deps,
+        &mut field_info,
+        extra_apis,
+    );
+    let type_kind = if byvalue_checker.is_pod(&name.name) {
+        // It's POD so any errors encountered parsing its fields are important.
+        // Let's not allow anything to be POD if it's got rvalue reference fields.
+        if details.has_rvalue_reference_fields {
+            return Err(ConvertErrorWithContext(
+                ConvertError::RValueReferenceField,
+                Some(ErrorContext::new_for_item(id)),
+            ));
+        }
+        if let Some(err) = field_conversion_errors.into_iter().next() {
+            return Err(ConvertErrorWithContext(
+                err,
+                Some(ErrorContext::new_for_item(id)),
+            ));
+        }
+        TypeKind::Pod
+    } else {
+        TypeKind::NonPod
+    };
+    let castable_bases = bases
+        .iter()
+        .filter(|(_, is_public)| **is_public)
+        .map(|(base, _)| base)
+        .filter(|base| config.is_on_allowlist(&base.to_cpp_name()))
+        .cloned()
+        .collect();
+    let is_generic = !details.item.generics.params.is_empty();
+    let in_anonymous_namespace = name
+        .name
+        .ns_segment_iter()
+        .any(|ns| ns.starts_with("_bindgen_mod"));
+    Ok(Box::new(std::iter::once(Api::Struct {
+        name,
+        details,
+        analysis: PodAnalysis {
+            kind: type_kind,
+            bases: bases.into_keys().collect(),
+            castable_bases,
+            field_deps,
+            field_info,
+            is_generic,
+            in_anonymous_namespace,
+        },
+    })))
+}
+
+fn get_struct_field_types(
+    type_converter: &mut TypeConverter,
+    ns: &Namespace,
+    s: &ItemStruct,
+    field_deps: &mut HashSet<QualifiedName>,
+    field_info: &mut Vec<FieldInfo>,
+    extra_apis: &mut ApiVec<NullPhase>,
+) -> Vec<ConvertError> {
+    let mut convert_errors = Vec::new();
+    for f in &s.fields {
+        let annotated =
+            type_converter.convert_type(f.ty.clone(), ns, &TypeConversionContext::WithinReference);
+        match annotated {
+            Ok(mut r) => {
+                extra_apis.append(&mut r.extra_apis);
+                // Skip base classes represented as fields. Anything which wants to include bases can chain
+                // those to the list we're building.
+                if !f
+                    .ident
+                    .as_ref()
+                    .map(|id| {
+                        id.to_string().starts_with("_base")
+                            || id.to_string().starts_with("__bindgen_padding")
+                    })
+                    .unwrap_or(false)
+                {
+                    field_deps.extend(r.types_encountered);
+                    field_info.push(FieldInfo {
+                        ty: r.ty,
+                        type_kind: r.kind,
+                    });
+                }
+            }
+            Err(e) => convert_errors.push(e),
+        };
+    }
+    convert_errors
+}
+
+/// Map to whether the bases are public.
+fn get_bases(item: &ItemStruct) -> HashMap<QualifiedName, bool> {
+    item.fields
+        .iter()
+        .filter_map(|f| {
+            let is_public = matches!(f.vis, Visibility::Public(_));
+            match &f.ty {
+                Type::Path(typ) => f
+                    .ident
+                    .as_ref()
+                    .filter(|id| id.to_string().starts_with("_base"))
+                    .map(|_| (QualifiedName::from_type_path(typ), is_public)),
+                _ => None,
+            }
+        })
+        .collect()
+}
diff --git a/engine/src/conversion/analysis/remove_ignored.rs b/engine/src/conversion/analysis/remove_ignored.rs
new file mode 100644
index 0000000..bd11b13
--- /dev/null
+++ b/engine/src/conversion/analysis/remove_ignored.rs
@@ -0,0 +1,95 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::set::IndexSet as HashSet;
+
+use super::deps::HasDependencies;
+use super::fun::{FnAnalysis, FnKind, FnPhase};
+use crate::conversion::apivec::ApiVec;
+use crate::conversion::{convert_error::ErrorContext, ConvertError};
+use crate::{conversion::api::Api, known_types};
+
+/// Remove any APIs which depend on other items which have been ignored.
+/// We also eliminate any APIs that depend on some type that we just don't
+/// know about at all. In either case, we don't simply remove the type, but instead
+/// replace it with an error marker.
+pub(crate) fn filter_apis_by_ignored_dependents(mut apis: ApiVec<FnPhase>) -> ApiVec<FnPhase> {
+    let (ignored_items, valid_items): (Vec<&Api<_>>, Vec<&Api<_>>) = apis
+        .iter()
+        .partition(|api| matches!(api, Api::IgnoredItem { .. }));
+    let mut ignored_items: HashSet<_> = ignored_items
+        .into_iter()
+        .map(|api| api.name().clone())
+        .collect();
+    let valid_types: HashSet<_> = valid_items
+        .into_iter()
+        .flat_map(|api| api.valid_types())
+        .collect();
+    let mut iterate_again = true;
+    while iterate_again {
+        iterate_again = false;
+        apis = apis
+            .into_iter()
+            .map(|api| {
+                let ignored_dependents: HashSet<_> = api
+                    .deps()
+                    .filter(|dep| ignored_items.contains(*dep))
+                    .cloned()
+                    .collect();
+                if !ignored_dependents.is_empty() {
+                    iterate_again = true;
+                    ignored_items.insert(api.name().clone());
+                    create_ignore_item(api, ConvertError::IgnoredDependent(ignored_dependents))
+                } else {
+                    let mut missing_deps = api.deps().filter(|dep| {
+                        !valid_types.contains(*dep) && !known_types().is_known_type(dep)
+                    });
+                    let first = missing_deps.next();
+                    std::mem::drop(missing_deps);
+                    if let Some(missing_dep) = first.cloned() {
+                        create_ignore_item(api, ConvertError::UnknownDependentType(missing_dep))
+                    } else {
+                        api
+                    }
+                }
+            })
+            .collect();
+    }
+    apis
+}
+
+fn create_ignore_item(api: Api<FnPhase>, err: ConvertError) -> Api<FnPhase> {
+    let id = api.name().get_final_ident();
+    log::info!("Marking as ignored: {} because {}", id.to_string(), err);
+    Api::IgnoredItem {
+        name: api.name_info().clone(),
+        err,
+        ctx: match api {
+            Api::Function {
+                analysis:
+                    FnAnalysis {
+                        kind: FnKind::TraitMethod { .. },
+                        ..
+                    },
+                ..
+            } => None,
+            Api::Function {
+                analysis:
+                    FnAnalysis {
+                        kind:
+                            FnKind::Method {
+                                impl_for: self_ty, ..
+                            },
+                        ..
+                    },
+                ..
+            } => Some(ErrorContext::new_for_method(self_ty.get_final_ident(), id)),
+            _ => Some(ErrorContext::new_for_item(id)),
+        },
+    }
+}
diff --git a/engine/src/conversion/analysis/replace_hopeless_typedef_targets.rs b/engine/src/conversion/analysis/replace_hopeless_typedef_targets.rs
new file mode 100644
index 0000000..8d5d033
--- /dev/null
+++ b/engine/src/conversion/analysis/replace_hopeless_typedef_targets.rs
@@ -0,0 +1,100 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use autocxx_parser::IncludeCppConfig;
+use indexmap::set::IndexSet as HashSet;
+
+use crate::{
+    conversion::{
+        analysis::tdef::TypedefAnalysis,
+        api::Api,
+        apivec::ApiVec,
+        convert_error::{ConvertErrorWithContext, ErrorContext},
+        ConvertError,
+    },
+    types::QualifiedName,
+};
+
+use super::pod::PodPhase;
+/// Where we find a typedef pointing at something we can't represent,
+/// e.g. because it uses too many template parameters, break the link.
+/// Use the typedef as a first-class type.
+pub(crate) fn replace_hopeless_typedef_targets(
+    config: &IncludeCppConfig,
+    apis: ApiVec<PodPhase>,
+) -> ApiVec<PodPhase> {
+    let ignored_types: HashSet<QualifiedName> = apis
+        .iter()
+        .filter_map(|api| match api {
+            Api::IgnoredItem { .. } => Some(api.name()),
+            _ => None,
+        })
+        .cloned()
+        .collect();
+    let ignored_forward_declarations: HashSet<QualifiedName> = apis
+        .iter()
+        .filter_map(|api| match api {
+            Api::ForwardDeclaration { err: Some(_), .. } => Some(api.name()),
+            _ => None,
+        })
+        .cloned()
+        .collect();
+    // Convert any Typedefs which depend on these things into OpaqueTypedefs
+    // instead.
+    // And, after this point we no longer need special knowledge of forward
+    // declarations with errors, so just convert them into regular IgnoredItems too.
+    apis.into_iter()
+        .map(|api| match api {
+            Api::Typedef {
+                ref name,
+                analysis: TypedefAnalysis { ref deps, .. },
+                ..
+            } if !ignored_types.is_disjoint(deps) =>
+            // This typedef depended on something we ignored.
+            // Ideally, we'd turn it into an opaque item.
+            // We can't do that if this is an inner type,
+            // because we have no way to know if it's abstract or not,
+            // and we can't represent inner types in cxx without knowing
+            // that.
+            {
+                let name_id = name.name.get_final_ident();
+                if api
+                    .cpp_name()
+                    .as_ref()
+                    .map(|n| n.contains("::"))
+                    .unwrap_or_default()
+                {
+                    Api::IgnoredItem {
+                        name: api.name_info().clone(),
+                        err: ConvertError::NestedOpaqueTypedef,
+                        ctx: Some(ErrorContext::new_for_item(name_id)),
+                    }
+                } else {
+                    Api::OpaqueTypedef {
+                        name: api.name_info().clone(),
+                        forward_declaration: !config
+                            .instantiable
+                            .contains(&name.name.to_cpp_name()),
+                    }
+                }
+            }
+            Api::Typedef {
+                analysis: TypedefAnalysis { ref deps, .. },
+                ..
+            } if !ignored_forward_declarations.is_disjoint(deps) => Api::OpaqueTypedef {
+                name: api.name_info().clone(),
+                forward_declaration: true,
+            },
+            Api::ForwardDeclaration {
+                name,
+                err: Some(ConvertErrorWithContext(err, ctx)),
+            } => Api::IgnoredItem { name, err, ctx },
+            _ => api,
+        })
+        .collect()
+}
diff --git a/engine/src/conversion/analysis/tdef.rs b/engine/src/conversion/analysis/tdef.rs
new file mode 100644
index 0000000..5a635f8
--- /dev/null
+++ b/engine/src/conversion/analysis/tdef.rs
@@ -0,0 +1,128 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::set::IndexSet as HashSet;
+
+use autocxx_parser::IncludeCppConfig;
+use syn::ItemType;
+
+use crate::{
+    conversion::{
+        analysis::type_converter::{add_analysis, Annotated, TypeConversionContext, TypeConverter},
+        api::{AnalysisPhase, Api, ApiName, NullPhase, TypedefKind},
+        apivec::ApiVec,
+        convert_error::{ConvertErrorWithContext, ErrorContext},
+        error_reporter::convert_apis,
+        parse::BindgenSemanticAttributes,
+        ConvertError,
+    },
+    types::QualifiedName,
+};
+
+pub(crate) struct TypedefAnalysis {
+    pub(crate) kind: TypedefKind,
+    pub(crate) deps: HashSet<QualifiedName>,
+}
+
+/// Analysis phase where typedef analysis has been performed but no other
+/// analyses just yet.
+pub(crate) struct TypedefPhase;
+
+impl AnalysisPhase for TypedefPhase {
+    type TypedefAnalysis = TypedefAnalysis;
+    type StructAnalysis = ();
+    type FunAnalysis = ();
+}
+
+#[allow(clippy::needless_collect)] // we need the extra collect because the closure borrows extra_apis
+pub(crate) fn convert_typedef_targets(
+    config: &IncludeCppConfig,
+    apis: ApiVec<NullPhase>,
+) -> ApiVec<TypedefPhase> {
+    let mut type_converter = TypeConverter::new(config, &apis);
+    let mut extra_apis = ApiVec::new();
+    let mut results = ApiVec::new();
+    convert_apis(
+        apis,
+        &mut results,
+        Api::fun_unchanged,
+        Api::struct_unchanged,
+        Api::enum_unchanged,
+        |name, item, old_tyname, _| {
+            Ok(Box::new(std::iter::once(match item {
+                TypedefKind::Type(ity) => get_replacement_typedef(
+                    name,
+                    ity,
+                    old_tyname,
+                    &mut type_converter,
+                    &mut extra_apis,
+                )?,
+                TypedefKind::Use { .. } => Api::Typedef {
+                    name,
+                    item: item.clone(),
+                    old_tyname,
+                    analysis: TypedefAnalysis {
+                        kind: item,
+                        deps: HashSet::new(),
+                    },
+                },
+            })))
+        },
+    );
+    results.extend(extra_apis.into_iter().map(add_analysis));
+    results
+}
+
+fn get_replacement_typedef(
+    name: ApiName,
+    ity: ItemType,
+    old_tyname: Option<QualifiedName>,
+    type_converter: &mut TypeConverter,
+    extra_apis: &mut ApiVec<NullPhase>,
+) -> Result<Api<TypedefPhase>, ConvertErrorWithContext> {
+    if !ity.generics.params.is_empty() {
+        return Err(ConvertErrorWithContext(
+            ConvertError::TypedefTakesGenericParameters,
+            Some(ErrorContext::new_for_item(name.name.get_final_ident())),
+        ));
+    }
+    let mut converted_type = ity.clone();
+    let metadata = BindgenSemanticAttributes::new_retaining_others(&mut converted_type.attrs);
+    metadata.check_for_fatal_attrs(&ity.ident)?;
+    let type_conversion_results = type_converter.convert_type(
+        (*ity.ty).clone(),
+        name.name.get_namespace(),
+        &TypeConversionContext::WithinReference,
+    );
+    match type_conversion_results {
+        Err(err) => Err(ConvertErrorWithContext(
+            err,
+            Some(ErrorContext::new_for_item(name.name.get_final_ident())),
+        )),
+        Ok(Annotated {
+            ty: syn::Type::Path(ref typ),
+            ..
+        }) if QualifiedName::from_type_path(typ) == name.name => Err(ConvertErrorWithContext(
+            ConvertError::InfinitelyRecursiveTypedef(name.name.clone()),
+            Some(ErrorContext::new_for_item(name.name.get_final_ident())),
+        )),
+        Ok(mut final_type) => {
+            converted_type.ty = Box::new(final_type.ty.clone());
+            extra_apis.append(&mut final_type.extra_apis);
+            Ok(Api::Typedef {
+                name,
+                item: TypedefKind::Type(ity),
+                old_tyname,
+                analysis: TypedefAnalysis {
+                    kind: TypedefKind::Type(converted_type),
+                    deps: final_type.types_encountered,
+                },
+            })
+        }
+    }
+}
diff --git a/engine/src/conversion/analysis/type_converter.rs b/engine/src/conversion/analysis/type_converter.rs
new file mode 100644
index 0000000..afdda8a
--- /dev/null
+++ b/engine/src/conversion/analysis/type_converter.rs
@@ -0,0 +1,686 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::{
+    conversion::{
+        api::{AnalysisPhase, Api, ApiName, NullPhase, TypedefKind, UnanalyzedApi},
+        apivec::ApiVec,
+        codegen_cpp::type_to_cpp::type_to_cpp,
+        ConvertError,
+    },
+    known_types::{known_types, CxxGenericType},
+    types::{make_ident, Namespace, QualifiedName},
+};
+use autocxx_parser::IncludeCppConfig;
+use indexmap::map::IndexMap as HashMap;
+use indexmap::set::IndexSet as HashSet;
+use itertools::Itertools;
+use proc_macro2::Ident;
+use quote::ToTokens;
+use syn::{
+    parse_quote, punctuated::Punctuated, token::Comma, GenericArgument, PathArguments, PathSegment,
+    Type, TypePath, TypePtr,
+};
+
+use super::tdef::TypedefAnalysis;
+
+/// Certain kinds of type may require special handling by callers.
+#[derive(Debug)]
+pub(crate) enum TypeKind {
+    Regular,
+    Pointer,
+    SubclassHolder(Ident),
+    Reference,
+    RValueReference,
+    MutableReference,
+}
+
+/// Results of some type conversion, annotated with a list of every type encountered,
+/// and optionally any extra APIs we need in order to use this type.
+pub(crate) struct Annotated<T> {
+    pub(crate) ty: T,
+    pub(crate) types_encountered: HashSet<QualifiedName>,
+    pub(crate) extra_apis: ApiVec<NullPhase>,
+    pub(crate) kind: TypeKind,
+}
+
+impl<T> Annotated<T> {
+    fn new(
+        ty: T,
+        types_encountered: HashSet<QualifiedName>,
+        extra_apis: ApiVec<NullPhase>,
+        kind: TypeKind,
+    ) -> Self {
+        Self {
+            ty,
+            types_encountered,
+            extra_apis,
+            kind,
+        }
+    }
+
+    fn map<T2, F: FnOnce(T) -> T2>(self, fun: F) -> Annotated<T2> {
+        Annotated {
+            ty: fun(self.ty),
+            types_encountered: self.types_encountered,
+            extra_apis: self.extra_apis,
+            kind: self.kind,
+        }
+    }
+}
+
+/// How to interpret a pointer which we encounter during type conversion.
+#[derive(Clone, Copy)]
+pub(crate) enum PointerTreatment {
+    Pointer,
+    Reference,
+    RValueReference,
+}
+
+/// Options when converting a type.
+/// It's possible we could add more policies here in future.
+/// For example, Rust in general allows type names containing
+/// __, whereas cxx doesn't. If we could identify cases where
+/// a type will only ever be used in a bindgen context,
+/// we could be more liberal. At the moment though, all outputs
+/// from [TypeConverter] _might_ be used in the [cxx::bridge].
+pub(crate) enum TypeConversionContext {
+    WithinReference,
+    WithinContainer,
+    OuterType { pointer_treatment: PointerTreatment },
+}
+
+impl TypeConversionContext {
+    fn pointer_treatment(&self) -> PointerTreatment {
+        match self {
+            Self::WithinReference | Self::WithinContainer => PointerTreatment::Pointer,
+            Self::OuterType { pointer_treatment } => *pointer_treatment,
+        }
+    }
+    fn allow_instantiation_of_forward_declaration(&self) -> bool {
+        matches!(self, Self::WithinReference)
+    }
+}
+
+/// A type which can convert from a type encountered in `bindgen`
+/// output to the sort of type we should represeent to `cxx`.
+/// As a simple example, `std::string` should be replaced
+/// with [CxxString]. This also involves keeping track
+/// of typedefs, and any instantiated concrete types.
+///
+/// To do this conversion correctly, this type relies on
+/// inspecting the pre-existing list of APIs.
+pub(crate) struct TypeConverter<'a> {
+    types_found: HashSet<QualifiedName>,
+    typedefs: HashMap<QualifiedName, Type>,
+    concrete_templates: HashMap<String, QualifiedName>,
+    forward_declarations: HashSet<QualifiedName>,
+    ignored_types: HashSet<QualifiedName>,
+    config: &'a IncludeCppConfig,
+}
+
+impl<'a> TypeConverter<'a> {
+    pub(crate) fn new<A: AnalysisPhase>(config: &'a IncludeCppConfig, apis: &ApiVec<A>) -> Self
+    where
+        A::TypedefAnalysis: TypedefTarget,
+    {
+        Self {
+            types_found: find_types(apis),
+            typedefs: Self::find_typedefs(apis),
+            concrete_templates: Self::find_concrete_templates(apis),
+            forward_declarations: Self::find_incomplete_types(apis),
+            ignored_types: Self::find_ignored_types(apis),
+            config,
+        }
+    }
+
+    pub(crate) fn convert_boxed_type(
+        &mut self,
+        ty: Box<Type>,
+        ns: &Namespace,
+        ctx: &TypeConversionContext,
+    ) -> Result<Annotated<Box<Type>>, ConvertError> {
+        Ok(self.convert_type(*ty, ns, ctx)?.map(Box::new))
+    }
+
+    pub(crate) fn convert_type(
+        &mut self,
+        ty: Type,
+        ns: &Namespace,
+        ctx: &TypeConversionContext,
+    ) -> Result<Annotated<Type>, ConvertError> {
+        let result = match ty {
+            Type::Path(p) => {
+                let newp = self.convert_type_path(p, ns)?;
+                if let Type::Path(newpp) = &newp.ty {
+                    let qn = QualifiedName::from_type_path(newpp);
+                    if !ctx.allow_instantiation_of_forward_declaration()
+                        && self.forward_declarations.contains(&qn)
+                    {
+                        return Err(ConvertError::TypeContainingForwardDeclaration(qn));
+                    }
+                    // Special handling because rust_Str (as emitted by bindgen)
+                    // doesn't simply get renamed to a different type _identifier_.
+                    // This plain type-by-value (as far as bindgen is concerned)
+                    // is actually a &str.
+                    if known_types().should_dereference_in_cpp(&qn) {
+                        Annotated::new(
+                            Type::Reference(parse_quote! {
+                                &str
+                            }),
+                            newp.types_encountered,
+                            newp.extra_apis,
+                            TypeKind::Reference,
+                        )
+                    } else {
+                        newp
+                    }
+                } else {
+                    newp
+                }
+            }
+            Type::Reference(mut r) => {
+                let innerty =
+                    self.convert_boxed_type(r.elem, ns, &TypeConversionContext::WithinReference)?;
+                r.elem = innerty.ty;
+                Annotated::new(
+                    Type::Reference(r),
+                    innerty.types_encountered,
+                    innerty.extra_apis,
+                    TypeKind::Reference,
+                )
+            }
+            Type::Array(mut arr) => {
+                let innerty =
+                    self.convert_type(*arr.elem, ns, &TypeConversionContext::WithinReference)?;
+                arr.elem = Box::new(innerty.ty);
+                Annotated::new(
+                    Type::Array(arr),
+                    innerty.types_encountered,
+                    innerty.extra_apis,
+                    TypeKind::Regular,
+                )
+            }
+            Type::Ptr(ptr) => self.convert_ptr(ptr, ns, ctx.pointer_treatment())?,
+            _ => return Err(ConvertError::UnknownType(ty.to_token_stream().to_string())),
+        };
+        Ok(result)
+    }
+
+    fn convert_type_path(
+        &mut self,
+        mut typ: TypePath,
+        ns: &Namespace,
+    ) -> Result<Annotated<Type>, ConvertError> {
+        // First, qualify any unqualified paths.
+        if typ.path.segments.iter().next().unwrap().ident != "root" {
+            let ty = QualifiedName::from_type_path(&typ);
+            // If the type looks like it is unqualified, check we know it
+            // already, and if not, qualify it according to the current
+            // namespace. This is a bit of a shortcut compared to having a full
+            // resolution pass which can search all known namespaces.
+            if !known_types().is_known_type(&ty) {
+                let num_segments = typ.path.segments.len();
+                if num_segments > 1 {
+                    return Err(ConvertError::UnsupportedBuiltInType(ty));
+                }
+                if !self.types_found.contains(&ty) {
+                    typ.path.segments = std::iter::once(&"root".to_string())
+                        .chain(ns.iter())
+                        .map(|s| {
+                            let i = make_ident(s);
+                            parse_quote! { #i }
+                        })
+                        .chain(typ.path.segments.into_iter())
+                        .collect();
+                }
+            }
+        }
+
+        let original_tn = QualifiedName::from_type_path(&typ);
+        original_tn.validate_ok_for_cxx()?;
+        if self.config.is_on_blocklist(&original_tn.to_cpp_name()) {
+            return Err(ConvertError::Blocked(original_tn));
+        }
+        let mut deps = HashSet::new();
+
+        // Now convert this type itself.
+        deps.insert(original_tn.clone());
+        // First let's see if this is a typedef.
+        let (typ, tn) = match self.resolve_typedef(&original_tn)? {
+            None => (typ, original_tn),
+            Some(Type::Path(resolved_tp)) => {
+                let resolved_tn = QualifiedName::from_type_path(resolved_tp);
+                deps.insert(resolved_tn.clone());
+                (resolved_tp.clone(), resolved_tn)
+            }
+            Some(Type::Ptr(resolved_tp)) => {
+                return Ok(Annotated::new(
+                    Type::Ptr(resolved_tp.clone()),
+                    deps,
+                    ApiVec::new(),
+                    TypeKind::Pointer,
+                ))
+            }
+            Some(other) => {
+                return Ok(Annotated::new(
+                    other.clone(),
+                    deps,
+                    ApiVec::new(),
+                    TypeKind::Regular,
+                ))
+            }
+        };
+
+        // Now let's see if it's a known type.
+        // (We may entirely reject some types at this point too.)
+        let mut typ = match known_types().consider_substitution(&tn) {
+            Some(mut substitute_type) => {
+                if let Some(last_seg_args) =
+                    typ.path.segments.into_iter().last().map(|ps| ps.arguments)
+                {
+                    let last_seg = substitute_type.path.segments.last_mut().unwrap();
+                    last_seg.arguments = last_seg_args;
+                }
+                substitute_type
+            }
+            None => typ,
+        };
+
+        let mut extra_apis = ApiVec::new();
+        let mut kind = TypeKind::Regular;
+
+        // Finally let's see if it's generic.
+        if let Some(last_seg) = Self::get_generic_args(&mut typ) {
+            let generic_behavior = known_types().cxx_generic_behavior(&tn);
+            let forward_declarations_ok = generic_behavior == CxxGenericType::Rust;
+            if generic_behavior != CxxGenericType::Not {
+                // this is a type of generic understood by cxx (e.g. CxxVector)
+                // so let's convert any generic type arguments. This recurses.
+                if let PathArguments::AngleBracketed(ref mut ab) = last_seg.arguments {
+                    let mut innerty = self.convert_punctuated(
+                        ab.args.clone(),
+                        ns,
+                        &TypeConversionContext::WithinContainer,
+                    )?;
+                    ab.args = innerty.ty;
+                    kind = self.confirm_inner_type_is_acceptable_generic_payload(
+                        &ab.args,
+                        &tn,
+                        generic_behavior,
+                        forward_declarations_ok,
+                    )?;
+                    deps.extend(innerty.types_encountered.drain(..));
+                } else {
+                    return Err(ConvertError::TemplatedTypeContainingNonPathArg(tn.clone()));
+                }
+            } else {
+                // Oh poop. It's a generic type which cxx won't be able to handle.
+                // We'll have to come up with a concrete type in both the cxx::bridge (in Rust)
+                // and a corresponding typedef in C++.
+                // Let's first see if this is a concrete version of a templated type
+                // which we already rejected. Some, but possibly not all, of the reasons
+                // for its rejection would also apply to any concrete types we
+                // make. Err on the side of caution. In future we may be able to relax
+                // this a bit.
+                let qn = QualifiedName::from_type_path(&typ); // ignores generic params
+                if self.ignored_types.contains(&qn) {
+                    return Err(ConvertError::ConcreteVersionOfIgnoredTemplate);
+                }
+                let (new_tn, api) = self.get_templated_typename(&Type::Path(typ))?;
+                extra_apis.extend(api.into_iter());
+                deps.remove(&tn);
+                typ = new_tn.to_type_path();
+                deps.insert(new_tn);
+            }
+        }
+        Ok(Annotated::new(Type::Path(typ), deps, extra_apis, kind))
+    }
+
+    fn get_generic_args(typ: &mut TypePath) -> Option<&mut PathSegment> {
+        match typ.path.segments.last_mut() {
+            Some(s) if !s.arguments.is_empty() => Some(s),
+            _ => None,
+        }
+    }
+
+    fn convert_punctuated<P>(
+        &mut self,
+        pun: Punctuated<GenericArgument, P>,
+        ns: &Namespace,
+        ctx: &TypeConversionContext,
+    ) -> Result<Annotated<Punctuated<GenericArgument, P>>, ConvertError>
+    where
+        P: Default,
+    {
+        let mut new_pun = Punctuated::new();
+        let mut types_encountered = HashSet::new();
+        let mut extra_apis = ApiVec::new();
+        for arg in pun.into_iter() {
+            new_pun.push(match arg {
+                GenericArgument::Type(t) => {
+                    let mut innerty = self.convert_type(t, ns, ctx)?;
+                    types_encountered.extend(innerty.types_encountered.drain(..));
+                    extra_apis.append(&mut innerty.extra_apis);
+                    GenericArgument::Type(innerty.ty)
+                }
+                _ => arg,
+            });
+        }
+        Ok(Annotated::new(
+            new_pun,
+            types_encountered,
+            extra_apis,
+            TypeKind::Regular,
+        ))
+    }
+
+    fn resolve_typedef<'b>(&'b self, tn: &QualifiedName) -> Result<Option<&'b Type>, ConvertError> {
+        let mut encountered = HashSet::new();
+        let mut tn = tn.clone();
+        let mut previous_typ = None;
+        loop {
+            let r = self.typedefs.get(&tn);
+            match r {
+                Some(Type::Path(typ)) => {
+                    previous_typ = r;
+                    let new_tn = QualifiedName::from_type_path(typ);
+                    if encountered.contains(&new_tn) {
+                        return Err(ConvertError::InfinitelyRecursiveTypedef(tn.clone()));
+                    }
+                    encountered.insert(new_tn.clone());
+                    tn = new_tn;
+                }
+                None => return Ok(previous_typ),
+                _ => return Ok(r),
+            }
+        }
+    }
+
+    fn convert_ptr(
+        &mut self,
+        mut ptr: TypePtr,
+        ns: &Namespace,
+        pointer_treatment: PointerTreatment,
+    ) -> Result<Annotated<Type>, ConvertError> {
+        match pointer_treatment {
+            PointerTreatment::Pointer => {
+                crate::known_types::ensure_pointee_is_valid(&ptr)?;
+                let innerty =
+                    self.convert_boxed_type(ptr.elem, ns, &TypeConversionContext::WithinReference)?;
+                ptr.elem = innerty.ty;
+                Ok(Annotated::new(
+                    Type::Ptr(ptr),
+                    innerty.types_encountered,
+                    innerty.extra_apis,
+                    TypeKind::Pointer,
+                ))
+            }
+            PointerTreatment::Reference => {
+                let mutability = ptr.mutability;
+                let elem =
+                    self.convert_boxed_type(ptr.elem, ns, &TypeConversionContext::WithinReference)?;
+                // TODO - in the future, we should check if this is a rust::Str and throw
+                // a wobbler if not. rust::Str should only be seen _by value_ in C++
+                // headers; it manifests as &str in Rust but on the C++ side it must
+                // be a plain value. We should detect and abort.
+                let mut outer = elem.map(|elem| match mutability {
+                    Some(_) => Type::Path(parse_quote! {
+                        ::std::pin::Pin < & #mutability #elem >
+                    }),
+                    None => Type::Reference(parse_quote! {
+                        & #elem
+                    }),
+                });
+                outer.kind = if mutability.is_some() {
+                    TypeKind::MutableReference
+                } else {
+                    TypeKind::Reference
+                };
+                Ok(outer)
+            }
+            PointerTreatment::RValueReference => {
+                crate::known_types::ensure_pointee_is_valid(&ptr)?;
+                let innerty =
+                    self.convert_boxed_type(ptr.elem, ns, &TypeConversionContext::WithinReference)?;
+                ptr.elem = innerty.ty;
+                Ok(Annotated::new(
+                    Type::Ptr(ptr),
+                    innerty.types_encountered,
+                    innerty.extra_apis,
+                    TypeKind::RValueReference,
+                ))
+            }
+        }
+    }
+
+    fn get_templated_typename(
+        &mut self,
+        rs_definition: &Type,
+    ) -> Result<(QualifiedName, Option<UnanalyzedApi>), ConvertError> {
+        let count = self.concrete_templates.len();
+        // We just use this as a hash key, essentially.
+        // TODO: Once we've completed the TypeConverter refactoring (see #220),
+        // pass in an actual original_name_map here.
+        let cpp_definition = type_to_cpp(rs_definition, &HashMap::new())?;
+        let e = self.concrete_templates.get(&cpp_definition);
+        match e {
+            Some(tn) => Ok((tn.clone(), None)),
+            None => {
+                let synthetic_ident = format!(
+                    "{}_AutocxxConcrete",
+                    cpp_definition.replace(|c: char| !(c.is_ascii_alphanumeric() || c == '_'), "_")
+                );
+                // Remove runs of multiple _s. Trying to avoid a dependency on
+                // regex.
+                let synthetic_ident = synthetic_ident
+                    .split('_')
+                    .filter(|s| !s.is_empty())
+                    .join("_");
+                // Ensure we're not duplicating some existing concrete template name.
+                // If so, we'll invent a name which is guaranteed to be unique.
+                let synthetic_ident = match self
+                    .concrete_templates
+                    .values()
+                    .map(|n| n.get_final_item())
+                    .find(|s| s == &synthetic_ident)
+                {
+                    None => synthetic_ident,
+                    Some(_) => format!("AutocxxConcrete{}", count),
+                };
+                let api = UnanalyzedApi::ConcreteType {
+                    name: ApiName::new_in_root_namespace(make_ident(&synthetic_ident)),
+                    cpp_definition: cpp_definition.clone(),
+                    rs_definition: Some(Box::new(rs_definition.clone())),
+                };
+                self.concrete_templates
+                    .insert(cpp_definition, api.name().clone());
+                Ok((api.name().clone(), Some(api)))
+            }
+        }
+    }
+
+    fn confirm_inner_type_is_acceptable_generic_payload(
+        &self,
+        path_args: &Punctuated<GenericArgument, Comma>,
+        desc: &QualifiedName,
+        generic_behavior: CxxGenericType,
+        forward_declarations_ok: bool,
+    ) -> Result<TypeKind, ConvertError> {
+        for inner in path_args {
+            match inner {
+                GenericArgument::Type(Type::Path(typ)) => {
+                    let inner_qn = QualifiedName::from_type_path(typ);
+                    if !forward_declarations_ok && self.forward_declarations.contains(&inner_qn) {
+                        return Err(ConvertError::TypeContainingForwardDeclaration(inner_qn));
+                    }
+                    match generic_behavior {
+                        CxxGenericType::Rust => {
+                            if !inner_qn.get_namespace().is_empty() {
+                                return Err(ConvertError::RustTypeWithAPath(inner_qn));
+                            }
+                            if !self.config.is_rust_type(&inner_qn.get_final_ident()) {
+                                return Err(ConvertError::BoxContainingNonRustType(inner_qn));
+                            }
+                            if self
+                                .config
+                                .is_subclass_holder(&inner_qn.get_final_ident().to_string())
+                            {
+                                return Ok(TypeKind::SubclassHolder(inner_qn.get_final_ident()));
+                            } else {
+                                return Ok(TypeKind::Regular);
+                            }
+                        }
+                        CxxGenericType::CppPtr => {
+                            if !known_types().permissible_within_unique_ptr(&inner_qn) {
+                                return Err(ConvertError::InvalidTypeForCppPtr(inner_qn));
+                            }
+                        }
+                        CxxGenericType::CppVector => {
+                            if !known_types().permissible_within_vector(&inner_qn) {
+                                return Err(ConvertError::InvalidTypeForCppVector(inner_qn));
+                            }
+                            if matches!(
+                                typ.path.segments.last().map(|ps| &ps.arguments),
+                                Some(
+                                    PathArguments::Parenthesized(_)
+                                        | PathArguments::AngleBracketed(_)
+                                )
+                            ) {
+                                return Err(ConvertError::GenericsWithinVector);
+                            }
+                        }
+                        _ => {}
+                    }
+                }
+                _ => {
+                    return Err(ConvertError::TemplatedTypeContainingNonPathArg(
+                        desc.clone(),
+                    ))
+                }
+            }
+        }
+        Ok(TypeKind::Regular)
+    }
+
+    fn find_typedefs<A: AnalysisPhase>(apis: &ApiVec<A>) -> HashMap<QualifiedName, Type>
+    where
+        A::TypedefAnalysis: TypedefTarget,
+    {
+        apis.iter()
+            .filter_map(|api| match &api {
+                Api::Typedef { analysis, .. } => analysis
+                    .get_target()
+                    .cloned()
+                    .map(|ty| (api.name().clone(), ty)),
+                _ => None,
+            })
+            .collect()
+    }
+
+    fn find_concrete_templates<A: AnalysisPhase>(
+        apis: &ApiVec<A>,
+    ) -> HashMap<String, QualifiedName> {
+        apis.iter()
+            .filter_map(|api| match &api {
+                Api::ConcreteType { cpp_definition, .. } => {
+                    Some((cpp_definition.clone(), api.name().clone()))
+                }
+                _ => None,
+            })
+            .collect()
+    }
+
+    fn find_incomplete_types<A: AnalysisPhase>(apis: &ApiVec<A>) -> HashSet<QualifiedName> {
+        apis.iter()
+            .filter_map(|api| match api {
+                Api::ForwardDeclaration { .. }
+                | Api::OpaqueTypedef {
+                    forward_declaration: true,
+                    ..
+                } => Some(api.name()),
+                _ => None,
+            })
+            .cloned()
+            .collect()
+    }
+
+    fn find_ignored_types<A: AnalysisPhase>(apis: &ApiVec<A>) -> HashSet<QualifiedName> {
+        apis.iter()
+            .filter_map(|api| match api {
+                Api::IgnoredItem { .. } => Some(api.name()),
+                _ => None,
+            })
+            .cloned()
+            .collect()
+    }
+}
+
+/// Processing functions sometimes results in new types being materialized.
+/// These types haven't been through the analysis phases (chicken and egg
+/// problem) but fortunately, don't need to. We need to keep the type
+/// system happy by adding an [ApiAnalysis] but in practice, for the sorts
+/// of things that get created, it's always blank.
+pub(crate) fn add_analysis<A: AnalysisPhase>(api: UnanalyzedApi) -> Api<A> {
+    match api {
+        Api::ConcreteType {
+            name,
+            rs_definition,
+            cpp_definition,
+        } => Api::ConcreteType {
+            name,
+            rs_definition,
+            cpp_definition,
+        },
+        Api::IgnoredItem { name, err, ctx } => Api::IgnoredItem { name, err, ctx },
+        _ => panic!("Function analysis created an unexpected type of extra API"),
+    }
+}
+pub(crate) trait TypedefTarget {
+    fn get_target(&self) -> Option<&Type>;
+}
+
+impl TypedefTarget for () {
+    fn get_target(&self) -> Option<&Type> {
+        None
+    }
+}
+
+impl TypedefTarget for TypedefAnalysis {
+    fn get_target(&self) -> Option<&Type> {
+        Some(match self.kind {
+            TypedefKind::Type(ref ty) => &ty.ty,
+            TypedefKind::Use(_, ref ty) => ty,
+        })
+    }
+}
+
+pub(crate) fn find_types<A: AnalysisPhase>(apis: &ApiVec<A>) -> HashSet<QualifiedName> {
+    apis.iter()
+        .filter_map(|api| match api {
+            Api::ForwardDeclaration { .. }
+            | Api::OpaqueTypedef { .. }
+            | Api::ConcreteType { .. }
+            | Api::Typedef { .. }
+            | Api::Enum { .. }
+            | Api::Struct { .. }
+            | Api::Subclass { .. }
+            | Api::ExternCppType { .. }
+            | Api::RustType { .. } => Some(api.name()),
+            Api::StringConstructor { .. }
+            | Api::Function { .. }
+            | Api::Const { .. }
+            | Api::CType { .. }
+            | Api::RustSubclassFn { .. }
+            | Api::IgnoredItem { .. }
+            | Api::SubclassTraitItem { .. }
+            | Api::RustFn { .. } => None,
+        })
+        .cloned()
+        .collect()
+}
diff --git a/engine/src/conversion/api.rs b/engine/src/conversion/api.rs
new file mode 100644
index 0000000..3d04674
--- /dev/null
+++ b/engine/src/conversion/api.rs
@@ -0,0 +1,715 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::set::IndexSet as HashSet;
+use std::fmt::Display;
+
+use crate::types::{make_ident, Namespace, QualifiedName};
+use autocxx_parser::{ExternCppType, RustFun, RustPath};
+use itertools::Itertools;
+use quote::ToTokens;
+use syn::{
+    parse::Parse,
+    punctuated::Punctuated,
+    token::{Comma, Unsafe},
+    Attribute, FnArg, Ident, ItemConst, ItemEnum, ItemStruct, ItemType, ItemUse, LitBool, LitInt,
+    Pat, ReturnType, Type, Visibility,
+};
+
+use super::{
+    analysis::{
+        fun::{
+            function_wrapper::{CppFunction, CppFunctionBody, CppFunctionKind},
+            ReceiverMutability,
+        },
+        PointerTreatment,
+    },
+    convert_error::{ConvertErrorWithContext, ErrorContext},
+    ConvertError,
+};
+
+#[derive(Copy, Clone, Eq, PartialEq)]
+pub(crate) enum TypeKind {
+    Pod,    // trivial. Can be moved and copied in Rust.
+    NonPod, // has destructor or non-trivial move constructors. Can only hold by UniquePtr
+    Abstract, // has pure virtual members - can't even generate UniquePtr.
+            // It's possible that the type itself isn't pure virtual, but it inherits from
+            // some other type which is pure virtual. Alternatively, maybe we just don't
+            // know if the base class is pure virtual because it wasn't on the allowlist,
+            // in which case we'll err on the side of caution.
+}
+
+/// C++ visibility.
+#[derive(Debug, Clone, PartialEq, Eq, Copy)]
+pub(crate) enum CppVisibility {
+    Public,
+    Protected,
+    Private,
+}
+
+/// Details about a C++ struct.
+pub(crate) struct StructDetails {
+    pub(crate) vis: CppVisibility,
+    pub(crate) item: ItemStruct,
+    pub(crate) layout: Option<Layout>,
+    pub(crate) has_rvalue_reference_fields: bool,
+}
+
+/// Layout of a type, equivalent to the same type in ir/layout.rs in bindgen
+#[derive(Clone)]
+pub(crate) struct Layout {
+    /// The size (in bytes) of this layout.
+    pub(crate) size: usize,
+    /// The alignment (in bytes) of this layout.
+    pub(crate) align: usize,
+    /// Whether this layout's members are packed or not.
+    pub(crate) packed: bool,
+}
+
+impl Parse for Layout {
+    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
+        let size: LitInt = input.parse()?;
+        input.parse::<syn::token::Comma>()?;
+        let align: LitInt = input.parse()?;
+        input.parse::<syn::token::Comma>()?;
+        let packed: LitBool = input.parse()?;
+        Ok(Layout {
+            size: size.base10_parse().unwrap(),
+            align: align.base10_parse().unwrap(),
+            packed: packed.value(),
+        })
+    }
+}
+
+#[derive(Clone)]
+pub(crate) enum Virtualness {
+    None,
+    Virtual,
+    PureVirtual,
+}
+
+#[derive(Clone, Copy)]
+pub(crate) enum CastMutability {
+    ConstToConst,
+    MutToConst,
+    MutToMut,
+}
+
+/// Indicates that this function (which is synthetic) should
+/// be a trait implementation rather than a method or free function.
+#[derive(Clone)]
+pub(crate) enum TraitSynthesis {
+    Cast {
+        to_type: QualifiedName,
+        mutable: CastMutability,
+    },
+    AllocUninitialized(QualifiedName),
+    FreeUninitialized(QualifiedName),
+}
+
+/// Details of a subclass constructor.
+/// TODO: zap this; replace with an extra API.
+#[derive(Clone)]
+pub(crate) struct SubclassConstructorDetails {
+    pub(crate) subclass: SubclassName,
+    pub(crate) is_trivial: bool,
+    /// Implementation of the constructor _itself_ as distinct
+    /// from any wrapper function we create to call it.
+    pub(crate) cpp_impl: CppFunction,
+}
+
+/// Contributions to traits representing C++ superclasses that
+/// we may implement as Rust subclasses.
+#[derive(Clone)]
+pub(crate) struct SuperclassMethod {
+    pub(crate) name: Ident,
+    pub(crate) receiver: QualifiedName,
+    pub(crate) params: Punctuated<FnArg, Comma>,
+    pub(crate) param_names: Vec<Pat>,
+    pub(crate) ret_type: ReturnType,
+    pub(crate) receiver_mutability: ReceiverMutability,
+    pub(crate) requires_unsafe: UnsafetyNeeded,
+    pub(crate) is_pure_virtual: bool,
+}
+
+/// Information about references (as opposed to pointers) to be found
+/// within the function signature. This is derived from bindgen annotations
+/// which is why it's not within `FuncToConvert::inputs`
+#[derive(Default, Clone)]
+pub(crate) struct References {
+    pub(crate) rvalue_ref_params: HashSet<Ident>,
+    pub(crate) ref_params: HashSet<Ident>,
+    pub(crate) ref_return: bool,
+    pub(crate) rvalue_ref_return: bool,
+}
+
+impl References {
+    pub(crate) fn new_with_this_and_return_as_reference() -> Self {
+        Self {
+            ref_return: true,
+            ref_params: [make_ident("this")].into_iter().collect(),
+            ..Default::default()
+        }
+    }
+    pub(crate) fn param_treatment(&self, param: &Ident) -> PointerTreatment {
+        if self.rvalue_ref_params.contains(param) {
+            PointerTreatment::RValueReference
+        } else if self.ref_params.contains(param) {
+            PointerTreatment::Reference
+        } else {
+            PointerTreatment::Pointer
+        }
+    }
+    pub(crate) fn return_treatment(&self) -> PointerTreatment {
+        if self.rvalue_ref_return {
+            PointerTreatment::RValueReference
+        } else if self.ref_return {
+            PointerTreatment::Reference
+        } else {
+            PointerTreatment::Pointer
+        }
+    }
+}
+
+#[derive(Clone)]
+pub(crate) struct TraitImplSignature {
+    pub(crate) ty: Type,
+    pub(crate) trait_signature: Type,
+    /// The trait is 'unsafe' itself
+    pub(crate) unsafety: Option<Unsafe>,
+}
+
+impl Eq for TraitImplSignature {}
+
+impl PartialEq for TraitImplSignature {
+    fn eq(&self, other: &Self) -> bool {
+        totokens_equal(&self.unsafety, &other.unsafety)
+            && totokens_equal(&self.ty, &other.ty)
+            && totokens_equal(&self.trait_signature, &other.trait_signature)
+    }
+}
+
+fn totokens_to_string<T: ToTokens>(a: &T) -> String {
+    a.to_token_stream().to_string()
+}
+
+fn totokens_equal<T: ToTokens>(a: &T, b: &T) -> bool {
+    totokens_to_string(a) == totokens_to_string(b)
+}
+
+fn hash_totokens<T: ToTokens, H: std::hash::Hasher>(a: &T, state: &mut H) {
+    use std::hash::Hash;
+    totokens_to_string(a).hash(state)
+}
+
+impl std::hash::Hash for TraitImplSignature {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        hash_totokens(&self.ty, state);
+        hash_totokens(&self.trait_signature, state);
+        hash_totokens(&self.unsafety, state);
+    }
+}
+
+#[derive(Clone, Debug)]
+pub(crate) enum SpecialMemberKind {
+    DefaultConstructor,
+    CopyConstructor,
+    MoveConstructor,
+    Destructor,
+    AssignmentOperator,
+}
+
+impl Display for SpecialMemberKind {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(
+            f,
+            "{}",
+            match self {
+                SpecialMemberKind::DefaultConstructor => "default constructor",
+                SpecialMemberKind::CopyConstructor => "copy constructor",
+                SpecialMemberKind::MoveConstructor => "move constructor",
+                SpecialMemberKind::Destructor => "destructor",
+                SpecialMemberKind::AssignmentOperator => "assignment operator",
+            }
+        )
+    }
+}
+
+#[derive(Clone)]
+pub(crate) enum Provenance {
+    Bindgen,
+    SynthesizedOther,
+    SynthesizedSubclassConstructor(Box<SubclassConstructorDetails>),
+}
+
+/// A C++ function for which we need to generate bindings, but haven't
+/// yet analyzed in depth. This is little more than a `ForeignItemFn`
+/// broken down into its constituent parts, plus some metadata from the
+/// surrounding bindgen parsing context.
+///
+/// Some parts of the code synthesize additional functions and then
+/// pass them through the same pipeline _as if_ they were discovered
+/// during normal bindgen parsing. If that happens, they'll create one
+/// of these structures, and typically fill in some of the
+/// `synthesized_*` members which are not filled in from bindgen.
+#[derive(Clone)]
+pub(crate) struct FuncToConvert {
+    pub(crate) provenance: Provenance,
+    pub(crate) ident: Ident,
+    pub(crate) doc_attrs: Vec<Attribute>,
+    pub(crate) inputs: Punctuated<FnArg, Comma>,
+    pub(crate) variadic: bool,
+    pub(crate) output: ReturnType,
+    pub(crate) vis: Visibility,
+    pub(crate) virtualness: Virtualness,
+    pub(crate) cpp_vis: CppVisibility,
+    pub(crate) special_member: Option<SpecialMemberKind>,
+    pub(crate) unused_template_param: bool,
+    pub(crate) references: References,
+    pub(crate) original_name: Option<String>,
+    /// Used for static functions only. For all other functons,
+    /// this is figured out from the receiver type in the inputs.
+    pub(crate) self_ty: Option<QualifiedName>,
+    /// If we wish to use a different 'this' type than the original
+    /// method receiver, e.g. because we're making a subclass
+    /// constructor, fill it in here.
+    pub(crate) synthesized_this_type: Option<QualifiedName>,
+    /// If this function should actually belong to a trait.
+    pub(crate) add_to_trait: Option<TraitSynthesis>,
+    /// If Some, this function didn't really exist in the original
+    /// C++ and instead we're synthesizing it.
+    pub(crate) synthetic_cpp: Option<(CppFunctionBody, CppFunctionKind)>,
+    pub(crate) is_deleted: bool,
+}
+
+/// Layers of analysis which may be applied to decorate each API.
+/// See description of the purpose of this trait within `Api`.
+pub(crate) trait AnalysisPhase {
+    type TypedefAnalysis;
+    type StructAnalysis;
+    type FunAnalysis;
+}
+
+/// No analysis has been applied to this API.
+pub(crate) struct NullPhase;
+
+impl AnalysisPhase for NullPhase {
+    type TypedefAnalysis = ();
+    type StructAnalysis = ();
+    type FunAnalysis = ();
+}
+
+#[derive(Clone)]
+pub(crate) enum TypedefKind {
+    Use(ItemUse, Box<Type>),
+    Type(ItemType),
+}
+
+/// Name information for an API. This includes the name by
+/// which we know it in Rust, and its C++ name, which may differ.
+#[derive(Clone, Hash, PartialEq, Eq)]
+pub(crate) struct ApiName {
+    pub(crate) name: QualifiedName,
+    cpp_name: Option<String>,
+}
+
+impl ApiName {
+    pub(crate) fn new(ns: &Namespace, id: Ident) -> Self {
+        Self::new_from_qualified_name(QualifiedName::new(ns, id))
+    }
+
+    pub(crate) fn new_with_cpp_name(ns: &Namespace, id: Ident, cpp_name: Option<String>) -> Self {
+        Self {
+            name: QualifiedName::new(ns, id),
+            cpp_name,
+        }
+    }
+
+    pub(crate) fn new_from_qualified_name(name: QualifiedName) -> Self {
+        Self {
+            name,
+            cpp_name: None,
+        }
+    }
+
+    pub(crate) fn new_in_root_namespace(id: Ident) -> Self {
+        Self::new(&Namespace::new(), id)
+    }
+
+    pub(crate) fn cpp_name(&self) -> String {
+        self.cpp_name
+            .as_ref()
+            .cloned()
+            .unwrap_or_else(|| self.name.get_final_item().to_string())
+    }
+
+    pub(crate) fn qualified_cpp_name(&self) -> String {
+        let cpp_name = self.cpp_name();
+        self.name
+            .ns_segment_iter()
+            .cloned()
+            .chain(std::iter::once(cpp_name))
+            .join("::")
+    }
+
+    pub(crate) fn cpp_name_if_present(&self) -> Option<&String> {
+        self.cpp_name.as_ref()
+    }
+}
+
+impl std::fmt::Debug for ApiName {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.name)?;
+        if let Some(cpp_name) = &self.cpp_name {
+            write!(f, " (cpp={})", cpp_name)?;
+        }
+        Ok(())
+    }
+}
+
+/// A name representing a subclass.
+/// This is a simple newtype wrapper which exists such that
+/// we can consistently generate the names of the various subsidiary
+/// types which are required both in C++ and Rust codegen.
+#[derive(Clone, Hash, PartialEq, Eq, Debug)]
+pub(crate) struct SubclassName(pub(crate) ApiName);
+
+impl SubclassName {
+    pub(crate) fn new(id: Ident) -> Self {
+        Self(ApiName::new_in_root_namespace(id))
+    }
+    pub(crate) fn from_holder_name(id: &Ident) -> Self {
+        Self::new(make_ident(id.to_string().strip_suffix("Holder").unwrap()))
+    }
+    pub(crate) fn id(&self) -> Ident {
+        self.0.name.get_final_ident()
+    }
+    /// Generate the name for the 'Holder' type
+    pub(crate) fn holder(&self) -> Ident {
+        self.with_suffix("Holder")
+    }
+    /// Generate the name for the 'Cpp' type
+    pub(crate) fn cpp(&self) -> QualifiedName {
+        let id = self.with_suffix("Cpp");
+        QualifiedName::new(self.0.name.get_namespace(), id)
+    }
+    pub(crate) fn cpp_remove_ownership(&self) -> Ident {
+        self.with_suffix("Cpp_remove_ownership")
+    }
+    pub(crate) fn remove_ownership(&self) -> Ident {
+        self.with_suffix("_remove_ownership")
+    }
+    fn with_suffix(&self, suffix: &str) -> Ident {
+        make_ident(format!("{}{}", self.0.name.get_final_item(), suffix))
+    }
+    pub(crate) fn get_trait_api_name(sup: &QualifiedName, method_name: &str) -> QualifiedName {
+        QualifiedName::new(
+            sup.get_namespace(),
+            make_ident(format!(
+                "{}_{}_trait_item",
+                sup.get_final_item(),
+                method_name
+            )),
+        )
+    }
+    // TODO this and the following should probably include both class name and method name
+    pub(crate) fn get_super_fn_name(superclass_namespace: &Namespace, id: &str) -> QualifiedName {
+        let id = make_ident(format!("{}_super", id));
+        QualifiedName::new(superclass_namespace, id)
+    }
+    pub(crate) fn get_methods_trait_name(superclass_name: &QualifiedName) -> QualifiedName {
+        Self::with_qualified_name_suffix(superclass_name, "methods")
+    }
+    pub(crate) fn get_supers_trait_name(superclass_name: &QualifiedName) -> QualifiedName {
+        Self::with_qualified_name_suffix(superclass_name, "supers")
+    }
+
+    fn with_qualified_name_suffix(name: &QualifiedName, suffix: &str) -> QualifiedName {
+        let id = make_ident(format!("{}_{}", name.get_final_item(), suffix));
+        QualifiedName::new(name.get_namespace(), id)
+    }
+}
+
+#[derive(strum_macros::Display)]
+/// Different types of API we might encounter.
+///
+/// This type is parameterized over an `ApiAnalysis`. This is any additional
+/// information which we wish to apply to our knowledge of our APIs later
+/// during analysis phases.
+///
+/// This is not as high-level as the equivalent types in `cxx` or `bindgen`,
+/// because sometimes we pass on the `bindgen` output directly in the
+/// Rust codegen output.
+///
+/// This derives from [strum_macros::Display] because we want to be
+/// able to debug-print the enum discriminant without worrying about
+/// the fact that their payloads may not be `Debug` or `Display`.
+/// (Specifically, allowing `syn` Types to be `Debug` requires
+/// enabling syn's `extra-traits` feature which increases compile time.)
+pub(crate) enum Api<T: AnalysisPhase> {
+    /// A forward declaration, which we mustn't store in a UniquePtr.
+    ForwardDeclaration {
+        name: ApiName,
+        /// If we found a problem parsing this forward declaration, we'll
+        /// ephemerally store the error here, as opposed to immediately
+        /// converting it to an `IgnoredItem`. That's because the
+        /// 'replace_hopeless_typedef_targets' analysis phase needs to spot
+        /// cases where there was an error which was _also_ a forward declaration.
+        /// That phase will then discard such Api::ForwardDeclarations
+        /// and replace them with normal Api::IgnoredItems.
+        err: Option<ConvertErrorWithContext>,
+    },
+    /// We found a typedef to something that we didn't fully understand.
+    /// We'll treat it as an opaque unsized type.
+    OpaqueTypedef {
+        name: ApiName,
+        /// Further store whether this was a typedef to a forward declaration.
+        /// If so we can't allow it to live in a UniquePtr, just like a regular
+        /// Api::ForwardDeclaration.
+        forward_declaration: bool,
+    },
+    /// A synthetic type we've manufactured in order to
+    /// concretize some templated C++ type.
+    ConcreteType {
+        name: ApiName,
+        rs_definition: Option<Box<Type>>,
+        cpp_definition: String,
+    },
+    /// A simple note that we want to make a constructor for
+    /// a `std::string` on the heap.
+    StringConstructor { name: ApiName },
+    /// A function. May include some analysis.
+    Function {
+        name: ApiName,
+        fun: Box<FuncToConvert>,
+        analysis: T::FunAnalysis,
+    },
+    /// A constant.
+    Const {
+        name: ApiName,
+        const_item: ItemConst,
+    },
+    /// A typedef found in the bindgen output which we wish
+    /// to pass on in our output
+    Typedef {
+        name: ApiName,
+        item: TypedefKind,
+        old_tyname: Option<QualifiedName>,
+        analysis: T::TypedefAnalysis,
+    },
+    /// An enum encountered in the
+    /// `bindgen` output.
+    Enum { name: ApiName, item: ItemEnum },
+    /// A struct encountered in the
+    /// `bindgen` output.
+    Struct {
+        name: ApiName,
+        details: Box<StructDetails>,
+        analysis: T::StructAnalysis,
+    },
+    /// A variable-length C integer type (e.g. int, unsigned long).
+    CType {
+        name: ApiName,
+        typename: QualifiedName,
+    },
+    /// Some item which couldn't be processed by autocxx for some reason.
+    /// We will have emitted a warning message about this, but we want
+    /// to mark that it's ignored so that we don't attempt to process
+    /// dependent items.
+    IgnoredItem {
+        name: ApiName,
+        err: ConvertError,
+        ctx: Option<ErrorContext>,
+    },
+    /// A Rust type which is not a C++ type.
+    RustType { name: ApiName, path: RustPath },
+    /// A function for the 'extern Rust' block which is not a C++ type.
+    RustFn {
+        name: ApiName,
+        details: RustFun,
+        receiver: Option<QualifiedName>,
+    },
+    /// Some function for the extern "Rust" block.
+    RustSubclassFn {
+        name: ApiName,
+        subclass: SubclassName,
+        details: Box<RustSubclassFnDetails>,
+    },
+    /// A Rust subclass of a C++ class.
+    Subclass {
+        name: SubclassName,
+        superclass: QualifiedName,
+    },
+    /// Contributions to the traits representing superclass methods that we might
+    /// subclass in Rust.
+    SubclassTraitItem {
+        name: ApiName,
+        details: SuperclassMethod,
+    },
+    /// A type which we shouldn't ourselves generate, but can use in functions
+    /// and so-forth by referring to some definition elsewhere.
+    ExternCppType {
+        name: ApiName,
+        details: ExternCppType,
+        pod: bool,
+    },
+}
+
+pub(crate) struct RustSubclassFnDetails {
+    pub(crate) params: Punctuated<FnArg, Comma>,
+    pub(crate) ret: ReturnType,
+    pub(crate) cpp_impl: CppFunction,
+    pub(crate) method_name: Ident,
+    pub(crate) superclass: QualifiedName,
+    pub(crate) receiver_mutability: ReceiverMutability,
+    pub(crate) dependencies: Vec<QualifiedName>,
+    pub(crate) requires_unsafe: UnsafetyNeeded,
+    pub(crate) is_pure_virtual: bool,
+}
+
+#[derive(Clone, Debug)]
+pub(crate) enum UnsafetyNeeded {
+    None,
+    JustBridge,
+    Always,
+}
+
+impl<T: AnalysisPhase> Api<T> {
+    pub(crate) fn name_info(&self) -> &ApiName {
+        match self {
+            Api::ForwardDeclaration { name, .. } => name,
+            Api::OpaqueTypedef { name, .. } => name,
+            Api::ConcreteType { name, .. } => name,
+            Api::StringConstructor { name } => name,
+            Api::Function { name, .. } => name,
+            Api::Const { name, .. } => name,
+            Api::Typedef { name, .. } => name,
+            Api::Enum { name, .. } => name,
+            Api::Struct { name, .. } => name,
+            Api::CType { name, .. } => name,
+            Api::IgnoredItem { name, .. } => name,
+            Api::RustType { name, .. } => name,
+            Api::RustFn { name, .. } => name,
+            Api::RustSubclassFn { name, .. } => name,
+            Api::Subclass { name, .. } => &name.0,
+            Api::SubclassTraitItem { name, .. } => name,
+            Api::ExternCppType { name, .. } => name,
+        }
+    }
+
+    /// The name of this API as used in Rust code.
+    /// For types, it's important that this never changes, since
+    /// functions or other types may refer to this.
+    /// Yet for functions, this may not actually be the name
+    /// used in the [cxx::bridge] mod -  see
+    /// [Api<FnAnalysis>::cxxbridge_name]
+    pub(crate) fn name(&self) -> &QualifiedName {
+        &self.name_info().name
+    }
+
+    /// The name recorded for use in C++, if and only if
+    /// it differs from Rust.
+    pub(crate) fn cpp_name(&self) -> &Option<String> {
+        &self.name_info().cpp_name
+    }
+
+    /// The name for use in C++, whether or not it differs
+    /// from Rust.
+    pub(crate) fn effective_cpp_name(&self) -> &str {
+        self.cpp_name()
+            .as_deref()
+            .unwrap_or_else(|| self.name().get_final_item())
+    }
+
+    /// If this API turns out to have the same QualifiedName as another,
+    /// whether it's OK to just discard it?
+    pub(crate) fn discard_duplicates(&self) -> bool {
+        matches!(self, Api::IgnoredItem { .. })
+    }
+
+    pub(crate) fn valid_types(&self) -> Box<dyn Iterator<Item = QualifiedName>> {
+        match self {
+            Api::Subclass { name, .. } => Box::new(
+                vec![
+                    self.name().clone(),
+                    QualifiedName::new(&Namespace::new(), name.holder()),
+                    name.cpp(),
+                ]
+                .into_iter(),
+            ),
+            _ => Box::new(std::iter::once(self.name().clone())),
+        }
+    }
+}
+
+impl<T: AnalysisPhase> std::fmt::Debug for Api<T> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{:?} (kind={})", self.name_info(), self)
+    }
+}
+
+pub(crate) type UnanalyzedApi = Api<NullPhase>;
+
+impl<T: AnalysisPhase> Api<T> {
+    pub(crate) fn typedef_unchanged(
+        name: ApiName,
+        item: TypedefKind,
+        old_tyname: Option<QualifiedName>,
+        analysis: T::TypedefAnalysis,
+    ) -> Result<Box<dyn Iterator<Item = Api<T>>>, ConvertErrorWithContext>
+    where
+        T: 'static,
+    {
+        Ok(Box::new(std::iter::once(Api::Typedef {
+            name,
+            item,
+            old_tyname,
+            analysis,
+        })))
+    }
+
+    pub(crate) fn struct_unchanged(
+        name: ApiName,
+        details: Box<StructDetails>,
+        analysis: T::StructAnalysis,
+    ) -> Result<Box<dyn Iterator<Item = Api<T>>>, ConvertErrorWithContext>
+    where
+        T: 'static,
+    {
+        Ok(Box::new(std::iter::once(Api::Struct {
+            name,
+            details,
+            analysis,
+        })))
+    }
+
+    pub(crate) fn fun_unchanged(
+        name: ApiName,
+        fun: Box<FuncToConvert>,
+        analysis: T::FunAnalysis,
+    ) -> Result<Box<dyn Iterator<Item = Api<T>>>, ConvertErrorWithContext>
+    where
+        T: 'static,
+    {
+        Ok(Box::new(std::iter::once(Api::Function {
+            name,
+            fun,
+            analysis,
+        })))
+    }
+
+    pub(crate) fn enum_unchanged(
+        name: ApiName,
+        item: ItemEnum,
+    ) -> Result<Box<dyn Iterator<Item = Api<T>>>, ConvertErrorWithContext>
+    where
+        T: 'static,
+    {
+        Ok(Box::new(std::iter::once(Api::Enum { name, item })))
+    }
+}
diff --git a/engine/src/conversion/apivec.rs b/engine/src/conversion/apivec.rs
new file mode 100644
index 0000000..1e440cc
--- /dev/null
+++ b/engine/src/conversion/apivec.rs
@@ -0,0 +1,137 @@
+// Copyright 2022 Google LLC
+//
+// 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
+//
+//    https://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.
+
+use indexmap::set::IndexSet as HashSet;
+
+use crate::{
+    conversion::{api::ApiName, convert_error::ErrorContext, ConvertError},
+    types::QualifiedName,
+};
+
+use super::api::{AnalysisPhase, Api};
+
+/// Newtype wrapper for a list of APIs, which enforces the invariant
+/// that each API has a unique name.
+///
+/// Specifically, each API should have a unique [`QualifiedName`] which is kept
+/// within an [`ApiName`]. The [`QualifiedName`] is used to refer to this API
+/// from others, e.g. to represent edges in the graph used for garbage collection,
+/// so that's why this uniqueness is so important.
+///
+/// At present, this type also refuses to allow mutation of an API once it
+/// has been added to a set. This is because the autocxx engine is
+/// fundamentally organized into lots of analysis phases, each one _adding_
+/// fields rather than mutating earlier fields. The idea here is that it's
+/// impossible for stupid future maintainers (i.e. me) to make errors by
+/// referring to fields before they're filled in. If a field exists, it's
+/// correct.
+///
+/// While this is currently the case, it's possible that in future we could
+/// see legitimate reasons to break this latter invariant and allow mutation
+/// of APIs within an existing `ApiVec`. But it's extremely important that
+/// the naming-uniqueness-invariant remains, so any such mutation should
+/// allow mutation only of other fields, not the name.
+pub(crate) struct ApiVec<P: AnalysisPhase> {
+    apis: Vec<Api<P>>,
+    names: HashSet<QualifiedName>,
+}
+
+impl<P: AnalysisPhase> ApiVec<P> {
+    pub(crate) fn push(&mut self, api: Api<P>) {
+        let name = api.name();
+        let already_contains = self.already_contains(name);
+        if already_contains {
+            if api.discard_duplicates() {
+                // This is already an IgnoredItem or something else where
+                // we can silently drop it.
+                log::info!("Discarding duplicate API for {}", name);
+            } else {
+                log::info!(
+                    "Duplicate API for {} - removing all of them and replacing with an IgnoredItem.",
+                    name
+                );
+                self.retain(|api| api.name() != name);
+                self.push(Api::IgnoredItem {
+                    name: ApiName::new_from_qualified_name(name.clone()),
+                    err: ConvertError::DuplicateItemsFoundInParsing,
+                    ctx: Some(ErrorContext::new_for_item(name.get_final_ident())),
+                })
+            }
+        } else {
+            self.names.insert(name.clone());
+            self.apis.push(api)
+        }
+    }
+
+    fn already_contains(&self, name: &QualifiedName) -> bool {
+        self.names.contains(name)
+    }
+
+    pub(crate) fn new() -> Self {
+        Self::default()
+    }
+
+    pub(crate) fn append(&mut self, more: &mut ApiVec<P>) {
+        self.extend(more.apis.drain(..))
+    }
+
+    pub(crate) fn extend(&mut self, it: impl Iterator<Item = Api<P>>) {
+        // Could be optimized in future
+        for api in it {
+            self.push(api)
+        }
+    }
+
+    pub(crate) fn iter(&self) -> impl Iterator<Item = &Api<P>> {
+        self.apis.iter()
+    }
+
+    pub(crate) fn into_iter(self) -> impl Iterator<Item = Api<P>> {
+        self.apis.into_iter()
+    }
+
+    pub(crate) fn is_empty(&self) -> bool {
+        self.apis.is_empty()
+    }
+
+    pub fn retain<F>(&mut self, f: F)
+    where
+        F: FnMut(&Api<P>) -> bool,
+    {
+        self.apis.retain(f);
+        self.names.clear();
+        self.names
+            .extend(self.apis.iter().map(|api| api.name()).cloned());
+    }
+}
+
+impl<P: AnalysisPhase> Default for ApiVec<P> {
+    fn default() -> Self {
+        Self {
+            apis: Default::default(),
+            names: Default::default(),
+        }
+    }
+}
+
+impl<P: AnalysisPhase> FromIterator<Api<P>> for ApiVec<P> {
+    fn from_iter<I: IntoIterator<Item = Api<P>>>(iter: I) -> Self {
+        let mut this = ApiVec::new();
+        for i in iter {
+            // Could be optimized in future
+            this.push(i);
+        }
+        this
+    }
+}
diff --git a/engine/src/conversion/codegen_cpp/function_wrapper_cpp.rs b/engine/src/conversion/codegen_cpp/function_wrapper_cpp.rs
new file mode 100644
index 0000000..b2e1ea3
--- /dev/null
+++ b/engine/src/conversion/codegen_cpp/function_wrapper_cpp.rs
@@ -0,0 +1,83 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::conversion::{
+    analysis::fun::function_wrapper::{CppConversionType, TypeConversionPolicy},
+    ConvertError,
+};
+
+use super::type_to_cpp::{type_to_cpp, CppNameMap};
+
+impl TypeConversionPolicy {
+    pub(super) fn unconverted_type(
+        &self,
+        cpp_name_map: &CppNameMap,
+    ) -> Result<String, ConvertError> {
+        match self.cpp_conversion {
+            CppConversionType::FromUniquePtrToValue => self.unique_ptr_wrapped_type(cpp_name_map),
+            CppConversionType::FromPtrToValue => {
+                Ok(format!("{}*", self.unwrapped_type_as_string(cpp_name_map)?))
+            }
+            _ => self.unwrapped_type_as_string(cpp_name_map),
+        }
+    }
+
+    pub(super) fn converted_type(&self, cpp_name_map: &CppNameMap) -> Result<String, ConvertError> {
+        match self.cpp_conversion {
+            CppConversionType::FromValueToUniquePtr => self.unique_ptr_wrapped_type(cpp_name_map),
+            _ => self.unwrapped_type_as_string(cpp_name_map),
+        }
+    }
+
+    fn unwrapped_type_as_string(&self, cpp_name_map: &CppNameMap) -> Result<String, ConvertError> {
+        type_to_cpp(&self.unwrapped_type, cpp_name_map)
+    }
+
+    fn unique_ptr_wrapped_type(
+        &self,
+        original_name_map: &CppNameMap,
+    ) -> Result<String, ConvertError> {
+        Ok(format!(
+            "std::unique_ptr<{}>",
+            self.unwrapped_type_as_string(original_name_map)?
+        ))
+    }
+
+    pub(super) fn cpp_conversion(
+        &self,
+        var_name: &str,
+        cpp_name_map: &CppNameMap,
+        is_return: bool,
+    ) -> Result<Option<String>, ConvertError> {
+        // If is_return we want to avoid unnecessary std::moves because they
+        // make RVO less effective
+        Ok(match self.cpp_conversion {
+            CppConversionType::None | CppConversionType::FromReturnValueToPlacementPtr => {
+                Some(var_name.to_string())
+            }
+            CppConversionType::Move => Some(format!("std::move({})", var_name)),
+            CppConversionType::FromUniquePtrToValue | CppConversionType::FromPtrToMove => {
+                Some(format!("std::move(*{})", var_name))
+            }
+            CppConversionType::FromValueToUniquePtr => Some(format!(
+                "std::make_unique<{}>({})",
+                self.unconverted_type(cpp_name_map)?,
+                var_name
+            )),
+            CppConversionType::FromPtrToValue => {
+                let dereference = format!("*{}", var_name);
+                Some(if is_return {
+                    dereference
+                } else {
+                    format!("std::move({})", dereference)
+                })
+            }
+            CppConversionType::IgnoredPlacementPtrParameter => None,
+        })
+    }
+}
diff --git a/engine/src/conversion/codegen_cpp/mod.rs b/engine/src/conversion/codegen_cpp/mod.rs
new file mode 100644
index 0000000..02e92b2
--- /dev/null
+++ b/engine/src/conversion/codegen_cpp/mod.rs
@@ -0,0 +1,724 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod function_wrapper_cpp;
+mod new_and_delete_prelude;
+pub(crate) mod type_to_cpp;
+
+use crate::{
+    conversion::analysis::fun::{function_wrapper::CppFunctionKind, FnAnalysis},
+    types::{make_ident, QualifiedName},
+    CppCodegenOptions, CppFilePair,
+};
+use autocxx_parser::IncludeCppConfig;
+use indexmap::map::IndexMap as HashMap;
+use indexmap::set::IndexSet as HashSet;
+use itertools::Itertools;
+use std::borrow::Cow;
+use type_to_cpp::{original_name_map_from_apis, type_to_cpp, CppNameMap};
+
+use self::type_to_cpp::{
+    final_ident_using_original_name_map, namespaced_name_using_original_name_map,
+};
+
+use super::{
+    analysis::{
+        fun::{
+            function_wrapper::{CppFunction, CppFunctionBody},
+            FnPhase, PodAndDepAnalysis,
+        },
+        pod::PodAnalysis,
+    },
+    api::{Api, Provenance, SubclassName, TypeKind},
+    apivec::ApiVec,
+    ConvertError,
+};
+
+#[derive(Ord, PartialOrd, Eq, PartialEq, Clone, Hash)]
+enum Header {
+    System(&'static str),
+    CxxH,
+    CxxgenH,
+    NewDeletePrelude,
+}
+
+impl Header {
+    fn include_stmt(
+        &self,
+        cpp_codegen_options: &CppCodegenOptions,
+        cxxgen_header_name: &str,
+    ) -> String {
+        let blank = "".to_string();
+        match self {
+            Self::System(name) => format!("#include <{}>", name),
+            Self::CxxH => {
+                let prefix = cpp_codegen_options.path_to_cxx_h.as_ref().unwrap_or(&blank);
+                format!("#include \"{}cxx.h\"", prefix)
+            }
+            Self::CxxgenH => {
+                let prefix = cpp_codegen_options
+                    .path_to_cxxgen_h
+                    .as_ref()
+                    .unwrap_or(&blank);
+                format!("#include \"{}{}\"", prefix, cxxgen_header_name)
+            }
+            Header::NewDeletePrelude => new_and_delete_prelude::NEW_AND_DELETE_PRELUDE.to_string(),
+        }
+    }
+
+    fn is_system(&self) -> bool {
+        matches!(self, Header::System(_) | Header::CxxH)
+    }
+}
+
+enum ConversionDirection {
+    RustCallsCpp,
+    CppCallsCpp,
+    CppCallsRust,
+}
+
+/// Some extra snippet of C++ which we (autocxx) need to generate, beyond
+/// that which cxx itself generates.
+#[derive(Default)]
+struct ExtraCpp {
+    type_definition: Option<String>, // are output before main declarations
+    declaration: Option<String>,
+    definition: Option<String>,
+    headers: Vec<Header>,
+    cpp_headers: Vec<Header>,
+}
+
+/// Generates additional C++ glue functions needed by autocxx.
+/// In some ways it would be preferable to be able to pass snippets
+/// of C++ through to `cxx` for inclusion in the C++ file which it
+/// generates, and perhaps we'll explore that in future. But for now,
+/// autocxx generates its own _additional_ C++ files which therefore
+/// need to be built and included in linking procedures.
+pub(crate) struct CppCodeGenerator<'a> {
+    additional_functions: Vec<ExtraCpp>,
+    inclusions: String,
+    original_name_map: CppNameMap,
+    config: &'a IncludeCppConfig,
+    cpp_codegen_options: &'a CppCodegenOptions<'a>,
+    cxxgen_header_name: &'a str,
+}
+
+struct SubclassFunction<'a> {
+    fun: &'a CppFunction,
+    is_pure_virtual: bool,
+}
+
+impl<'a> CppCodeGenerator<'a> {
+    pub(crate) fn generate_cpp_code(
+        inclusions: String,
+        apis: &ApiVec<FnPhase>,
+        config: &'a IncludeCppConfig,
+        cpp_codegen_options: &CppCodegenOptions,
+        cxxgen_header_name: &str,
+    ) -> Result<Option<CppFilePair>, ConvertError> {
+        let mut gen = CppCodeGenerator {
+            additional_functions: Vec::new(),
+            inclusions,
+            original_name_map: original_name_map_from_apis(apis),
+            config,
+            cpp_codegen_options,
+            cxxgen_header_name,
+        };
+        // The 'filter' on the following line is designed to ensure we don't accidentally
+        // end up out of sync with needs_cpp_codegen
+        gen.add_needs(apis.iter().filter(|api| api.needs_cpp_codegen()))?;
+        Ok(gen.generate())
+    }
+
+    // It's important to keep this in sync with Api::needs_cpp_codegen.
+    fn add_needs<'b>(
+        &mut self,
+        apis: impl Iterator<Item = &'a Api<FnPhase>>,
+    ) -> Result<(), ConvertError> {
+        let mut constructors_by_subclass: HashMap<SubclassName, Vec<&CppFunction>> = HashMap::new();
+        let mut methods_by_subclass: HashMap<SubclassName, Vec<SubclassFunction>> = HashMap::new();
+        let mut deferred_apis = Vec::new();
+        for api in apis {
+            match &api {
+                Api::StringConstructor { .. } => self.generate_string_constructor(),
+                Api::Function {
+                    analysis:
+                        FnAnalysis {
+                            cpp_wrapper: Some(cpp_wrapper),
+                            ignore_reason: Ok(_),
+                            externally_callable: true,
+                            ..
+                        },
+                    fun,
+                    ..
+                } => {
+                    if let Provenance::SynthesizedSubclassConstructor(details) = &fun.provenance {
+                        constructors_by_subclass
+                            .entry(details.subclass.clone())
+                            .or_default()
+                            .push(&details.cpp_impl);
+                    }
+                    self.generate_cpp_function(cpp_wrapper)?
+                }
+                Api::ConcreteType {
+                    rs_definition,
+                    cpp_definition,
+                    ..
+                } => {
+                    let effective_cpp_definition = match rs_definition {
+                        Some(rs_definition) => {
+                            Cow::Owned(type_to_cpp(rs_definition, &self.original_name_map)?)
+                        }
+                        None => Cow::Borrowed(cpp_definition),
+                    };
+
+                    self.generate_typedef(api.name(), &effective_cpp_definition)
+                }
+                Api::CType { typename, .. } => self.generate_ctype_typedef(typename),
+                Api::Subclass { .. } => deferred_apis.push(api),
+                Api::RustSubclassFn {
+                    subclass, details, ..
+                } => {
+                    methods_by_subclass
+                        .entry(subclass.clone())
+                        .or_default()
+                        .push(SubclassFunction {
+                            fun: &details.cpp_impl,
+                            is_pure_virtual: details.is_pure_virtual,
+                        });
+                }
+                Api::Struct {
+                    name,
+                    analysis:
+                        PodAndDepAnalysis {
+                            pod:
+                                PodAnalysis {
+                                    kind: TypeKind::Pod,
+                                    ..
+                                },
+                            ..
+                        },
+                    ..
+                } => {
+                    self.generate_pod_assertion(name.qualified_cpp_name());
+                }
+                _ => panic!("Should have filtered on needs_cpp_codegen"),
+            }
+        }
+
+        for api in deferred_apis.into_iter() {
+            match api {
+                Api::Subclass { name, superclass } => self.generate_subclass(
+                    superclass,
+                    name,
+                    constructors_by_subclass.remove(name).unwrap_or_default(),
+                    methods_by_subclass.remove(name).unwrap_or_default(),
+                )?,
+                _ => panic!("Unexpected deferred API"),
+            }
+        }
+        Ok(())
+    }
+
+    fn generate(&self) -> Option<CppFilePair> {
+        if self.additional_functions.is_empty() {
+            None
+        } else {
+            let headers = self.collect_headers(|additional_need| &additional_need.headers);
+            let cpp_headers = self.collect_headers(|additional_need| &additional_need.cpp_headers);
+            let type_definitions = self.concat_additional_items(|x| x.type_definition.as_ref());
+            let declarations = self.concat_additional_items(|x| x.declaration.as_ref());
+            let declarations = format!(
+                "#ifndef __AUTOCXXGEN_H__\n#define __AUTOCXXGEN_H__\n\n{}\n{}\n{}\n{}#endif // __AUTOCXXGEN_H__\n",
+                headers, self.inclusions, type_definitions, declarations
+            );
+            log::info!("Additional C++ decls:\n{}", declarations);
+            let header_name = self
+                .cpp_codegen_options
+                .autocxxgen_header_namer
+                .name_header(self.config.get_mod_name().to_string());
+            let implementation = if self
+                .additional_functions
+                .iter()
+                .any(|x| x.definition.is_some())
+            {
+                let definitions = self.concat_additional_items(|x| x.definition.as_ref());
+                let definitions = format!(
+                    "#include \"{}\"\n{}\n{}",
+                    header_name, cpp_headers, definitions
+                );
+                log::info!("Additional C++ defs:\n{}", definitions);
+                Some(definitions.into_bytes())
+            } else {
+                None
+            };
+            Some(CppFilePair {
+                header: declarations.into_bytes(),
+                implementation,
+                header_name,
+            })
+        }
+    }
+
+    fn collect_headers<F>(&self, filter: F) -> String
+    where
+        F: Fn(&ExtraCpp) -> &[Header],
+    {
+        let cpp_headers: HashSet<_> = self
+            .additional_functions
+            .iter()
+            .flat_map(|x| filter(x).iter())
+            .filter(|x| !self.cpp_codegen_options.suppress_system_headers || !x.is_system())
+            .collect(); // uniqify
+        cpp_headers
+            .iter()
+            .map(|x| x.include_stmt(self.cpp_codegen_options, self.cxxgen_header_name))
+            .join("\n")
+    }
+
+    fn concat_additional_items<F>(&self, field_access: F) -> String
+    where
+        F: FnMut(&ExtraCpp) -> Option<&String>,
+    {
+        let mut s = self
+            .additional_functions
+            .iter()
+            .flat_map(field_access)
+            .join("\n");
+        s.push('\n');
+        s
+    }
+
+    fn generate_pod_assertion(&mut self, name: String) {
+        // These assertions are generated by cxx for trivial ExternTypes but
+        // *only if* such types are used as trivial types in the cxx::bridge.
+        // It's possible for types which we generate to be used even without
+        // passing through the cxx::bridge, and as we generate Drop impls, that
+        // can result in destructors for nested types being called multiple times
+        // if we represent them as trivial types. So generate an extra
+        // assertion to make sure.
+        let declaration = Some(format!("static_assert(::rust::IsRelocatable<{}>::value, \"type {} should be trivially move constructible and trivially destructible to be used with generate_pod! in autocxx\");", name, name));
+        self.additional_functions.push(ExtraCpp {
+            declaration,
+            headers: vec![Header::CxxH],
+            ..Default::default()
+        })
+    }
+
+    fn generate_string_constructor(&mut self) {
+        let makestring_name = self.config.get_makestring_name();
+        let declaration = Some(format!("inline std::unique_ptr<std::string> {}(::rust::Str str) {{ return std::make_unique<std::string>(std::string(str)); }}", makestring_name));
+        self.additional_functions.push(ExtraCpp {
+            declaration,
+            headers: vec![
+                Header::System("memory"),
+                Header::System("string"),
+                Header::CxxH,
+            ],
+            ..Default::default()
+        })
+    }
+
+    fn generate_cpp_function(&mut self, details: &CppFunction) -> Result<(), ConvertError> {
+        self.additional_functions
+            .push(self.generate_cpp_function_inner(
+                details,
+                false,
+                ConversionDirection::RustCallsCpp,
+                false,
+                None,
+            )?);
+        Ok(())
+    }
+
+    fn generate_cpp_function_inner(
+        &self,
+        details: &CppFunction,
+        avoid_this: bool,
+        conversion_direction: ConversionDirection,
+        requires_rust_declarations: bool,
+        force_name: Option<&str>,
+    ) -> Result<ExtraCpp, ConvertError> {
+        // Even if the original function call is in a namespace,
+        // we generate this wrapper in the global namespace.
+        // We could easily do this the other way round, and when
+        // cxx::bridge comes to support nested namespace mods then
+        // we wil wish to do that to avoid name conflicts. However,
+        // at the moment this is simpler because it avoids us having
+        // to generate namespace blocks in the generated C++.
+        let is_a_method = !avoid_this
+            && matches!(
+                details.kind,
+                CppFunctionKind::Method
+                    | CppFunctionKind::ConstMethod
+                    | CppFunctionKind::Constructor
+            );
+        let name = match force_name {
+            Some(n) => n.to_string(),
+            None => details.wrapper_function_name.to_string(),
+        };
+        let get_arg_name = |counter: usize| -> String {
+            if is_a_method && counter == 0 {
+                // For method calls that we generate, the first
+                // argument name needs to be such that we recognize
+                // it as a method in the second invocation of
+                // bridge_converter after it's flowed again through
+                // bindgen.
+                // TODO this may not be the case any longer. We
+                // may be able to remove this.
+                "autocxx_gen_this".to_string()
+            } else {
+                format!("arg{}", counter)
+            }
+        };
+        // If this returns a non-POD value, we may instead wish to emplace
+        // it into a parameter, let's see.
+        let args: Result<Vec<_>, _> = details
+            .argument_conversion
+            .iter()
+            .enumerate()
+            .map(|(counter, ty)| {
+                Ok(format!(
+                    "{} {}",
+                    match conversion_direction {
+                        ConversionDirection::RustCallsCpp =>
+                            ty.unconverted_type(&self.original_name_map)?,
+                        ConversionDirection::CppCallsCpp =>
+                            ty.converted_type(&self.original_name_map)?,
+                        ConversionDirection::CppCallsRust =>
+                            ty.inverse().unconverted_type(&self.original_name_map)?,
+                    },
+                    get_arg_name(counter)
+                ))
+            })
+            .collect();
+        let args = args?.join(", ");
+        let default_return = match details.kind {
+            CppFunctionKind::SynthesizedConstructor => "",
+            _ => "void",
+        };
+        let ret_type = details
+            .return_conversion
+            .as_ref()
+            .and_then(|x| match conversion_direction {
+                ConversionDirection::RustCallsCpp => {
+                    if x.populate_return_value() {
+                        Some(x.converted_type(&self.original_name_map))
+                    } else {
+                        None
+                    }
+                }
+                ConversionDirection::CppCallsCpp => {
+                    Some(x.unconverted_type(&self.original_name_map))
+                }
+                ConversionDirection::CppCallsRust => {
+                    Some(x.inverse().converted_type(&self.original_name_map))
+                }
+            })
+            .unwrap_or_else(|| Ok(default_return.to_string()))?;
+        let constness = match details.kind {
+            CppFunctionKind::ConstMethod => " const",
+            _ => "",
+        };
+        let declaration = format!("{} {}({}){}", ret_type, name, args, constness);
+        let qualification = if let Some(qualification) = &details.qualification {
+            format!("{}::", qualification.to_cpp_name())
+        } else {
+            "".to_string()
+        };
+        let qualified_declaration = format!(
+            "{} {}{}({}){}",
+            ret_type, qualification, name, args, constness
+        );
+        // Whether there's a placement param in which to put the return value
+        let placement_param = details
+            .argument_conversion
+            .iter()
+            .enumerate()
+            .filter_map(|(counter, conv)| {
+                if conv.is_placement_parameter() {
+                    Some(get_arg_name(counter))
+                } else {
+                    None
+                }
+            })
+            .next();
+        // Arguments to underlying function call
+        let arg_list: Result<Vec<_>, _> = details
+            .argument_conversion
+            .iter()
+            .enumerate()
+            .map(|(counter, conv)| match conversion_direction {
+                ConversionDirection::RustCallsCpp => {
+                    conv.cpp_conversion(&get_arg_name(counter), &self.original_name_map, false)
+                }
+                ConversionDirection::CppCallsCpp => Ok(Some(get_arg_name(counter))),
+                ConversionDirection::CppCallsRust => conv.inverse().cpp_conversion(
+                    &get_arg_name(counter),
+                    &self.original_name_map,
+                    false,
+                ),
+            })
+            .collect();
+        let mut arg_list = arg_list?.into_iter().flatten();
+        let receiver = if is_a_method { arg_list.next() } else { None };
+        if matches!(&details.payload, CppFunctionBody::ConstructSuperclass(_)) {
+            arg_list.next();
+        }
+        let arg_list = if details.pass_obs_field {
+            std::iter::once("*obs".to_string())
+                .chain(arg_list)
+                .join(",")
+        } else {
+            arg_list.join(", ")
+        };
+        let (mut underlying_function_call, field_assignments, need_allocators) = match &details
+            .payload
+        {
+            CppFunctionBody::Cast => (arg_list, "".to_string(), false),
+            CppFunctionBody::PlacementNew(ns, id) => {
+                let ty_id = QualifiedName::new(ns, id.clone());
+                let ty_id = self.namespaced_name(&ty_id);
+                (
+                    format!("new ({}) {}({})", receiver.unwrap(), ty_id, arg_list),
+                    "".to_string(),
+                    false,
+                )
+            }
+            CppFunctionBody::Destructor(ns, id) => {
+                let ty_id = QualifiedName::new(ns, id.clone());
+                let ty_id = final_ident_using_original_name_map(&ty_id, &self.original_name_map);
+                (format!("{}->~{}()", arg_list, ty_id), "".to_string(), false)
+            }
+            CppFunctionBody::FunctionCall(ns, id) => match receiver {
+                Some(receiver) => (
+                    format!("{}.{}({})", receiver, id, arg_list),
+                    "".to_string(),
+                    false,
+                ),
+                None => {
+                    let underlying_function_call = ns
+                        .into_iter()
+                        .cloned()
+                        .chain(std::iter::once(id.to_string()))
+                        .join("::");
+                    (
+                        format!("{}({})", underlying_function_call, arg_list),
+                        "".to_string(),
+                        false,
+                    )
+                }
+            },
+            CppFunctionBody::StaticMethodCall(ns, ty_id, fn_id) => {
+                let underlying_function_call = ns
+                    .into_iter()
+                    .cloned()
+                    .chain([ty_id.to_string(), fn_id.to_string()].iter().cloned())
+                    .join("::");
+                (
+                    format!("{}({})", underlying_function_call, arg_list),
+                    "".to_string(),
+                    false,
+                )
+            }
+            CppFunctionBody::ConstructSuperclass(_) => ("".to_string(), arg_list, false),
+            CppFunctionBody::AllocUninitialized(ty) => {
+                let namespaced_ty = self.namespaced_name(ty);
+                (
+                    format!("new_appropriately<{}>();", namespaced_ty,),
+                    "".to_string(),
+                    true,
+                )
+            }
+            CppFunctionBody::FreeUninitialized(ty) => (
+                format!("delete_appropriately<{}>(arg0);", self.namespaced_name(ty)),
+                "".to_string(),
+                true,
+            ),
+        };
+        if let Some(ret) = &details.return_conversion {
+            let call_itself = match conversion_direction {
+                ConversionDirection::RustCallsCpp => {
+                    ret.cpp_conversion(&underlying_function_call, &self.original_name_map, true)?
+                }
+                ConversionDirection::CppCallsCpp => Some(underlying_function_call),
+                ConversionDirection::CppCallsRust => ret.inverse().cpp_conversion(
+                    &underlying_function_call,
+                    &self.original_name_map,
+                    true,
+                )?,
+            }
+            .expect(
+                "Expected some conversion type for return value which resulted in a parameter name",
+            );
+
+            underlying_function_call = match placement_param {
+                Some(placement_param) => {
+                    let tyname = type_to_cpp(&ret.unwrapped_type, &self.original_name_map)?;
+                    format!("new({}) {}({})", placement_param, tyname, call_itself)
+                }
+                None => format!("return {}", call_itself),
+            };
+        };
+        if !underlying_function_call.is_empty() {
+            underlying_function_call = format!("{};", underlying_function_call);
+        }
+        let field_assignments =
+            if let CppFunctionBody::ConstructSuperclass(superclass_name) = &details.payload {
+                let superclass_assignments = if field_assignments.is_empty() {
+                    "".to_string()
+                } else {
+                    format!("{}({}), ", superclass_name, field_assignments)
+                };
+                format!(": {}obs(std::move(arg0))", superclass_assignments)
+            } else {
+                "".into()
+            };
+        let definition_after_sig =
+            format!("{} {{ {} }}", field_assignments, underlying_function_call,);
+        let (declaration, definition) = if requires_rust_declarations {
+            (
+                Some(format!("{};", declaration)),
+                Some(format!(
+                    "{} {}",
+                    qualified_declaration, definition_after_sig
+                )),
+            )
+        } else {
+            (
+                Some(format!("inline {} {}", declaration, definition_after_sig)),
+                None,
+            )
+        };
+        let mut headers = vec![Header::System("memory")];
+        if need_allocators {
+            headers.push(Header::System("stddef.h"));
+            headers.push(Header::NewDeletePrelude);
+        }
+        Ok(ExtraCpp {
+            declaration,
+            definition,
+            headers,
+            ..Default::default()
+        })
+    }
+
+    fn namespaced_name(&self, name: &QualifiedName) -> String {
+        namespaced_name_using_original_name_map(name, &self.original_name_map)
+    }
+
+    fn generate_ctype_typedef(&mut self, tn: &QualifiedName) {
+        let cpp_name = tn.to_cpp_name();
+        self.generate_typedef(tn, &cpp_name)
+    }
+
+    fn generate_typedef(&mut self, tn: &QualifiedName, definition: &str) {
+        let our_name = tn.get_final_item();
+        self.additional_functions.push(ExtraCpp {
+            type_definition: Some(format!("typedef {} {};", definition, our_name)),
+            ..Default::default()
+        })
+    }
+
+    fn generate_subclass(
+        &mut self,
+        superclass: &QualifiedName,
+        subclass: &SubclassName,
+        constructors: Vec<&CppFunction>,
+        methods: Vec<SubclassFunction>,
+    ) -> Result<(), ConvertError> {
+        let holder = subclass.holder();
+        self.additional_functions.push(ExtraCpp {
+            type_definition: Some(format!("struct {};", holder)),
+            ..Default::default()
+        });
+        let mut method_decls = Vec::new();
+        for method in methods {
+            // First the method which calls from C++ to Rust
+            let mut fn_impl = self.generate_cpp_function_inner(
+                method.fun,
+                true,
+                ConversionDirection::CppCallsRust,
+                true,
+                Some(&method.fun.original_cpp_name),
+            )?;
+            method_decls.push(fn_impl.declaration.take().unwrap());
+            self.additional_functions.push(fn_impl);
+            // And now the function to be called from Rust for default implementation (calls superclass in C++)
+            if !method.is_pure_virtual {
+                let mut super_method = method.fun.clone();
+                super_method.pass_obs_field = false;
+                super_method.wrapper_function_name = SubclassName::get_super_fn_name(
+                    superclass.get_namespace(),
+                    &method.fun.wrapper_function_name.to_string(),
+                )
+                .get_final_ident();
+                super_method.payload = CppFunctionBody::StaticMethodCall(
+                    superclass.get_namespace().clone(),
+                    superclass.get_final_ident(),
+                    make_ident(&method.fun.original_cpp_name),
+                );
+                let mut super_fn_impl = self.generate_cpp_function_inner(
+                    &super_method,
+                    true,
+                    ConversionDirection::CppCallsCpp,
+                    false,
+                    None,
+                )?;
+                method_decls.push(super_fn_impl.declaration.take().unwrap());
+                self.additional_functions.push(super_fn_impl);
+            }
+        }
+        // In future, for each superclass..
+        let super_name = superclass.get_final_item();
+        method_decls.push(format!(
+            "const {}& As_{}() const {{ return *this; }}",
+            super_name, super_name,
+        ));
+        method_decls.push(format!(
+            "{}& As_{}_mut() {{ return *this; }}",
+            super_name, super_name
+        ));
+        // And now constructors
+        let mut constructor_decls: Vec<String> = Vec::new();
+        for constructor in constructors {
+            let mut fn_impl = self.generate_cpp_function_inner(
+                constructor,
+                false,
+                ConversionDirection::CppCallsCpp,
+                false,
+                None,
+            )?;
+            let decl = fn_impl.declaration.take().unwrap();
+            constructor_decls.push(decl);
+            self.additional_functions.push(fn_impl);
+        }
+        self.additional_functions.push(ExtraCpp {
+            type_definition: Some(format!(
+                "class {} : {}\n{{\npublic:\n{}\n{}\nvoid {}() const;\nprivate:rust::Box<{}> obs;\nvoid really_remove_ownership();\n\n}};",
+                subclass.cpp(),
+                superclass.to_cpp_name(),
+                constructor_decls.join("\n"),
+                method_decls.join("\n"),
+                subclass.cpp_remove_ownership(),
+                holder
+            )),
+            definition: Some(format!(
+                "void {}::{}() const {{\nconst_cast<{}*>(this)->really_remove_ownership();\n}}\nvoid {}::really_remove_ownership() {{\nauto new_obs = {}(std::move(obs));\nobs = std::move(new_obs);\n}}\n",
+                subclass.cpp(),
+                subclass.cpp_remove_ownership(),
+                subclass.cpp(),
+                subclass.cpp(),
+                subclass.remove_ownership()
+            )),
+            cpp_headers: vec![Header::CxxgenH],
+            ..Default::default()
+        });
+        Ok(())
+    }
+}
diff --git a/engine/src/conversion/codegen_cpp/new_and_delete_prelude.rs b/engine/src/conversion/codegen_cpp/new_and_delete_prelude.rs
new file mode 100644
index 0000000..d860789
--- /dev/null
+++ b/engine/src/conversion/codegen_cpp/new_and_delete_prelude.rs
@@ -0,0 +1,43 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indoc::indoc;
+
+/// This is logic to call either an overloaded operator new/delete
+/// or the standard one.
+/// The SFINAE magic here is: int is a better match than long,
+/// and so the versions which match class-specific operator new/delete
+/// will be used in preference to the general global ::operator new/delete.
+pub(super) static NEW_AND_DELETE_PRELUDE: &str = indoc! {"
+    #ifndef AUTOCXX_NEW_AND_DELETE_PRELUDE
+    #define AUTOCXX_NEW_AND_DELETE_PRELUDE
+    // Mechanics to call custom operator new and delete
+    template <typename T>
+    auto delete_imp(T *ptr, int) -> decltype((void)T::operator delete(ptr)) {
+      T::operator delete(ptr);
+    }
+    template <typename T> void delete_imp(T *ptr, long) { ::operator delete(ptr); }
+    template <typename T> void delete_appropriately(T *obj) {
+      // 0 is a better match for the first 'delete_imp' so will match
+      // preferentially.
+      delete_imp(obj, 0);
+    }
+    template <typename T>
+    auto new_imp(size_t count, int) -> decltype(T::operator new(count)) {
+      return T::operator new(count);
+    }
+    template <typename T> void *new_imp(size_t count, long) {
+      return ::operator new(count);
+    }
+    template <typename T> T *new_appropriately() {
+      // 0 is a better match for the first 'delete_imp' so will match
+      // preferentially.
+      return static_cast<T *>(new_imp<T>(sizeof(T), 0));
+    }
+    #endif // AUTOCXX_NEW_AND_DELETE_PRELUDE
+"};
diff --git a/engine/src/conversion/codegen_cpp/type_to_cpp.rs b/engine/src/conversion/codegen_cpp/type_to_cpp.rs
new file mode 100644
index 0000000..7febb7a
--- /dev/null
+++ b/engine/src/conversion/codegen_cpp/type_to_cpp.rs
@@ -0,0 +1,140 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::{
+    conversion::{apivec::ApiVec, AnalysisPhase, ConvertError},
+    types::QualifiedName,
+};
+use indexmap::map::IndexMap as HashMap;
+use itertools::Itertools;
+use quote::ToTokens;
+use std::iter::once;
+use syn::{Token, Type};
+
+/// Map from QualifiedName to original C++ name. Original C++ name does not
+/// include the namespace; this can be assumed to be the same as the namespace
+/// in the QualifiedName.
+pub(crate) type CppNameMap = HashMap<QualifiedName, String>;
+
+pub(crate) fn original_name_map_from_apis<T: AnalysisPhase>(apis: &ApiVec<T>) -> CppNameMap {
+    apis.iter()
+        .filter_map(|api| {
+            api.cpp_name()
+                .as_ref()
+                .map(|cpp_name| (api.name().clone(), cpp_name.clone()))
+        })
+        .collect()
+}
+
+pub(crate) fn namespaced_name_using_original_name_map(
+    qual_name: &QualifiedName,
+    original_name_map: &CppNameMap,
+) -> String {
+    if let Some(cpp_name) = original_name_map.get(qual_name) {
+        qual_name
+            .get_namespace()
+            .iter()
+            .chain(once(cpp_name))
+            .join("::")
+    } else {
+        qual_name.to_cpp_name()
+    }
+}
+
+pub(crate) fn final_ident_using_original_name_map(
+    qual_name: &QualifiedName,
+    original_name_map: &CppNameMap,
+) -> String {
+    match original_name_map.get(qual_name) {
+        Some(original_name) => {
+            // If we have an original name, this may be a nested struct
+            // (e.g. A::B). The final ident here is just 'B' so...
+            original_name
+                .rsplit_once("::")
+                .map_or(original_name.clone(), |(_, original_name)| {
+                    original_name.to_string()
+                })
+        }
+        None => qual_name.get_final_cpp_item(),
+    }
+}
+
+pub(crate) fn type_to_cpp(ty: &Type, cpp_name_map: &CppNameMap) -> Result<String, ConvertError> {
+    match ty {
+        Type::Path(typ) => {
+            // If this is a std::unique_ptr we do need to pass
+            // its argument through.
+            let qual_name = QualifiedName::from_type_path(typ);
+            let root = namespaced_name_using_original_name_map(&qual_name, cpp_name_map);
+            if root == "Pin" {
+                // Strip all Pins from type names when describing them in C++.
+                let inner_type = &typ.path.segments.last().unwrap().arguments;
+                if let syn::PathArguments::AngleBracketed(ab) = inner_type {
+                    let inner_type = ab.args.iter().next().unwrap();
+                    if let syn::GenericArgument::Type(gat) = inner_type {
+                        return type_to_cpp(gat, cpp_name_map);
+                    }
+                }
+                panic!("Pin<...> didn't contain the inner types we expected");
+            }
+            let suffix = match &typ.path.segments.last().unwrap().arguments {
+                syn::PathArguments::AngleBracketed(ab) => {
+                    let results: Result<Vec<_>, _> = ab
+                        .args
+                        .iter()
+                        .map(|x| match x {
+                            syn::GenericArgument::Type(gat) => type_to_cpp(gat, cpp_name_map),
+                            _ => Ok("".to_string()),
+                        })
+                        .collect();
+                    Some(results?.join(", "))
+                }
+                syn::PathArguments::None | syn::PathArguments::Parenthesized(_) => None,
+            };
+            match suffix {
+                None => Ok(root),
+                Some(suffix) => Ok(format!("{}<{}>", root, suffix)),
+            }
+        }
+        Type::Reference(typr) => match &*typr.elem {
+            Type::Path(typ) if typ.path.is_ident("str") => Ok("rust::Str".into()),
+            _ => Ok(format!(
+                "{}{}&",
+                get_mut_string(&typr.mutability),
+                type_to_cpp(typr.elem.as_ref(), cpp_name_map)?
+            )),
+        },
+        Type::Ptr(typp) => Ok(format!(
+            "{}{}*",
+            get_mut_string(&typp.mutability),
+            type_to_cpp(typp.elem.as_ref(), cpp_name_map)?
+        )),
+        Type::Array(_)
+        | Type::BareFn(_)
+        | Type::Group(_)
+        | Type::ImplTrait(_)
+        | Type::Infer(_)
+        | Type::Macro(_)
+        | Type::Never(_)
+        | Type::Paren(_)
+        | Type::Slice(_)
+        | Type::TraitObject(_)
+        | Type::Tuple(_)
+        | Type::Verbatim(_) => Err(ConvertError::UnsupportedType(
+            ty.to_token_stream().to_string(),
+        )),
+        _ => Err(ConvertError::UnknownType(ty.to_token_stream().to_string())),
+    }
+}
+
+fn get_mut_string(mutability: &Option<Token![mut]>) -> &'static str {
+    match mutability {
+        None => "const ",
+        Some(_) => "",
+    }
+}
diff --git a/engine/src/conversion/codegen_rs/fun_codegen.rs b/engine/src/conversion/codegen_rs/fun_codegen.rs
new file mode 100644
index 0000000..7c32b1b
--- /dev/null
+++ b/engine/src/conversion/codegen_rs/fun_codegen.rs
@@ -0,0 +1,424 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::set::IndexSet as HashSet;
+use std::borrow::Cow;
+
+use proc_macro2::TokenStream;
+use quote::{quote, ToTokens};
+use syn::{
+    parse::Parser,
+    parse_quote,
+    punctuated::Punctuated,
+    token::{Comma, Unsafe},
+    Attribute, FnArg, ForeignItem, Ident, ImplItem, Item, ReturnType,
+};
+
+use super::{
+    function_wrapper_rs::RustParamConversion,
+    maybe_unsafes_to_tokens,
+    unqualify::{unqualify_params, unqualify_ret_type},
+    ImplBlockDetails, MaybeUnsafeStmt, RsCodegenResult, TraitImplBlockDetails, Use,
+};
+use crate::{
+    conversion::{
+        analysis::fun::{
+            ArgumentAnalysis, FnAnalysis, FnKind, MethodKind, RustRenameStrategy,
+            TraitMethodDetails,
+        },
+        api::UnsafetyNeeded,
+    },
+    types::{Namespace, QualifiedName},
+};
+use crate::{
+    conversion::{api::FuncToConvert, codegen_rs::lifetime::add_explicit_lifetime_if_necessary},
+    types::make_ident,
+};
+
+impl UnsafetyNeeded {
+    pub(crate) fn bridge_token(&self) -> Option<Unsafe> {
+        match self {
+            UnsafetyNeeded::None => None,
+            _ => Some(parse_quote! { unsafe }),
+        }
+    }
+
+    pub(crate) fn wrapper_token(&self) -> Option<Unsafe> {
+        match self {
+            UnsafetyNeeded::Always => Some(parse_quote! { unsafe }),
+            _ => None,
+        }
+    }
+
+    pub(crate) fn from_param_details(params: &[ArgumentAnalysis], ignore_placements: bool) -> Self {
+        params.iter().fold(UnsafetyNeeded::None, |accumulator, pd| {
+            if matches!(accumulator, UnsafetyNeeded::Always) {
+                UnsafetyNeeded::Always
+            } else if (pd.self_type.is_some() || pd.is_placement_return_destination)
+                && ignore_placements
+            {
+                if matches!(
+                    pd.requires_unsafe,
+                    UnsafetyNeeded::Always | UnsafetyNeeded::JustBridge
+                ) {
+                    UnsafetyNeeded::JustBridge
+                } else {
+                    accumulator
+                }
+            } else if matches!(pd.requires_unsafe, UnsafetyNeeded::Always) {
+                UnsafetyNeeded::Always
+            } else if matches!(accumulator, UnsafetyNeeded::JustBridge)
+                || matches!(pd.requires_unsafe, UnsafetyNeeded::JustBridge)
+            {
+                UnsafetyNeeded::JustBridge
+            } else {
+                UnsafetyNeeded::None
+            }
+        })
+    }
+}
+
+pub(super) fn gen_function(
+    ns: &Namespace,
+    fun: FuncToConvert,
+    analysis: FnAnalysis,
+    cpp_call_name: String,
+    non_pod_types: &HashSet<QualifiedName>,
+) -> RsCodegenResult {
+    if analysis.ignore_reason.is_err() || !analysis.externally_callable {
+        return RsCodegenResult::default();
+    }
+    let cxxbridge_name = analysis.cxxbridge_name;
+    let rust_name = &analysis.rust_name;
+    let ret_type = analysis.ret_type;
+    let param_details = analysis.param_details;
+    let wrapper_function_needed = analysis.cpp_wrapper.is_some();
+    let params = analysis.params;
+    let vis = analysis.vis;
+    let kind = analysis.kind;
+    let doc_attrs = fun.doc_attrs;
+
+    let mut cpp_name_attr = Vec::new();
+    let mut impl_entry = None;
+    let mut trait_impl_entry = None;
+    let mut bindgen_mod_items = Vec::new();
+    let always_unsafe_due_to_trait_definition = match kind {
+        FnKind::TraitMethod { ref details, .. } => details.trait_call_is_unsafe,
+        _ => false,
+    };
+    let fn_generator = FnGenerator {
+        param_details: &param_details,
+        cxxbridge_name: &cxxbridge_name,
+        rust_name,
+        unsafety: &analysis.requires_unsafe,
+        always_unsafe_due_to_trait_definition,
+        doc_attrs: &doc_attrs,
+        non_pod_types,
+    };
+    // In rare occasions, we might need to give an explicit lifetime.
+    let (lifetime_tokens, params, ret_type) = add_explicit_lifetime_if_necessary(
+        &param_details,
+        params,
+        Cow::Borrowed(&ret_type),
+        non_pod_types,
+        true,
+    );
+
+    if analysis.rust_wrapper_needed {
+        match kind {
+            FnKind::Method {
+                ref impl_for,
+                method_kind: MethodKind::Constructor { .. },
+                ..
+            } => {
+                // Constructor.
+                impl_entry = Some(fn_generator.generate_constructor_impl(impl_for));
+            }
+            FnKind::Method {
+                ref impl_for,
+                ref method_kind,
+                ..
+            } => {
+                // Method, or static method.
+                impl_entry = Some(fn_generator.generate_method_impl(
+                    matches!(method_kind, MethodKind::Constructor { .. }),
+                    impl_for,
+                    &ret_type,
+                ));
+            }
+            FnKind::TraitMethod { ref details, .. } => {
+                trait_impl_entry = Some(fn_generator.generate_trait_impl(details, &ret_type));
+            }
+            _ => {
+                // Generate plain old function
+                bindgen_mod_items.push(fn_generator.generate_function_impl(&ret_type));
+            }
+        }
+    }
+
+    let materialization = match kind {
+        FnKind::Method { .. } | FnKind::TraitMethod { .. } => None,
+        FnKind::Function => match analysis.rust_rename_strategy {
+            _ if analysis.rust_wrapper_needed => {
+                Some(Use::SpecificNameFromBindgen(make_ident(rust_name)))
+            }
+            RustRenameStrategy::RenameInOutputMod(ref alias) => {
+                Some(Use::UsedFromCxxBridgeWithAlias(alias.clone()))
+            }
+            _ => Some(Use::UsedFromCxxBridge),
+        },
+    };
+    if cxxbridge_name != cpp_call_name && !wrapper_function_needed {
+        cpp_name_attr = Attribute::parse_outer
+            .parse2(quote!(
+                #[cxx_name = #cpp_call_name]
+            ))
+            .unwrap();
+    }
+
+    // Finally - namespace support. All the Types in everything
+    // above this point are fully qualified. We need to unqualify them.
+    // We need to do that _after_ the above wrapper_function_needed
+    // work, because it relies upon spotting fully qualified names like
+    // std::unique_ptr. However, after it's done its job, all such
+    // well-known types should be unqualified already (e.g. just UniquePtr)
+    // and the following code will act to unqualify only those types
+    // which the user has declared.
+    let params = unqualify_params(params);
+    let ret_type = unqualify_ret_type(ret_type.into_owned());
+    // And we need to make an attribute for the namespace that the function
+    // itself is in.
+    let namespace_attr = if ns.is_empty() || wrapper_function_needed {
+        Vec::new()
+    } else {
+        let namespace_string = ns.to_string();
+        Attribute::parse_outer
+            .parse2(quote!(
+                #[namespace = #namespace_string]
+            ))
+            .unwrap()
+    };
+    // At last, actually generate the cxx::bridge entry.
+    let bridge_unsafety = analysis.requires_unsafe.bridge_token();
+    let extern_c_mod_item = ForeignItem::Fn(parse_quote!(
+        #(#namespace_attr)*
+        #(#cpp_name_attr)*
+        #(#doc_attrs)*
+        #vis #bridge_unsafety fn #cxxbridge_name #lifetime_tokens ( #params ) #ret_type;
+    ));
+    RsCodegenResult {
+        extern_c_mod_items: vec![extern_c_mod_item],
+        bindgen_mod_items,
+        impl_entry,
+        trait_impl_entry,
+        materializations: materialization.into_iter().collect(),
+        ..Default::default()
+    }
+}
+
+/// Knows how to generate a given function.
+#[derive(Clone)]
+struct FnGenerator<'a> {
+    param_details: &'a [ArgumentAnalysis],
+    cxxbridge_name: &'a Ident,
+    rust_name: &'a str,
+    unsafety: &'a UnsafetyNeeded,
+    always_unsafe_due_to_trait_definition: bool,
+    doc_attrs: &'a Vec<Attribute>,
+    non_pod_types: &'a HashSet<QualifiedName>,
+}
+
+impl<'a> FnGenerator<'a> {
+    fn common_parts<'b>(
+        &self,
+        avoid_self: bool,
+        parameter_reordering: &Option<Vec<usize>>,
+        ret_type: &'b ReturnType,
+    ) -> (
+        Option<TokenStream>,
+        Punctuated<FnArg, Comma>,
+        std::borrow::Cow<'b, ReturnType>,
+        TokenStream,
+    ) {
+        let mut wrapper_params: Punctuated<FnArg, Comma> = Punctuated::new();
+        let mut local_variables = Vec::new();
+        let mut arg_list = Vec::new();
+        let mut ptr_arg_name = None;
+        let mut ret_type = Cow::Borrowed(ret_type);
+        let mut any_conversion_requires_unsafe = false;
+        for pd in self.param_details {
+            let wrapper_arg_name = if pd.self_type.is_some() && !avoid_self {
+                parse_quote!(self)
+            } else {
+                pd.name.clone()
+            };
+            let rust_for_param = pd.conversion.rust_conversion(wrapper_arg_name.clone());
+            match rust_for_param {
+                RustParamConversion::Param {
+                    ty,
+                    conversion,
+                    local_variables: mut these_local_variables,
+                    conversion_requires_unsafe,
+                } => {
+                    arg_list.push(conversion.clone());
+                    local_variables.append(&mut these_local_variables);
+                    if pd.is_placement_return_destination {
+                        ptr_arg_name = Some(conversion);
+                    } else {
+                        let param_mutability = pd.conversion.rust_conversion.requires_mutability();
+                        wrapper_params.push(parse_quote!(
+                            #param_mutability #wrapper_arg_name: #ty
+                        ));
+                    }
+                    any_conversion_requires_unsafe =
+                        conversion_requires_unsafe || any_conversion_requires_unsafe;
+                }
+                RustParamConversion::ReturnValue { ty } => {
+                    ptr_arg_name = Some(pd.name.to_token_stream());
+                    ret_type = Cow::Owned(parse_quote! {
+                        -> impl autocxx::moveit::new::New<Output = #ty>
+                    });
+                    arg_list.push(pd.name.to_token_stream());
+                }
+            }
+        }
+        if let Some(parameter_reordering) = &parameter_reordering {
+            wrapper_params = Self::reorder_parameters(wrapper_params, parameter_reordering);
+        }
+        let (lifetime_tokens, wrapper_params, ret_type) = add_explicit_lifetime_if_necessary(
+            self.param_details,
+            wrapper_params,
+            ret_type,
+            self.non_pod_types,
+            false,
+        );
+
+        let cxxbridge_name = self.cxxbridge_name;
+        let call_body = MaybeUnsafeStmt::maybe_unsafe(
+            quote! {
+                cxxbridge::#cxxbridge_name ( #(#arg_list),* )
+            },
+            any_conversion_requires_unsafe || matches!(self.unsafety, UnsafetyNeeded::JustBridge),
+        );
+        let call_stmts = if let Some(ptr_arg_name) = ptr_arg_name {
+            let mut closure_stmts = local_variables;
+            closure_stmts.push(MaybeUnsafeStmt::binary(
+                quote! { let #ptr_arg_name = unsafe { #ptr_arg_name.get_unchecked_mut().as_mut_ptr() };},
+                quote! { let #ptr_arg_name = #ptr_arg_name.get_unchecked_mut().as_mut_ptr();},
+            ));
+            closure_stmts.push(call_body);
+            let closure_stmts = maybe_unsafes_to_tokens(closure_stmts, true);
+            vec![MaybeUnsafeStmt::needs_unsafe(parse_quote! {
+                autocxx::moveit::new::by_raw(move |#ptr_arg_name| {
+                    #closure_stmts
+                })
+            })]
+        } else {
+            let mut call_stmts = local_variables;
+            call_stmts.push(call_body);
+            call_stmts
+        };
+        let context_is_unsafe = matches!(self.unsafety, UnsafetyNeeded::Always)
+            || self.always_unsafe_due_to_trait_definition;
+        let call_body = maybe_unsafes_to_tokens(call_stmts, context_is_unsafe);
+        (lifetime_tokens, wrapper_params, ret_type, call_body)
+    }
+
+    /// Generate an 'impl Type { methods-go-here }' item
+    fn generate_method_impl(
+        &self,
+        avoid_self: bool,
+        impl_block_type_name: &QualifiedName,
+        ret_type: &ReturnType,
+    ) -> Box<ImplBlockDetails> {
+        let (lifetime_tokens, wrapper_params, ret_type, call_body) =
+            self.common_parts(avoid_self, &None, ret_type);
+        let rust_name = make_ident(self.rust_name);
+        let unsafety = self.unsafety.wrapper_token();
+        let doc_attrs = self.doc_attrs;
+        Box::new(ImplBlockDetails {
+            item: ImplItem::Method(parse_quote! {
+                #(#doc_attrs)*
+                pub #unsafety fn #rust_name #lifetime_tokens ( #wrapper_params ) #ret_type {
+                    #call_body
+                }
+            }),
+            ty: impl_block_type_name.get_final_ident(),
+        })
+    }
+
+    /// Generate an 'impl Trait for Type { methods-go-here }' in its entrety.
+    fn generate_trait_impl(
+        &self,
+        details: &TraitMethodDetails,
+        ret_type: &ReturnType,
+    ) -> Box<TraitImplBlockDetails> {
+        let (lifetime_tokens, wrapper_params, ret_type, call_body) =
+            self.common_parts(details.avoid_self, &details.parameter_reordering, ret_type);
+        let doc_attrs = self.doc_attrs;
+        let unsafety = self.unsafety.wrapper_token();
+        let key = details.trt.clone();
+        let method_name = &details.method_name;
+        let item = parse_quote! {
+            #(#doc_attrs)*
+            #unsafety fn #method_name #lifetime_tokens ( #wrapper_params ) #ret_type {
+                #call_body
+            }
+        };
+        Box::new(TraitImplBlockDetails { item, key })
+    }
+
+    /// Generate a 'impl Type { methods-go-here }' item which is a constructor
+    /// for use with moveit traits.
+    fn generate_constructor_impl(
+        &self,
+        impl_block_type_name: &QualifiedName,
+    ) -> Box<ImplBlockDetails> {
+        let ret_type: ReturnType = parse_quote! { -> impl autocxx::moveit::new::New<Output=Self> };
+        let (lifetime_tokens, wrapper_params, ret_type, call_body) =
+            self.common_parts(true, &None, &ret_type);
+        let rust_name = make_ident(&self.rust_name);
+        let doc_attrs = self.doc_attrs;
+        let unsafety = self.unsafety.wrapper_token();
+        Box::new(ImplBlockDetails {
+            item: ImplItem::Method(parse_quote! {
+                #(#doc_attrs)*
+                pub #unsafety fn #rust_name #lifetime_tokens ( #wrapper_params ) #ret_type {
+                    #call_body
+                }
+            }),
+            ty: impl_block_type_name.get_final_ident(),
+        })
+    }
+
+    /// Generate a function call wrapper
+    fn generate_function_impl(&self, ret_type: &ReturnType) -> Item {
+        let (lifetime_tokens, wrapper_params, ret_type, call_body) =
+            self.common_parts(false, &None, ret_type);
+        let rust_name = make_ident(self.rust_name);
+        let doc_attrs = self.doc_attrs;
+        let unsafety = self.unsafety.wrapper_token();
+        Item::Fn(parse_quote! {
+            #(#doc_attrs)*
+            pub #unsafety fn #rust_name #lifetime_tokens ( #wrapper_params ) #ret_type {
+                #call_body
+            }
+        })
+    }
+
+    fn reorder_parameters(
+        params: Punctuated<FnArg, Comma>,
+        parameter_ordering: &[usize],
+    ) -> Punctuated<FnArg, Comma> {
+        let old_params = params.into_iter().collect::<Vec<_>>();
+        parameter_ordering
+            .iter()
+            .map(|n| old_params.get(*n).unwrap().clone())
+            .collect()
+    }
+}
diff --git a/engine/src/conversion/codegen_rs/function_wrapper_rs.rs b/engine/src/conversion/codegen_rs/function_wrapper_rs.rs
new file mode 100644
index 0000000..a3fc71f
--- /dev/null
+++ b/engine/src/conversion/codegen_rs/function_wrapper_rs.rs
@@ -0,0 +1,172 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use proc_macro2::TokenStream;
+use syn::{Pat, Type, TypePtr};
+
+use crate::{
+    conversion::analysis::fun::function_wrapper::{RustConversionType, TypeConversionPolicy},
+    types::make_ident,
+};
+use quote::quote;
+use syn::parse_quote;
+
+use super::MaybeUnsafeStmt;
+
+/// Output Rust snippets for how to deal with a given parameter.
+pub(super) enum RustParamConversion {
+    Param {
+        ty: Type,
+        local_variables: Vec<MaybeUnsafeStmt>,
+        conversion: TokenStream,
+        conversion_requires_unsafe: bool,
+    },
+    ReturnValue {
+        ty: Type,
+    },
+}
+
+impl TypeConversionPolicy {
+    /// If returns `None` then this parameter should be omitted entirely.
+    pub(super) fn rust_conversion(&self, var: Pat) -> RustParamConversion {
+        match self.rust_conversion {
+            RustConversionType::None => RustParamConversion::Param {
+                ty: self.converted_rust_type(),
+                local_variables: Vec::new(),
+                conversion: quote! { #var },
+                conversion_requires_unsafe: false,
+            },
+            RustConversionType::FromStr => RustParamConversion::Param {
+                ty: parse_quote! { impl ToCppString },
+                local_variables: Vec::new(),
+                conversion: quote! ( #var .into_cpp() ),
+                conversion_requires_unsafe: false,
+            },
+            RustConversionType::ToBoxedUpHolder(ref sub) => {
+                let holder_type = sub.holder();
+                let id = sub.id();
+                let ty = parse_quote! { autocxx::subclass::CppSubclassRustPeerHolder<
+                    super::super::super:: #id>
+                };
+                RustParamConversion::Param {
+                    ty,
+                    local_variables: Vec::new(),
+                    conversion: quote! {
+                        Box::new(#holder_type(#var))
+                    },
+                    conversion_requires_unsafe: false,
+                }
+            }
+            RustConversionType::FromPinMaybeUninitToPtr => {
+                let ty = match &self.unwrapped_type {
+                    Type::Ptr(TypePtr { elem, .. }) => &*elem,
+                    _ => panic!("Not a ptr"),
+                };
+                let ty = parse_quote! {
+                    ::std::pin::Pin<&mut ::std::mem::MaybeUninit< #ty >>
+                };
+                RustParamConversion::Param {
+                    ty,
+                    local_variables: Vec::new(),
+                    conversion: quote! {
+                        #var.get_unchecked_mut().as_mut_ptr()
+                    },
+                    conversion_requires_unsafe: true,
+                }
+            }
+            RustConversionType::FromPinMoveRefToPtr => {
+                let ty = match &self.unwrapped_type {
+                    Type::Ptr(TypePtr { elem, .. }) => &*elem,
+                    _ => panic!("Not a ptr"),
+                };
+                let ty = parse_quote! {
+                    ::std::pin::Pin<autocxx::moveit::MoveRef< '_, #ty >>
+                };
+                RustParamConversion::Param {
+                    ty,
+                    local_variables: Vec::new(),
+                    conversion: quote! {
+                        { let r: &mut _ = ::std::pin::Pin::into_inner_unchecked(#var.as_mut());
+                            r
+                        }
+                    },
+                    conversion_requires_unsafe: true,
+                }
+            }
+            RustConversionType::FromTypeToPtr => {
+                let ty = match &self.unwrapped_type {
+                    Type::Ptr(TypePtr { elem, .. }) => &*elem,
+                    _ => panic!("Not a ptr"),
+                };
+                let ty = parse_quote! { &mut #ty };
+                RustParamConversion::Param {
+                    ty,
+                    local_variables: Vec::new(),
+                    conversion: quote! {
+                        #var
+                    },
+                    conversion_requires_unsafe: false,
+                }
+            }
+            RustConversionType::FromValueParamToPtr | RustConversionType::FromRValueParamToPtr => {
+                let (handler_type, param_trait) = match self.rust_conversion {
+                    RustConversionType::FromValueParamToPtr => ("ValueParamHandler", "ValueParam"),
+                    RustConversionType::FromRValueParamToPtr => {
+                        ("RValueParamHandler", "RValueParam")
+                    }
+                    _ => unreachable!(),
+                };
+                let handler_type = make_ident(handler_type);
+                let param_trait = make_ident(param_trait);
+                let var_name = if let Pat::Ident(pti) = &var {
+                    &pti.ident
+                } else {
+                    panic!("Unexpected non-ident parameter name");
+                };
+                let space_var_name = make_ident(format!("{}_space", var_name));
+                let ty = &self.unwrapped_type;
+                let ty = parse_quote! { impl autocxx::#param_trait<#ty> };
+                // This is the usual trick to put something on the stack, then
+                // immediately shadow the variable name so it can't be accessed or moved.
+                RustParamConversion::Param {
+                    ty,
+                    local_variables: vec![
+                        MaybeUnsafeStmt::new(
+                            quote! { let mut #space_var_name = autocxx::#handler_type::default(); },
+                        ),
+                        MaybeUnsafeStmt::binary(
+                            quote! { let mut #space_var_name =
+                                unsafe { ::std::pin::Pin::new_unchecked(&mut #space_var_name) };
+                            },
+                            quote! { let mut #space_var_name =
+                                ::std::pin::Pin::new_unchecked(&mut #space_var_name);
+                            },
+                        ),
+                        MaybeUnsafeStmt::needs_unsafe(
+                            quote! { #space_var_name.as_mut().populate(#var_name); },
+                        ),
+                    ],
+                    conversion: quote! {
+                        #space_var_name.get_ptr()
+                    },
+                    conversion_requires_unsafe: false,
+                }
+            }
+            // This type of conversion means that this function parameter appears in the cxx::bridge
+            // but not in the arguments for the wrapper function, because instead we return an
+            // impl New which uses the cxx::bridge function's pointer parameter.
+            RustConversionType::FromPlacementParamToNewReturn => {
+                let ty = match &self.unwrapped_type {
+                    Type::Ptr(TypePtr { elem, .. }) => *(*elem).clone(),
+                    _ => panic!("Not a ptr"),
+                };
+                RustParamConversion::ReturnValue { ty }
+            }
+        }
+    }
+}
diff --git a/engine/src/conversion/codegen_rs/impl_item_creator.rs b/engine/src/conversion/codegen_rs/impl_item_creator.rs
new file mode 100644
index 0000000..89ef896
--- /dev/null
+++ b/engine/src/conversion/codegen_rs/impl_item_creator.rs
@@ -0,0 +1,41 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use autocxx_parser::IncludeCppConfig;
+use syn::{parse_quote, Ident, Item};
+
+pub(crate) fn create_impl_items(
+    id: &Ident,
+    movable: bool,
+    destroyable: bool,
+    config: &IncludeCppConfig,
+) -> Vec<Item> {
+    if config.exclude_impls {
+        return vec![];
+    }
+    let mut results = Vec::new();
+    if destroyable {
+        results.extend([
+            Item::Impl(parse_quote! {
+                impl UniquePtr<#id> {}
+            }),
+            Item::Impl(parse_quote! {
+                impl SharedPtr<#id> {}
+            }),
+            Item::Impl(parse_quote! {
+                impl WeakPtr<#id> {}
+            }),
+        ]);
+    }
+    if movable {
+        results.push(Item::Impl(parse_quote! {
+            impl CxxVector<#id> {}
+        }))
+    }
+    results
+}
diff --git a/engine/src/conversion/codegen_rs/lifetime.rs b/engine/src/conversion/codegen_rs/lifetime.rs
new file mode 100644
index 0000000..ea2c782
--- /dev/null
+++ b/engine/src/conversion/codegen_rs/lifetime.rs
@@ -0,0 +1,205 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+use crate::{
+    conversion::analysis::fun::{
+        function_wrapper::RustConversionType, ArgumentAnalysis, ReceiverMutability,
+    },
+    types::QualifiedName,
+};
+use indexmap::set::IndexSet as HashSet;
+use proc_macro2::TokenStream;
+use quote::{quote, ToTokens};
+use std::borrow::Cow;
+use syn::{
+    parse_quote, punctuated::Punctuated, token::Comma, FnArg, GenericArgument, PatType, Path,
+    PathSegment, ReturnType, Type, TypePath, TypeReference,
+};
+
+/// Function which can add explicit lifetime parameters to function signatures
+/// where necessary, based on analysis of parameters and return types.
+/// This is necessary in three cases:
+/// 1) where the parameter is a Pin<&mut T>
+///    and the return type is some kind of reference - because lifetime elision
+///    is not smart enough to see inside a Pin.
+/// 2) as a workaround for https://github.com/dtolnay/cxx/issues/1024, where the
+///    input parameter is a non-POD type but the output reference is a POD or
+///    built-in type
+/// 3) Any parameter is any form of reference, and we're returning an `impl New`
+///    3a) an 'impl ValueParam' counts as a reference.
+pub(crate) fn add_explicit_lifetime_if_necessary<'r>(
+    param_details: &[ArgumentAnalysis],
+    mut params: Punctuated<FnArg, Comma>,
+    ret_type: Cow<'r, ReturnType>,
+    non_pod_types: &HashSet<QualifiedName>,
+    assert_all_parameters_are_references: bool,
+) -> (
+    Option<TokenStream>,
+    Punctuated<FnArg, Comma>,
+    Cow<'r, ReturnType>,
+) {
+    let has_mutable_receiver = param_details.iter().any(|pd| {
+        matches!(pd.self_type, Some((_, ReceiverMutability::Mutable)))
+            && !pd.is_placement_return_destination
+    });
+
+    let any_param_is_reference = param_details.iter().any(|pd| {
+        pd.has_lifetime
+            || matches!(
+                pd.conversion.rust_conversion,
+                RustConversionType::FromValueParamToPtr
+            )
+    });
+    let return_type_is_impl = return_type_is_impl(&ret_type);
+    let non_pod_ref_param = reference_parameter_is_non_pod_reference(&params, non_pod_types);
+    let ret_type_pod = return_type_is_pod_or_known_type_reference(&ret_type, non_pod_types);
+    let returning_impl_with_a_reference_param = return_type_is_impl && any_param_is_reference;
+    let hits_1024_bug = non_pod_ref_param && ret_type_pod;
+    if !(has_mutable_receiver || hits_1024_bug || returning_impl_with_a_reference_param) {
+        return (None, params, ret_type);
+    }
+    let new_return_type = match ret_type.as_ref() {
+        ReturnType::Type(rarrow, boxed_type) => match boxed_type.as_ref() {
+            Type::Reference(rtr) => {
+                let mut new_rtr = rtr.clone();
+                new_rtr.lifetime = Some(parse_quote! { 'a });
+                Some(ReturnType::Type(
+                    *rarrow,
+                    Box::new(Type::Reference(new_rtr)),
+                ))
+            }
+            Type::Path(typ) => {
+                let mut new_path = typ.clone();
+                add_lifetime_to_pinned_reference(&mut new_path.path.segments)
+                    .ok()
+                    .map(|_| ReturnType::Type(*rarrow, Box::new(Type::Path(new_path))))
+            }
+            Type::ImplTrait(tyit) => {
+                let old_tyit = tyit.to_token_stream();
+                Some(parse_quote! {
+                    #rarrow #old_tyit + 'a
+                })
+            }
+            _ => None,
+        },
+        _ => None,
+    };
+
+    match new_return_type {
+        None => (None, params, ret_type),
+        Some(new_return_type) => {
+            for mut param in params.iter_mut() {
+                match &mut param {
+                    FnArg::Typed(PatType { ty, .. }) => match ty.as_mut() {
+                        Type::Path(TypePath {
+                            path: Path { segments, .. },
+                            ..
+                        }) => add_lifetime_to_pinned_reference(segments).unwrap_or_else(|e| {
+                            if assert_all_parameters_are_references {
+                                panic!("Expected a pinned reference: {:?}", e)
+                            }
+                        }),
+                        Type::Reference(tyr) => add_lifetime_to_reference(tyr),
+                        Type::ImplTrait(tyit) => add_lifetime_to_impl_trait(tyit),
+                        _ if assert_all_parameters_are_references => {
+                            panic!("Expected Pin<&mut T> or &T")
+                        }
+                        _ => {}
+                    },
+                    _ if assert_all_parameters_are_references => panic!("Unexpected fnarg"),
+                    _ => {}
+                }
+            }
+
+            (Some(quote! { <'a> }), params, Cow::Owned(new_return_type))
+        }
+    }
+}
+
+fn reference_parameter_is_non_pod_reference(
+    params: &Punctuated<FnArg, Comma>,
+    non_pod_types: &HashSet<QualifiedName>,
+) -> bool {
+    params.iter().any(|param| match param {
+        FnArg::Typed(PatType { ty, .. }) => match ty.as_ref() {
+            Type::Reference(TypeReference { elem, .. }) => match elem.as_ref() {
+                Type::Path(typ) => {
+                    let qn = QualifiedName::from_type_path(typ);
+                    non_pod_types.contains(&qn)
+                }
+                _ => false,
+            },
+            _ => false,
+        },
+        _ => false,
+    })
+}
+
+fn return_type_is_pod_or_known_type_reference(
+    ret_type: &ReturnType,
+    non_pod_types: &HashSet<QualifiedName>,
+) -> bool {
+    match ret_type {
+        ReturnType::Type(_, boxed_type) => match boxed_type.as_ref() {
+            Type::Reference(rtr) => match rtr.elem.as_ref() {
+                Type::Path(typ) => {
+                    let qn = QualifiedName::from_type_path(typ);
+                    !non_pod_types.contains(&qn)
+                }
+                _ => false,
+            },
+            _ => false,
+        },
+        _ => false,
+    }
+}
+
+fn return_type_is_impl(ret_type: &ReturnType) -> bool {
+    matches!(ret_type, ReturnType::Type(_, boxed_type) if matches!(boxed_type.as_ref(), Type::ImplTrait(..)))
+}
+
+#[derive(Debug)]
+enum AddLifetimeError {
+    WasNotPin,
+}
+
+fn add_lifetime_to_pinned_reference(
+    segments: &mut Punctuated<PathSegment, syn::token::Colon2>,
+) -> Result<(), AddLifetimeError> {
+    static EXPECTED_SEGMENTS: &[(&str, bool)] = &[
+        ("std", false),
+        ("pin", false),
+        ("Pin", true), // true = act on the arguments of this segment
+    ];
+
+    for (seg, (expected_name, act)) in segments.iter_mut().zip(EXPECTED_SEGMENTS.iter()) {
+        if seg.ident != expected_name {
+            return Err(AddLifetimeError::WasNotPin);
+        }
+        if *act {
+            match &mut seg.arguments {
+                syn::PathArguments::AngleBracketed(aba) => match aba.args.iter_mut().next() {
+                    Some(GenericArgument::Type(Type::Reference(tyr))) => {
+                        add_lifetime_to_reference(tyr);
+                    }
+                    _ => panic!("Expected generic args with a reference"),
+                },
+                _ => panic!("Expected angle bracketed args"),
+            }
+        }
+    }
+    Ok(())
+}
+
+fn add_lifetime_to_reference(tyr: &mut syn::TypeReference) {
+    tyr.lifetime = Some(parse_quote! { 'a })
+}
+
+fn add_lifetime_to_impl_trait(tyit: &mut syn::TypeImplTrait) {
+    tyit.bounds
+        .push(syn::TypeParamBound::Lifetime(parse_quote! { 'a }))
+}
diff --git a/engine/src/conversion/codegen_rs/mod.rs b/engine/src/conversion/codegen_rs/mod.rs
new file mode 100644
index 0000000..d488d52
--- /dev/null
+++ b/engine/src/conversion/codegen_rs/mod.rs
@@ -0,0 +1,1379 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod fun_codegen;
+mod function_wrapper_rs;
+mod impl_item_creator;
+mod lifetime;
+mod namespace_organizer;
+mod non_pod_struct;
+pub(crate) mod unqualify;
+
+use indexmap::map::IndexMap as HashMap;
+use indexmap::set::IndexSet as HashSet;
+
+use autocxx_parser::{ExternCppType, IncludeCppConfig, RustFun};
+
+use itertools::Itertools;
+use proc_macro2::{Span, TokenStream};
+use syn::{
+    parse_quote, punctuated::Punctuated, token::Comma, Attribute, Expr, FnArg, ForeignItem,
+    ForeignItemFn, Ident, ImplItem, Item, ItemForeignMod, ItemMod, TraitItem, TypePath,
+};
+
+use crate::{
+    conversion::{
+        codegen_rs::{
+            non_pod_struct::{make_non_pod, new_non_pod_struct},
+            unqualify::{unqualify_params, unqualify_ret_type},
+        },
+        doc_attr::get_doc_attrs,
+    },
+    types::{make_ident, Namespace, QualifiedName},
+};
+use impl_item_creator::create_impl_items;
+
+use self::{
+    fun_codegen::gen_function,
+    namespace_organizer::{HasNs, NamespaceEntries},
+};
+
+use super::{
+    analysis::{
+        fun::{FnPhase, PodAndDepAnalysis, ReceiverMutability},
+        pod::PodAnalysis,
+    },
+    api::{AnalysisPhase, Api, SubclassName, TypeKind, TypedefKind},
+    convert_error::ErrorContextType,
+};
+use super::{
+    api::{Layout, Provenance, RustSubclassFnDetails, SuperclassMethod, TraitImplSignature},
+    apivec::ApiVec,
+    codegen_cpp::type_to_cpp::{
+        namespaced_name_using_original_name_map, original_name_map_from_apis, CppNameMap,
+    },
+};
+use super::{convert_error::ErrorContext, ConvertError};
+use quote::quote;
+
+/// An entry which needs to go into an `impl` block for a given type.
+struct ImplBlockDetails {
+    item: ImplItem,
+    ty: Ident,
+}
+
+struct TraitImplBlockDetails {
+    item: TraitItem,
+    key: TraitImplSignature,
+}
+
+/// Whether and how this item should be exposed in the mods constructed
+/// for actual end-user use.
+#[derive(Clone)]
+enum Use {
+    /// Uses from cxx::bridge
+    UsedFromCxxBridge,
+    /// 'use' points to cxx::bridge with a different name
+    UsedFromCxxBridgeWithAlias(Ident),
+    /// 'use' directive points to bindgen
+    UsedFromBindgen,
+    /// 'use' a specific name from bindgen.
+    SpecificNameFromBindgen(Ident),
+    /// Some kind of custom item
+    Custom(Box<Item>),
+}
+
+fn get_string_items() -> Vec<Item> {
+    [
+        Item::Trait(parse_quote! {
+            pub trait ToCppString {
+                fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString>;
+            }
+        }),
+        // We can't just impl<T: AsRef<str>> ToCppString for T
+        // because the compiler says that this trait could be implemented
+        // in future for cxx::UniquePtr<cxx::CxxString>. Fair enough.
+        Item::Impl(parse_quote! {
+            impl ToCppString for &str {
+                fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString> {
+                    make_string(self)
+                }
+            }
+        }),
+        Item::Impl(parse_quote! {
+            impl ToCppString for String {
+                fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString> {
+                    make_string(&self)
+                }
+            }
+        }),
+        Item::Impl(parse_quote! {
+            impl ToCppString for &String {
+                fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString> {
+                    make_string(self)
+                }
+            }
+        }),
+        Item::Impl(parse_quote! {
+            impl ToCppString for cxx::UniquePtr<cxx::CxxString> {
+                fn into_cpp(self) -> cxx::UniquePtr<cxx::CxxString> {
+                    self
+                }
+            }
+        }),
+    ]
+    .to_vec()
+}
+
+/// Type which handles generation of Rust code.
+/// In practice, much of the "generation" involves connecting together
+/// existing lumps of code within the Api structures.
+pub(crate) struct RsCodeGenerator<'a> {
+    include_list: &'a [String],
+    bindgen_mod: ItemMod,
+    original_name_map: CppNameMap,
+    config: &'a IncludeCppConfig,
+    header_name: Option<String>,
+}
+
+impl<'a> RsCodeGenerator<'a> {
+    /// Generate code for a set of APIs that was discovered during parsing.
+    pub(crate) fn generate_rs_code(
+        all_apis: ApiVec<FnPhase>,
+        include_list: &'a [String],
+        bindgen_mod: ItemMod,
+        config: &'a IncludeCppConfig,
+        header_name: Option<String>,
+    ) -> Vec<Item> {
+        let c = Self {
+            include_list,
+            bindgen_mod,
+            original_name_map: original_name_map_from_apis(&all_apis),
+            config,
+            header_name,
+        };
+        c.rs_codegen(all_apis)
+    }
+
+    fn rs_codegen(mut self, all_apis: ApiVec<FnPhase>) -> Vec<Item> {
+        // ... and now let's start to generate the output code.
+        // First off, when we generate structs we may need to add some methods
+        // if they're superclasses.
+        let methods_by_superclass = self.accumulate_superclass_methods(&all_apis);
+        let subclasses_with_a_single_trivial_constructor =
+            find_trivially_constructed_subclasses(&all_apis);
+        let non_pod_types = find_non_pod_types(&all_apis);
+        // Now let's generate the Rust code.
+        let (rs_codegen_results_and_namespaces, additional_cpp_needs): (Vec<_>, Vec<_>) = all_apis
+            .into_iter()
+            .map(|api| {
+                let more_cpp_needed = api.needs_cpp_codegen();
+                let name = api.name().clone();
+                let gen = self.generate_rs_for_api(
+                    api,
+                    &methods_by_superclass,
+                    &subclasses_with_a_single_trivial_constructor,
+                    &non_pod_types,
+                );
+                ((name, gen), more_cpp_needed)
+            })
+            .unzip();
+        // First, the hierarchy of mods containing lots of 'use' statements
+        // which is the final API exposed as 'ffi'.
+        let mut use_statements =
+            Self::generate_final_use_statements(&rs_codegen_results_and_namespaces);
+        // And work out what we need for the bindgen mod.
+        let bindgen_root_items =
+            self.generate_final_bindgen_mods(&rs_codegen_results_and_namespaces);
+        // Both of the above ('use' hierarchy and bindgen mod) are organized into
+        // sub-mods by namespace. From here on, things are flat.
+        let (_, rs_codegen_results): (Vec<_>, Vec<_>) =
+            rs_codegen_results_and_namespaces.into_iter().unzip();
+        let (extern_c_mod_items, extern_rust_mod_items, all_items, bridge_items): (
+            Vec<_>,
+            Vec<_>,
+            Vec<_>,
+            Vec<_>,
+        ) = rs_codegen_results
+            .into_iter()
+            .map(|api| {
+                (
+                    api.extern_c_mod_items,
+                    api.extern_rust_mod_items,
+                    api.global_items,
+                    api.bridge_items,
+                )
+            })
+            .multiunzip();
+        // Items for the [cxx::bridge] mod...
+        let mut bridge_items: Vec<Item> = bridge_items.into_iter().flatten().collect();
+        // Things to include in the "extern "C"" mod passed within the cxx::bridge
+        let mut extern_c_mod_items: Vec<ForeignItem> =
+            extern_c_mod_items.into_iter().flatten().collect();
+        // The same for extern "Rust"
+        let mut extern_rust_mod_items = extern_rust_mod_items.into_iter().flatten().collect();
+        // And a list of global items to include at the top level.
+        let mut all_items: Vec<Item> = all_items.into_iter().flatten().collect();
+        // And finally any C++ we need to generate. And by "we" I mean autocxx not cxx.
+        let has_additional_cpp_needs = additional_cpp_needs.into_iter().any(std::convert::identity);
+        extern_c_mod_items.extend(self.build_include_foreign_items(has_additional_cpp_needs));
+        // We will always create an extern "C" mod even if bindgen
+        // didn't generate one, e.g. because it only generated types.
+        // We still want cxx to know about those types.
+        let mut extern_c_mod: ItemForeignMod = parse_quote!(
+            extern "C++" {}
+        );
+        extern_c_mod.items.append(&mut extern_c_mod_items);
+        bridge_items.push(Self::make_foreign_mod_unsafe(extern_c_mod));
+        let mut extern_rust_mod: ItemForeignMod = parse_quote!(
+            extern "Rust" {}
+        );
+        extern_rust_mod.items.append(&mut extern_rust_mod_items);
+        bridge_items.push(Item::ForeignMod(extern_rust_mod));
+        // The extensive use of parse_quote here could end up
+        // being a performance bottleneck. If so, we might want
+        // to set the 'contents' field of the ItemMod
+        // structures directly.
+        if !bindgen_root_items.is_empty() {
+            self.bindgen_mod.vis = parse_quote! {};
+            self.bindgen_mod.content.as_mut().unwrap().1 = vec![Item::Mod(parse_quote! {
+                pub(super) mod root {
+                    #(#bindgen_root_items)*
+                }
+            })];
+            all_items.push(Item::Mod(self.bindgen_mod));
+        }
+        all_items.push(Item::Mod(parse_quote! {
+            #[cxx::bridge]
+            mod cxxbridge {
+                #(#bridge_items)*
+            }
+        }));
+
+        all_items.push(Item::Use(parse_quote! {
+            #[allow(unused_imports)]
+            use bindgen::root;
+        }));
+        all_items.append(&mut use_statements);
+        all_items
+    }
+
+    fn accumulate_superclass_methods(
+        &self,
+        apis: &ApiVec<FnPhase>,
+    ) -> HashMap<QualifiedName, Vec<SuperclassMethod>> {
+        let mut results = HashMap::new();
+        results.extend(
+            self.config
+                .superclasses()
+                .map(|sc| (QualifiedName::new_from_cpp_name(sc), Vec::new())),
+        );
+        for api in apis.iter() {
+            if let Api::SubclassTraitItem { details, .. } = api {
+                let list = results.get_mut(&details.receiver);
+                if let Some(list) = list {
+                    list.push(details.clone());
+                }
+            }
+        }
+        results
+    }
+
+    fn make_foreign_mod_unsafe(ifm: ItemForeignMod) -> Item {
+        // At the moment syn does not support outputting 'unsafe extern "C"' except in verbatim
+        // items. See https://github.com/dtolnay/syn/pull/938
+        Item::Verbatim(quote! {
+            unsafe #ifm
+        })
+    }
+
+    fn build_include_foreign_items(&self, has_additional_cpp_needs: bool) -> Vec<ForeignItem> {
+        let extra_inclusion = if has_additional_cpp_needs {
+            Some(self.header_name.clone().unwrap())
+        } else {
+            None
+        };
+        let chained = self.include_list.iter().chain(extra_inclusion.iter());
+        chained
+            .map(|inc| {
+                ForeignItem::Macro(parse_quote! {
+                    include!(#inc);
+                })
+            })
+            .collect()
+    }
+
+    /// Generate lots of 'use' statements to pull cxxbridge items into the output
+    /// mod hierarchy according to C++ namespaces.
+    fn generate_final_use_statements(
+        input_items: &[(QualifiedName, RsCodegenResult)],
+    ) -> Vec<Item> {
+        let mut output_items = Vec::new();
+        let ns_entries = NamespaceEntries::new(input_items);
+        Self::append_child_use_namespace(&ns_entries, &mut output_items);
+        output_items
+    }
+
+    fn append_child_use_namespace(
+        ns_entries: &NamespaceEntries<(QualifiedName, RsCodegenResult)>,
+        output_items: &mut Vec<Item>,
+    ) {
+        for (name, codegen) in ns_entries.entries() {
+            output_items.extend(codegen.materializations.iter().map(|materialization| {
+                match materialization {
+                    Use::UsedFromCxxBridgeWithAlias(ref alias) => {
+                        Self::generate_cxx_use_stmt(name, Some(alias))
+                    }
+                    Use::UsedFromCxxBridge => Self::generate_cxx_use_stmt(name, None),
+                    Use::UsedFromBindgen => Self::generate_bindgen_use_stmt(name),
+                    Use::SpecificNameFromBindgen(id) => {
+                        let name = QualifiedName::new(name.get_namespace(), id.clone());
+                        Self::generate_bindgen_use_stmt(&name)
+                    }
+                    Use::Custom(item) => *item.clone(),
+                }
+            }));
+        }
+        for (child_name, child_ns_entries) in ns_entries.children() {
+            if child_ns_entries.is_empty() {
+                continue;
+            }
+            let child_id = make_ident(child_name);
+            let mut new_mod: ItemMod = parse_quote!(
+                pub mod #child_id {
+                }
+            );
+            Self::append_child_use_namespace(
+                child_ns_entries,
+                &mut new_mod.content.as_mut().unwrap().1,
+            );
+            output_items.push(Item::Mod(new_mod));
+        }
+    }
+
+    fn append_uses_for_ns(&mut self, items: &mut Vec<Item>, ns: &Namespace) {
+        let super_duper = std::iter::repeat(make_ident("super")); // I'll get my coat
+        let supers = super_duper.clone().take(ns.depth() + 2);
+        items.push(Item::Use(parse_quote! {
+            #[allow(unused_imports)]
+            use self::
+                #(#supers)::*
+            ::cxxbridge;
+        }));
+        if !self.config.exclude_utilities() {
+            let supers = super_duper.clone().take(ns.depth() + 2);
+            items.push(Item::Use(parse_quote! {
+                #[allow(unused_imports)]
+                use self::
+                    #(#supers)::*
+                ::ToCppString;
+            }));
+        }
+        let supers = super_duper.take(ns.depth() + 1);
+        items.push(Item::Use(parse_quote! {
+            #[allow(unused_imports)]
+            use self::
+                #(#supers)::*
+            ::root;
+        }));
+    }
+
+    fn append_child_bindgen_namespace(
+        &mut self,
+        ns_entries: &NamespaceEntries<(QualifiedName, RsCodegenResult)>,
+        output_items: &mut Vec<Item>,
+        ns: &Namespace,
+    ) {
+        let mut impl_entries_by_type: HashMap<_, Vec<_>> = HashMap::new();
+        let mut trait_impl_entries_by_trait_and_ty: HashMap<_, Vec<_>> = HashMap::new();
+        for item in ns_entries.entries() {
+            output_items.extend(item.1.bindgen_mod_items.iter().cloned());
+            if let Some(impl_entry) = &item.1.impl_entry {
+                impl_entries_by_type
+                    .entry(impl_entry.ty.clone())
+                    .or_default()
+                    .push(&impl_entry.item);
+            }
+            if let Some(trait_impl_entry) = &item.1.trait_impl_entry {
+                trait_impl_entries_by_trait_and_ty
+                    .entry(trait_impl_entry.key.clone())
+                    .or_default()
+                    .push(&trait_impl_entry.item);
+            }
+        }
+        for (ty, entries) in impl_entries_by_type.into_iter() {
+            output_items.push(Item::Impl(parse_quote! {
+                impl #ty {
+                    #(#entries)*
+                }
+            }))
+        }
+        for (key, entries) in trait_impl_entries_by_trait_and_ty.into_iter() {
+            let unsafety = key.unsafety;
+            let ty = key.ty;
+            let trt = key.trait_signature;
+            output_items.push(Item::Impl(parse_quote! {
+                #unsafety impl #trt for #ty {
+                    #(#entries)*
+                }
+            }))
+        }
+        for (child_name, child_ns_entries) in ns_entries.children() {
+            let new_ns = ns.push((*child_name).clone());
+            let child_id = make_ident(child_name);
+
+            let mut inner_output_items = Vec::new();
+            self.append_child_bindgen_namespace(child_ns_entries, &mut inner_output_items, &new_ns);
+            if !inner_output_items.is_empty() {
+                let mut new_mod: ItemMod = parse_quote!(
+                    pub mod #child_id {
+                    }
+                );
+                self.append_uses_for_ns(&mut inner_output_items, &new_ns);
+                new_mod.content.as_mut().unwrap().1 = inner_output_items;
+                output_items.push(Item::Mod(new_mod));
+            }
+        }
+    }
+
+    fn id_to_expr(id: &Ident) -> Expr {
+        parse_quote! { #id }
+    }
+
+    fn generate_final_bindgen_mods(
+        &mut self,
+        input_items: &[(QualifiedName, RsCodegenResult)],
+    ) -> Vec<Item> {
+        let mut output_items = Vec::new();
+        let ns = Namespace::new();
+        let ns_entries = NamespaceEntries::new(input_items);
+        self.append_child_bindgen_namespace(&ns_entries, &mut output_items, &ns);
+        self.append_uses_for_ns(&mut output_items, &ns);
+        output_items
+    }
+
+    fn generate_rs_for_api(
+        &self,
+        api: Api<FnPhase>,
+        associated_methods: &HashMap<QualifiedName, Vec<SuperclassMethod>>,
+        subclasses_with_a_single_trivial_constructor: &HashSet<QualifiedName>,
+        non_pod_types: &HashSet<QualifiedName>,
+    ) -> RsCodegenResult {
+        let name = api.name().clone();
+        let id = name.get_final_ident();
+        let cpp_call_name = api.effective_cpp_name().to_string();
+        match api {
+            Api::StringConstructor { .. } => {
+                let make_string_name = make_ident(self.config.get_makestring_name());
+                RsCodegenResult {
+                    extern_c_mod_items: vec![ForeignItem::Fn(parse_quote!(
+                        fn #make_string_name(str_: &str) -> UniquePtr<CxxString>;
+                    ))],
+                    global_items: get_string_items(),
+                    materializations: vec![Use::UsedFromCxxBridgeWithAlias(make_ident(
+                        "make_string",
+                    ))],
+                    ..Default::default()
+                }
+            }
+            Api::Function { fun, analysis, .. } => gen_function(
+                name.get_namespace(),
+                *fun,
+                analysis,
+                cpp_call_name,
+                non_pod_types,
+            ),
+            Api::Const { const_item, .. } => RsCodegenResult {
+                bindgen_mod_items: vec![Item::Const(const_item)],
+                materializations: vec![Use::UsedFromBindgen],
+                ..Default::default()
+            },
+            Api::Typedef { analysis, .. } => RsCodegenResult {
+                bindgen_mod_items: vec![match analysis.kind {
+                    TypedefKind::Type(type_item) => Item::Type(type_item),
+                    TypedefKind::Use(use_item, _) => Item::Use(use_item),
+                }],
+                materializations: vec![Use::UsedFromBindgen],
+                ..Default::default()
+            },
+            Api::Struct {
+                details,
+                analysis:
+                    PodAndDepAnalysis {
+                        pod:
+                            PodAnalysis {
+                                is_generic, kind, ..
+                            },
+                        constructors,
+                        ..
+                    },
+                ..
+            } => {
+                let doc_attrs = get_doc_attrs(&details.item.attrs);
+                let layout = details.layout.clone();
+                self.generate_type(
+                    &name,
+                    id,
+                    kind,
+                    constructors.move_constructor,
+                    constructors.destructor,
+                    || Some((Item::Struct(details.item), doc_attrs)),
+                    associated_methods,
+                    layout,
+                    is_generic,
+                )
+            }
+            Api::Enum { item, .. } => {
+                let doc_attrs = get_doc_attrs(&item.attrs);
+                self.generate_type(
+                    &name,
+                    id,
+                    TypeKind::Pod,
+                    true,
+                    true,
+                    || Some((Item::Enum(item), doc_attrs)),
+                    associated_methods,
+                    None,
+                    false,
+                )
+            }
+            Api::ForwardDeclaration { .. }
+            | Api::ConcreteType { .. }
+            | Api::OpaqueTypedef { .. } => self.generate_type(
+                &name,
+                id,
+                TypeKind::Abstract,
+                false, // assume for now that these types can't be kept in a Vector
+                true,  // assume for now that these types can be put in a smart pointer
+                || None,
+                associated_methods,
+                None,
+                false,
+            ),
+            Api::CType { .. } => RsCodegenResult {
+                extern_c_mod_items: vec![ForeignItem::Verbatim(quote! {
+                    type #id = autocxx::#id;
+                })],
+                ..Default::default()
+            },
+            Api::RustType { path, .. } => RsCodegenResult {
+                global_items: vec![parse_quote! {
+                    use super::#path;
+                }],
+                extern_rust_mod_items: vec![parse_quote! {
+                    type #id;
+                }],
+                ..Default::default()
+            },
+            Api::RustFn {
+                details:
+                    RustFun {
+                        path,
+                        sig,
+                        receiver: None,
+                        ..
+                    },
+                ..
+            } => RsCodegenResult {
+                global_items: vec![parse_quote! {
+                    use super::#path;
+                }],
+                extern_rust_mod_items: vec![parse_quote! {
+                    #sig;
+                }],
+                ..Default::default()
+            },
+            Api::RustFn {
+                details:
+                    RustFun {
+                        sig,
+                        receiver: Some(_),
+                        ..
+                    },
+                ..
+            } => RsCodegenResult {
+                extern_rust_mod_items: vec![parse_quote! {
+                    #sig;
+                }],
+                ..Default::default()
+            },
+            Api::RustSubclassFn {
+                details, subclass, ..
+            } => Self::generate_subclass_fn(id, *details, subclass),
+            Api::Subclass {
+                name, superclass, ..
+            } => {
+                let methods = associated_methods.get(&superclass);
+                let generate_peer_constructor =
+                    subclasses_with_a_single_trivial_constructor.contains(&name.0.name);
+                self.generate_subclass(name, &superclass, methods, generate_peer_constructor)
+            }
+            Api::ExternCppType {
+                details: ExternCppType { rust_path, .. },
+                ..
+            } => self.generate_extern_cpp_type(&name, rust_path, name.ns_segment_iter().count()),
+            Api::IgnoredItem {
+                err,
+                ctx: Some(ctx),
+                ..
+            } => Self::generate_error_entry(err, ctx),
+            Api::IgnoredItem { .. } | Api::SubclassTraitItem { .. } => RsCodegenResult::default(),
+        }
+    }
+
+    fn generate_subclass(
+        &self,
+        sub: SubclassName,
+        superclass: &QualifiedName,
+        methods: Option<&Vec<SuperclassMethod>>,
+        generate_peer_constructor: bool,
+    ) -> RsCodegenResult {
+        let super_name = superclass.get_final_item();
+        let super_path = superclass.to_type_path();
+        let super_cxxxbridge_id = superclass.get_final_ident();
+        let id = sub.id();
+        let holder = sub.holder();
+        let full_cpp = sub.cpp();
+        let cpp_path = full_cpp.to_type_path();
+        let cpp_id = full_cpp.get_final_ident();
+        let mut global_items = Vec::new();
+        global_items.push(parse_quote! {
+            pub use bindgen::root::#holder;
+        });
+        let relinquish_ownership_call = sub.cpp_remove_ownership();
+        let mut bindgen_mod_items = vec![
+            parse_quote! {
+                pub use cxxbridge::#cpp_id;
+            },
+            parse_quote! {
+                pub struct #holder(pub autocxx::subclass::CppSubclassRustPeerHolder<super::super::super::#id>);
+            },
+            parse_quote! {
+                impl autocxx::subclass::CppSubclassCppPeer for #cpp_id {
+                    fn relinquish_ownership(&self) {
+                        self.#relinquish_ownership_call();
+                    }
+                }
+            },
+        ];
+        let mut extern_c_mod_items = vec![
+            self.generate_cxxbridge_type(&full_cpp, false, Vec::new()),
+            parse_quote! {
+                fn #relinquish_ownership_call(self: &#cpp_id);
+            },
+        ];
+        if let Some(methods) = methods {
+            let supers = SubclassName::get_supers_trait_name(superclass).to_type_path();
+            let methods_impls: Vec<ImplItem> = methods
+                .iter()
+                .filter(|m| !m.is_pure_virtual)
+                .map(|m| {
+                    let cpp_super_method_name =
+                        SubclassName::get_super_fn_name(&Namespace::new(), &m.name.to_string())
+                            .get_final_ident();
+                    let mut params = m.params.clone();
+                    let ret = &m.ret_type.clone();
+                    let (peer_fn, first_param) = match m.receiver_mutability {
+                        ReceiverMutability::Const => ("peer", parse_quote!(&self)),
+                        ReceiverMutability::Mutable => ("peer_mut", parse_quote!(&mut self)),
+                    };
+                    let peer_fn = make_ident(peer_fn);
+                    *(params.iter_mut().next().unwrap()) = first_param;
+                    let param_names = m.param_names.iter().skip(1);
+                    let unsafe_token = m.requires_unsafe.wrapper_token();
+                    parse_quote! {
+                        #unsafe_token fn #cpp_super_method_name(#params) #ret {
+                            use autocxx::subclass::CppSubclass;
+                            self.#peer_fn().#cpp_super_method_name(#(#param_names),*)
+                        }
+                    }
+                })
+                .collect();
+            if !methods_impls.is_empty() {
+                bindgen_mod_items.push(parse_quote! {
+                    #[allow(non_snake_case)]
+                    impl #supers for super::super::super::#id {
+                        #(#methods_impls)*
+                    }
+                });
+            }
+        }
+        if generate_peer_constructor {
+            bindgen_mod_items.push(parse_quote! {
+                impl autocxx::subclass::CppPeerConstructor<#cpp_id> for super::super::super::#id {
+                    fn make_peer(&mut self, peer_holder: autocxx::subclass::CppSubclassRustPeerHolder<Self>) -> cxx::UniquePtr<#cpp_path> {
+                        use autocxx::moveit::EmplaceUnpinned;
+                        cxx::UniquePtr::emplace(#cpp_id :: new(peer_holder))
+                    }
+                }
+            })
+        };
+
+        // Once for each superclass, in future...
+        let as_id = make_ident(format!("As_{}", super_name));
+        extern_c_mod_items.push(parse_quote! {
+            fn #as_id(self: &#cpp_id) -> &#super_cxxxbridge_id;
+        });
+        let as_mut_id = make_ident(format!("As_{}_mut", super_name));
+        extern_c_mod_items.push(parse_quote! {
+            fn #as_mut_id(self: Pin<&mut #cpp_id>) -> Pin<&mut #super_cxxxbridge_id>;
+        });
+        bindgen_mod_items.push(parse_quote! {
+            impl AsRef<#super_path> for super::super::super::#id {
+                fn as_ref(&self) -> &cxxbridge::#super_cxxxbridge_id {
+                    use autocxx::subclass::CppSubclass;
+                    self.peer().#as_id()
+                }
+            }
+        });
+        // TODO it would be nice to impl AsMut here but pin prevents us
+        bindgen_mod_items.push(parse_quote! {
+            impl super::super::super::#id {
+                pub fn pin_mut(&mut self) -> ::std::pin::Pin<&mut cxxbridge::#super_cxxxbridge_id> {
+                    use autocxx::subclass::CppSubclass;
+                    self.peer_mut().#as_mut_id()
+                }
+            }
+        });
+        let remove_ownership = sub.remove_ownership();
+        global_items.push(parse_quote! {
+            #[allow(non_snake_case)]
+            pub fn #remove_ownership(me: Box<#holder>) -> Box<#holder> {
+                Box::new(#holder(me.0.relinquish_ownership()))
+            }
+        });
+        RsCodegenResult {
+            extern_c_mod_items,
+            // For now we just assume we can't keep subclasses in vectors, but we can put them in
+            // smart pointers.
+            // That's the reason for the 'false' and 'true'
+            bridge_items: create_impl_items(&cpp_id, false, true, self.config),
+            bindgen_mod_items,
+            materializations: vec![Use::Custom(Box::new(parse_quote! {
+                pub use cxxbridge::#cpp_id;
+            }))],
+            global_items,
+            extern_rust_mod_items: vec![
+                parse_quote! {
+                    pub type #holder;
+                },
+                parse_quote! {
+                    fn #remove_ownership(me: Box<#holder>) -> Box<#holder>;
+                },
+            ],
+            ..Default::default()
+        }
+    }
+
+    fn generate_subclass_fn(
+        api_name: Ident,
+        details: RustSubclassFnDetails,
+        subclass: SubclassName,
+    ) -> RsCodegenResult {
+        let params = details.params;
+        let ret = details.ret;
+        let unsafe_token = details.requires_unsafe.wrapper_token();
+        let global_def = quote! { #unsafe_token fn #api_name(#params) #ret };
+        let params = unqualify_params(params);
+        let ret = unqualify_ret_type(ret);
+        let method_name = details.method_name;
+        let cxxbridge_decl: ForeignItemFn =
+            parse_quote! { #unsafe_token fn #api_name(#params) #ret; };
+        let args: Punctuated<Expr, Comma> =
+            Self::args_from_sig(&cxxbridge_decl.sig.inputs).collect();
+        let superclass_id = details.superclass.get_final_ident();
+        let methods_trait = SubclassName::get_methods_trait_name(&details.superclass);
+        let methods_trait = methods_trait.to_type_path();
+        let (deref_ty, deref_call, borrow, mut_token) = match details.receiver_mutability {
+            ReceiverMutability::Const => ("Deref", "deref", "try_borrow", None),
+            ReceiverMutability::Mutable => (
+                "DerefMut",
+                "deref_mut",
+                "try_borrow_mut",
+                Some(syn::token::Mut(Span::call_site())),
+            ),
+        };
+        let deref_ty = make_ident(deref_ty);
+        let deref_call = make_ident(deref_call);
+        let borrow = make_ident(borrow);
+        let destroy_panic_msg = format!("Rust subclass API (method {} of subclass {} of superclass {}) called after subclass destroyed", method_name, subclass.0.name, superclass_id);
+        let reentrancy_panic_msg = format!("Rust subclass API (method {} of subclass {} of superclass {}) called whilst subclass already borrowed - likely a re-entrant call",  method_name, subclass.0.name, superclass_id);
+        RsCodegenResult {
+            global_items: vec![parse_quote! {
+                #global_def {
+                    let rc = me.0
+                        .get()
+                        .expect(#destroy_panic_msg);
+                    let #mut_token b = rc
+                        .as_ref()
+                        .#borrow()
+                        .expect(#reentrancy_panic_msg);
+                    let r = std::ops::#deref_ty::#deref_call(& #mut_token b);
+                    #methods_trait :: #method_name
+                        (r,
+                        #args)
+                }
+            }],
+            extern_rust_mod_items: vec![ForeignItem::Fn(cxxbridge_decl)],
+            ..Default::default()
+        }
+    }
+
+    fn args_from_sig(params: &Punctuated<FnArg, Comma>) -> impl Iterator<Item = Expr> + '_ {
+        params.iter().skip(1).filter_map(|fnarg| match fnarg {
+            syn::FnArg::Receiver(_) => None,
+            syn::FnArg::Typed(fnarg) => match &*fnarg.pat {
+                syn::Pat::Ident(id) => Some(Self::id_to_expr(&id.ident)),
+                _ => None,
+            },
+        })
+    }
+
+    #[allow(clippy::too_many_arguments)] // currently the least unclear way
+    fn generate_type<F>(
+        &self,
+        name: &QualifiedName,
+        id: Ident,
+        type_kind: TypeKind,
+        movable: bool,
+        destroyable: bool,
+        item_creator: F,
+        associated_methods: &HashMap<QualifiedName, Vec<SuperclassMethod>>,
+        layout: Option<Layout>,
+        is_generic: bool,
+    ) -> RsCodegenResult
+    where
+        F: FnOnce() -> Option<(Item, Vec<Attribute>)>,
+    {
+        let mut bindgen_mod_items = Vec::new();
+        let mut materializations = vec![Use::UsedFromBindgen];
+        Self::add_superclass_stuff_to_type(
+            name,
+            &mut bindgen_mod_items,
+            &mut materializations,
+            associated_methods.get(name),
+        );
+        let orig_item = item_creator();
+        let doc_attrs = orig_item
+            .as_ref()
+            .map(|maybe_item| maybe_item.1.clone())
+            .unwrap_or_default();
+        // We have a choice here to either:
+        // a) tell cxx to generate an opaque type using 'type A;'
+        // b) generate a concrete type definition, e.g. by using bindgen's
+        //    or doing our own, and then telling cxx 'type A = bindgen::A';'
+        match type_kind {
+            TypeKind::Pod | TypeKind::NonPod => {
+                // Feed cxx "type T = root::bindgen::T"
+                // For non-POD types, there might be the option of simply giving
+                // cxx a "type T;" as we do for abstract types below. There's
+                // two reasons we don't:
+                // a) we want to specify size and alignment for the sake of
+                //    moveit;
+                // b) for nested types such as 'A::B', there is no combination
+                //    of cxx-acceptable attributes which will inform cxx that
+                //    A is a class rather than a namespace.
+                let mut item = orig_item
+                    .expect("Instantiable types must provide instance")
+                    .0;
+                if matches!(type_kind, TypeKind::NonPod) {
+                    if let Item::Struct(ref mut s) = item {
+                        // Retain generics and doc attrs.
+                        make_non_pod(s, layout);
+                    } else {
+                        // enum
+                        item = Item::Struct(new_non_pod_struct(id.clone()));
+                    }
+                }
+                bindgen_mod_items.push(item);
+
+                if is_generic {
+                    // Still generate the type as emitted by bindgen,
+                    // but don't attempt to tell cxx about it
+                    RsCodegenResult {
+                        bindgen_mod_items,
+                        materializations,
+                        ..Default::default()
+                    }
+                } else {
+                    RsCodegenResult {
+                        global_items: self.generate_extern_type_impl(type_kind, name),
+                        bridge_items: create_impl_items(&id, movable, destroyable, self.config),
+                        extern_c_mod_items: vec![
+                            self.generate_cxxbridge_type(name, true, doc_attrs)
+                        ],
+                        bindgen_mod_items,
+                        materializations,
+                        ..Default::default()
+                    }
+                }
+            }
+            TypeKind::Abstract => {
+                if is_generic {
+                    RsCodegenResult::default()
+                } else {
+                    // Feed cxx "type T;"
+                    // We MUST do this because otherwise cxx assumes this can be
+                    // instantiated using UniquePtr etc.
+                    bindgen_mod_items.push(Item::Use(parse_quote! { pub use cxxbridge::#id; }));
+                    RsCodegenResult {
+                        extern_c_mod_items: vec![
+                            self.generate_cxxbridge_type(name, false, doc_attrs)
+                        ],
+                        bindgen_mod_items,
+                        materializations,
+                        ..Default::default()
+                    }
+                }
+            }
+        }
+    }
+
+    fn add_superclass_stuff_to_type(
+        name: &QualifiedName,
+        bindgen_mod_items: &mut Vec<Item>,
+        materializations: &mut Vec<Use>,
+        methods: Option<&Vec<SuperclassMethod>>,
+    ) {
+        if let Some(methods) = methods {
+            let (supers, mains): (Vec<_>, Vec<_>) = methods
+                .iter()
+                .map(|method| {
+                    let id = &method.name;
+                    let super_id =
+                        SubclassName::get_super_fn_name(&Namespace::new(), &id.to_string())
+                            .get_final_ident();
+                    let param_names: Punctuated<Expr, Comma> =
+                        Self::args_from_sig(&method.params).collect();
+                    let mut params = method.params.clone();
+                    *(params.iter_mut().next().unwrap()) = match method.receiver_mutability {
+                        ReceiverMutability::Const => parse_quote!(&self),
+                        ReceiverMutability::Mutable => parse_quote!(&mut self),
+                    };
+                    let ret_type = &method.ret_type;
+                    let unsafe_token = method.requires_unsafe.wrapper_token();
+                    if method.is_pure_virtual {
+                        (
+                            None,
+                            parse_quote!(
+                                #unsafe_token fn #id(#params) #ret_type;
+                            ),
+                        )
+                    } else {
+                        let a: Option<TraitItem> = Some(parse_quote!(
+                            #unsafe_token fn #super_id(#params) #ret_type;
+                        ));
+                        let b: TraitItem = parse_quote!(
+                            #unsafe_token fn #id(#params) #ret_type {
+                                self.#super_id(#param_names)
+                            }
+                        );
+                        (a, b)
+                    }
+                })
+                .unzip();
+            let supers: Vec<_> = supers.into_iter().flatten().collect();
+            let supers_name = SubclassName::get_supers_trait_name(name).get_final_ident();
+            let methods_name = SubclassName::get_methods_trait_name(name).get_final_ident();
+            if !supers.is_empty() {
+                bindgen_mod_items.push(parse_quote! {
+                    #[allow(non_snake_case)]
+                    pub trait #supers_name {
+                        #(#supers)*
+                    }
+                });
+                bindgen_mod_items.push(parse_quote! {
+                    #[allow(non_snake_case)]
+                    pub trait #methods_name : #supers_name {
+                        #(#mains)*
+                    }
+                });
+                materializations.push(Use::SpecificNameFromBindgen(supers_name));
+            } else {
+                bindgen_mod_items.push(parse_quote! {
+                    #[allow(non_snake_case)]
+                    pub trait #methods_name {
+                        #(#mains)*
+                    }
+                });
+            }
+            materializations.push(Use::SpecificNameFromBindgen(methods_name));
+        }
+    }
+
+    fn generate_extern_cpp_type(
+        &self,
+        name: &QualifiedName,
+        rust_path: TypePath,
+        ns_depth: usize,
+    ) -> RsCodegenResult {
+        let id = name.get_final_ident();
+        let super_duper = std::iter::repeat(make_ident("super"));
+        let supers = super_duper.take(ns_depth + 2);
+        let use_statement = parse_quote! {
+            pub use #(#supers)::* :: #id;
+        };
+        RsCodegenResult {
+            bindgen_mod_items: vec![use_statement],
+            extern_c_mod_items: vec![self.generate_cxxbridge_type(name, true, Vec::new())],
+            materializations: vec![Use::Custom(Box::new(parse_quote! { pub use #rust_path; }))],
+            ..Default::default()
+        }
+    }
+
+    /// Generates something in the output mod that will carry a docstring
+    /// explaining why a given type or function couldn't have bindings
+    /// generated.
+    fn generate_error_entry(err: ConvertError, ctx: ErrorContext) -> RsCodegenResult {
+        let err = format!("autocxx bindings couldn't be generated: {}", err);
+        let (impl_entry, bindgen_mod_item, materialization) = match ctx.into_type() {
+            ErrorContextType::Item(id) => (
+                // Populate within bindgen mod because impl blocks may attach.
+                None,
+                Some(parse_quote! {
+                    #[doc = #err]
+                    pub struct #id;
+                }),
+                Some(Use::SpecificNameFromBindgen(id)),
+            ),
+            ErrorContextType::SanitizedItem(id) => (
+                // Guaranteed to be no impl blocks - populate directly in output mod.
+                None,
+                None,
+                Some(Use::Custom(Box::new(parse_quote! {
+                    #[doc = #err]
+                    pub struct #id;
+                }))),
+            ),
+            ErrorContextType::Method { self_ty, method } => (
+                Some(Box::new(ImplBlockDetails {
+                    item: parse_quote! {
+                        #[doc = #err]
+                        fn #method(_uhoh: autocxx::BindingGenerationFailure) {
+                        }
+                    },
+                    ty: self_ty,
+                })),
+                None,
+                None,
+            ),
+        };
+        RsCodegenResult {
+            impl_entry,
+            bindgen_mod_items: bindgen_mod_item.into_iter().collect(),
+            materializations: materialization.into_iter().collect(),
+            ..Default::default()
+        }
+    }
+
+    fn generate_cxx_use_stmt(name: &QualifiedName, alias: Option<&Ident>) -> Item {
+        let segs = Self::find_output_mod_root(name.get_namespace())
+            .chain(std::iter::once(make_ident("cxxbridge")))
+            .chain(std::iter::once(name.get_final_ident()));
+        Item::Use(match alias {
+            None => parse_quote! {
+                pub use #(#segs)::*;
+            },
+            Some(alias) => parse_quote! {
+                pub use #(#segs)::* as #alias;
+            },
+        })
+    }
+
+    fn generate_bindgen_use_stmt(name: &QualifiedName) -> Item {
+        let segs =
+            Self::find_output_mod_root(name.get_namespace()).chain(name.get_bindgen_path_idents());
+        Item::Use(parse_quote! {
+            pub use #(#segs)::*;
+        })
+    }
+
+    fn generate_extern_type_impl(&self, type_kind: TypeKind, tyname: &QualifiedName) -> Vec<Item> {
+        let tynamestring = namespaced_name_using_original_name_map(tyname, &self.original_name_map);
+        let fulltypath = tyname.get_bindgen_path_idents();
+        let kind_item = match type_kind {
+            TypeKind::Pod => "Trivial",
+            _ => "Opaque",
+        };
+        let kind_item = make_ident(kind_item);
+        vec![Item::Impl(parse_quote! {
+            unsafe impl cxx::ExternType for #(#fulltypath)::* {
+                type Id = cxx::type_id!(#tynamestring);
+                type Kind = cxx::kind::#kind_item;
+            }
+        })]
+    }
+
+    fn generate_cxxbridge_type(
+        &self,
+        name: &QualifiedName,
+        references_bindgen: bool,
+        doc_attrs: Vec<Attribute>,
+    ) -> ForeignItem {
+        let ns = name.get_namespace();
+        let id = name.get_final_ident();
+        // The following lines actually Tell A Lie.
+        // If we have a nested class, B::C, within namespace A,
+        // we actually have to tell cxx that we have nested class C
+        // within namespace A.
+        let mut ns_components: Vec<_> = ns.iter().cloned().collect();
+        let mut cxx_name = None;
+        if let Some(cpp_name) = self.original_name_map.get(name) {
+            let cpp_name = QualifiedName::new_from_cpp_name(cpp_name);
+            cxx_name = Some(cpp_name.get_final_item().to_string());
+            ns_components.extend(cpp_name.ns_segment_iter().cloned());
+        };
+
+        let mut for_extern_c_ts = if !ns_components.is_empty() {
+            let ns_string = ns_components.join("::");
+            quote! {
+                #[namespace = #ns_string]
+            }
+        } else {
+            TokenStream::new()
+        };
+
+        if let Some(n) = cxx_name {
+            for_extern_c_ts.extend(quote! {
+                #[cxx_name = #n]
+            });
+        }
+
+        for_extern_c_ts.extend(quote! {
+            #(#doc_attrs)*
+        });
+
+        if references_bindgen {
+            for_extern_c_ts.extend(quote! {
+                type #id = super::bindgen::root::
+            });
+            for_extern_c_ts.extend(ns.iter().map(make_ident).map(|id| {
+                quote! {
+                    #id::
+                }
+            }));
+            for_extern_c_ts.extend(quote! {
+                #id;
+            });
+        } else {
+            for_extern_c_ts.extend(quote! {
+                type #id;
+            });
+        }
+        ForeignItem::Verbatim(for_extern_c_ts)
+    }
+
+    fn find_output_mod_root(ns: &Namespace) -> impl Iterator<Item = Ident> {
+        std::iter::repeat(make_ident("super")).take(ns.depth())
+    }
+}
+
+fn find_trivially_constructed_subclasses(apis: &ApiVec<FnPhase>) -> HashSet<QualifiedName> {
+    let (simple_constructors, complex_constructors): (Vec<_>, Vec<_>) = apis
+        .iter()
+        .filter_map(|api| match api {
+            Api::Function { fun, .. } => match &fun.provenance {
+                Provenance::SynthesizedSubclassConstructor(details) => {
+                    Some((&details.subclass.0.name, details.is_trivial))
+                }
+                _ => None,
+            },
+            _ => None,
+        })
+        .partition(|(_, trivial)| *trivial);
+    let simple_constructors: HashSet<_> =
+        simple_constructors.into_iter().map(|(qn, _)| qn).collect();
+    let complex_constructors: HashSet<_> =
+        complex_constructors.into_iter().map(|(qn, _)| qn).collect();
+    (&simple_constructors - &complex_constructors)
+        .into_iter()
+        .cloned()
+        .collect()
+}
+
+fn find_non_pod_types(apis: &ApiVec<FnPhase>) -> HashSet<QualifiedName> {
+    apis.iter()
+        .filter_map(|api| match api {
+            Api::Struct {
+                name,
+                analysis:
+                    PodAndDepAnalysis {
+                        pod:
+                            PodAnalysis {
+                                kind: TypeKind::NonPod,
+                                ..
+                            },
+                        ..
+                    },
+                ..
+            } => Some(name.name.clone()),
+            _ => None,
+        })
+        .collect()
+}
+
+impl HasNs for (QualifiedName, RsCodegenResult) {
+    fn get_namespace(&self) -> &Namespace {
+        self.0.get_namespace()
+    }
+}
+
+impl<T: AnalysisPhase> HasNs for Api<T> {
+    fn get_namespace(&self) -> &Namespace {
+        self.name().get_namespace()
+    }
+}
+
+/// Snippets of code generated from a particular API.
+/// These are then concatenated together into the final generated code.
+#[derive(Default)]
+struct RsCodegenResult {
+    extern_c_mod_items: Vec<ForeignItem>,
+    extern_rust_mod_items: Vec<ForeignItem>,
+    bridge_items: Vec<Item>,
+    global_items: Vec<Item>,
+    bindgen_mod_items: Vec<Item>,
+    impl_entry: Option<Box<ImplBlockDetails>>,
+    trait_impl_entry: Option<Box<TraitImplBlockDetails>>,
+    materializations: Vec<Use>,
+}
+
+/// An [`Item`] that always needs to be in an unsafe block.
+#[derive(Clone)]
+enum MaybeUnsafeStmt {
+    // This could almost be a syn::Stmt, but that doesn't quite work
+    // because the last stmt in a function is actually an expression
+    // thus lacking a semicolon.
+    Normal(TokenStream),
+    NeedsUnsafe(TokenStream),
+    Binary {
+        in_safe_context: TokenStream,
+        in_unsafe_context: TokenStream,
+    },
+}
+
+impl MaybeUnsafeStmt {
+    fn new(stmt: TokenStream) -> Self {
+        Self::Normal(stmt)
+    }
+
+    fn needs_unsafe(stmt: TokenStream) -> Self {
+        Self::NeedsUnsafe(stmt)
+    }
+
+    fn maybe_unsafe(stmt: TokenStream, needs_unsafe: bool) -> Self {
+        if needs_unsafe {
+            Self::NeedsUnsafe(stmt)
+        } else {
+            Self::Normal(stmt)
+        }
+    }
+
+    fn binary(in_safe_context: TokenStream, in_unsafe_context: TokenStream) -> Self {
+        Self::Binary {
+            in_safe_context,
+            in_unsafe_context,
+        }
+    }
+}
+
+fn maybe_unsafes_to_tokens(
+    items: Vec<MaybeUnsafeStmt>,
+    context_is_already_unsafe: bool,
+) -> TokenStream {
+    if context_is_already_unsafe {
+        let items = items.into_iter().map(|item| match item {
+            MaybeUnsafeStmt::Normal(stmt)
+            | MaybeUnsafeStmt::NeedsUnsafe(stmt)
+            | MaybeUnsafeStmt::Binary {
+                in_unsafe_context: stmt,
+                ..
+            } => stmt,
+        });
+        quote! {
+            #(#items)*
+        }
+    } else {
+        let mut currently_unsafe_list = None;
+        let mut output = Vec::new();
+        for item in items {
+            match item {
+                MaybeUnsafeStmt::NeedsUnsafe(stmt) => {
+                    if currently_unsafe_list.is_none() {
+                        currently_unsafe_list = Some(Vec::new());
+                    }
+                    currently_unsafe_list.as_mut().unwrap().push(stmt);
+                }
+                MaybeUnsafeStmt::Normal(stmt)
+                | MaybeUnsafeStmt::Binary {
+                    in_safe_context: stmt,
+                    ..
+                } => {
+                    if let Some(currently_unsafe_list) = currently_unsafe_list.take() {
+                        output.push(quote! {
+                            unsafe {
+                                #(#currently_unsafe_list)*
+                            }
+                        })
+                    }
+                    output.push(stmt);
+                }
+            }
+        }
+        if let Some(currently_unsafe_list) = currently_unsafe_list.take() {
+            output.push(quote! {
+                unsafe {
+                    #(#currently_unsafe_list)*
+                }
+            })
+        }
+        quote! {
+            #(#output)*
+        }
+    }
+}
+
+#[test]
+fn test_maybe_unsafes_to_tokens() {
+    let items = vec![
+        MaybeUnsafeStmt::new(quote! { use A; }),
+        MaybeUnsafeStmt::new(quote! { use B; }),
+        MaybeUnsafeStmt::needs_unsafe(quote! { use C; }),
+        MaybeUnsafeStmt::needs_unsafe(quote! { use D; }),
+        MaybeUnsafeStmt::new(quote! { use E; }),
+        MaybeUnsafeStmt::needs_unsafe(quote! { use F; }),
+    ];
+    assert_eq!(
+        maybe_unsafes_to_tokens(items.clone(), false).to_string(),
+        quote! {
+            use A;
+            use B;
+            unsafe {
+                use C;
+                use D;
+            }
+            use E;
+            unsafe {
+                use F;
+            }
+        }
+        .to_string()
+    );
+    assert_eq!(
+        maybe_unsafes_to_tokens(items, true).to_string(),
+        quote! {
+            use A;
+            use B;
+            use C;
+            use D;
+            use E;
+            use F;
+        }
+        .to_string()
+    );
+}
diff --git a/engine/src/conversion/codegen_rs/namespace_organizer.rs b/engine/src/conversion/codegen_rs/namespace_organizer.rs
new file mode 100644
index 0000000..886cb1c
--- /dev/null
+++ b/engine/src/conversion/codegen_rs/namespace_organizer.rs
@@ -0,0 +1,136 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::types::Namespace;
+use std::collections::BTreeMap;
+
+pub trait HasNs {
+    fn get_namespace(&self) -> &Namespace;
+}
+
+pub struct NamespaceEntries<'a, T: HasNs> {
+    entries: Vec<&'a T>,
+    children: BTreeMap<&'a String, NamespaceEntries<'a, T>>,
+}
+
+impl<'a, T: HasNs> NamespaceEntries<'a, T> {
+    pub(crate) fn new(apis: &'a [T]) -> Self {
+        let api_refs = apis.iter().collect::<Vec<_>>();
+        Self::sort_by_inner_namespace(api_refs, 0)
+    }
+
+    pub(crate) fn is_empty(&self) -> bool {
+        self.entries.is_empty() && self.children.iter().all(|(_, child)| child.is_empty())
+    }
+
+    pub(crate) fn entries(&self) -> &[&'a T] {
+        &self.entries
+    }
+
+    pub(crate) fn children(&self) -> impl Iterator<Item = (&&String, &NamespaceEntries<T>)> {
+        self.children.iter()
+    }
+
+    fn sort_by_inner_namespace(apis: Vec<&'a T>, depth: usize) -> Self {
+        let mut root = NamespaceEntries {
+            entries: Vec::new(),
+            children: BTreeMap::new(),
+        };
+
+        let mut kids_by_child_ns = BTreeMap::new();
+        for api in apis {
+            let first_ns_elem = api.get_namespace().iter().nth(depth);
+            if let Some(first_ns_elem) = first_ns_elem {
+                let list = kids_by_child_ns
+                    .entry(first_ns_elem)
+                    .or_insert_with(Vec::new);
+                list.push(api);
+                continue;
+            }
+            root.entries.push(api);
+        }
+
+        for (k, v) in kids_by_child_ns.into_iter() {
+            root.children
+                .insert(k, Self::sort_by_inner_namespace(v, depth + 1));
+        }
+
+        root
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{HasNs, NamespaceEntries};
+    use crate::types::Namespace;
+
+    struct TestApi(&'static str, Namespace);
+    impl HasNs for TestApi {
+        fn get_namespace(&self) -> &Namespace {
+            &self.1
+        }
+    }
+
+    #[test]
+    fn test_ns_entries_sort() {
+        let entries = vec![
+            make_api(None, "C"),
+            make_api(None, "A"),
+            make_api(Some("G"), "E"),
+            make_api(Some("D"), "F"),
+            make_api(Some("G"), "H"),
+            make_api(Some("D::K"), "L"),
+            make_api(Some("D::K"), "M"),
+            make_api(None, "B"),
+            make_api(Some("D"), "I"),
+            make_api(Some("D"), "J"),
+        ];
+        let ns = NamespaceEntries::new(&entries);
+        let root_entries = ns.entries();
+        assert_eq!(root_entries.len(), 3);
+        assert_ident(root_entries[0], "C");
+        assert_ident(root_entries[1], "A");
+        assert_ident(root_entries[2], "B");
+        let mut kids = ns.children();
+        let (d_id, d_nse) = kids.next().unwrap();
+        assert_eq!(d_id.to_string(), "D");
+        let (g_id, g_nse) = kids.next().unwrap();
+        assert_eq!(g_id.to_string(), "G");
+        assert!(kids.next().is_none());
+        let d_nse_entries = d_nse.entries();
+        assert_eq!(d_nse_entries.len(), 3);
+        assert_ident(d_nse_entries[0], "F");
+        assert_ident(d_nse_entries[1], "I");
+        assert_ident(d_nse_entries[2], "J");
+        let g_nse_entries = g_nse.entries();
+        assert_eq!(g_nse_entries.len(), 2);
+        assert_ident(g_nse_entries[0], "E");
+        assert_ident(g_nse_entries[1], "H");
+        let mut g_kids = g_nse.children();
+        assert!(g_kids.next().is_none());
+        let mut d_kids = d_nse.children();
+        let (k_id, k_nse) = d_kids.next().unwrap();
+        assert_eq!(k_id.to_string(), "K");
+        let k_nse_entries = k_nse.entries();
+        assert_eq!(k_nse_entries.len(), 2);
+        assert_ident(k_nse_entries[0], "L");
+        assert_ident(k_nse_entries[1], "M");
+    }
+
+    fn assert_ident(api: &TestApi, expected: &str) {
+        assert_eq!(api.0, expected);
+    }
+
+    fn make_api(ns: Option<&str>, id: &'static str) -> TestApi {
+        let ns = match ns {
+            Some(st) => Namespace::from_user_input(st),
+            None => Namespace::new(),
+        };
+        TestApi(id, ns)
+    }
+}
diff --git a/engine/src/conversion/codegen_rs/non_pod_struct.rs b/engine/src/conversion/codegen_rs/non_pod_struct.rs
new file mode 100644
index 0000000..e4bec2f
--- /dev/null
+++ b/engine/src/conversion/codegen_rs/non_pod_struct.rs
@@ -0,0 +1,132 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::conversion::api::Layout;
+use crate::types::make_ident;
+use proc_macro2::{Ident, Span};
+use quote::quote;
+use syn::parse::Parser;
+use syn::punctuated::Punctuated;
+use syn::{parse_quote, Field, Fields, GenericParam, ItemStruct, LitInt};
+
+pub(crate) fn new_non_pod_struct(id: Ident) -> ItemStruct {
+    let mut s = parse_quote! {
+        pub struct #id {
+        }
+    };
+    make_non_pod(&mut s, None);
+    s
+}
+
+pub(crate) fn make_non_pod(s: &mut ItemStruct, layout: Option<Layout>) {
+    // Make an opaque struct. If we have layout information, we pass
+    // that through to Rust. We keep only doc attrs, plus add a #[repr(C)]
+    // if necessary.
+    // Constraints here (thanks to dtolnay@ for this explanation of why the
+    // following is needed:)
+    // (1) If the real alignment of the C++ type is smaller and a reference
+    // is returned from C++ to Rust, mere existence of an insufficiently
+    // aligned reference in Rust causes UB even if never dereferenced
+    // by Rust code
+    // (see https://doc.rust-lang.org/1.47.0/reference/behavior-considered-undefined.html).
+    // Rustc can use least-significant bits of the reference for other storage.
+    // (if we have layout information from bindgen we use that instead)
+    // (2) We want to ensure the type is !Unpin
+    // (3) We want to ensure it's not Send or Sync
+    //
+    // For opaque types, the Rusty opaque structure could in fact be generated
+    // by three different things:
+    // a) bindgen, using its --opaque-type command line argument or the library
+    //    equivalent;
+    // b) us (autocxx), which is what this code does
+    // c) cxx, using "type B;" in an "extern "C++"" section
+    // We never use (a) because bindgen requires an allowlist of opaque types.
+    // Furthermore, it sometimes then discards struct definitions entirely
+    // and says "type A = [u8;2];" or something else which makes our life
+    // much more difficult.
+    // We use (c) for abstract types. For everything else, we do it ourselves
+    // for maximal control. See codegen_rs/mod.rs generate_type for more notes.
+    // First work out attributes.
+    let doc_attr = s
+        .attrs
+        .iter()
+        .filter(|a| a.path.get_ident().iter().any(|p| *p == "doc"))
+        .cloned();
+    let repr_attr = if let Some(layout) = &layout {
+        let align = make_lit_int(layout.align);
+        if layout.packed {
+            parse_quote! {
+                #[repr(C,align(#align),packed)]
+            }
+        } else {
+            parse_quote! {
+                #[repr(C,align(#align))]
+            }
+        }
+    } else {
+        parse_quote! {
+            #[repr(C, packed)]
+        }
+    };
+    let attrs = doc_attr.chain(std::iter::once(repr_attr));
+    s.attrs = attrs.collect();
+    // Now fill in fields. Usually, we just want a single field
+    // but if this is a generic type we need to faff a bit.
+    let generic_type_fields = s
+        .generics
+        .params
+        .iter()
+        .enumerate()
+        .filter_map(|(counter, gp)| match gp {
+            GenericParam::Type(gpt) => {
+                let id = &gpt.ident;
+                let field_name = make_ident(&format!("_phantom_{}", counter));
+                let toks = quote! {
+                    #field_name: ::std::marker::PhantomData<::std::cell::UnsafeCell< #id >>
+                };
+                Some(Field::parse_named.parse2(toks).unwrap())
+            }
+            _ => None,
+        });
+    let data_field = if let Some(layout) = layout {
+        let size = make_lit_int(layout.size);
+        Some(
+            syn::Field::parse_named
+                .parse2(quote! {
+                    _data: [u8; #size]
+                })
+                .unwrap(),
+        )
+    } else {
+        None
+    }
+    .into_iter();
+    let pin_field = syn::Field::parse_named
+        .parse2(quote! {
+            _pinned: core::marker::PhantomData<core::marker::PhantomPinned>
+        })
+        .unwrap();
+
+    let non_send_sync_field = syn::Field::parse_named
+        .parse2(quote! {
+            _non_send_sync: core::marker::PhantomData<[*const u8;0]>
+        })
+        .unwrap();
+    let all_fields: Punctuated<_, syn::token::Comma> = std::iter::once(pin_field)
+        .chain(std::iter::once(non_send_sync_field))
+        .chain(generic_type_fields)
+        .chain(data_field)
+        .collect();
+    s.fields = Fields::Named(parse_quote! { {
+        #all_fields
+    } })
+}
+
+fn make_lit_int(val: usize) -> LitInt {
+    LitInt::new(&val.to_string(), Span::call_site())
+}
diff --git a/engine/src/conversion/codegen_rs/unqualify.rs b/engine/src/conversion/codegen_rs/unqualify.rs
new file mode 100644
index 0000000..6f245c2
--- /dev/null
+++ b/engine/src/conversion/codegen_rs/unqualify.rs
@@ -0,0 +1,94 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use syn::{
+    parse_quote, punctuated::Punctuated, FnArg, GenericArgument, PathArguments, PathSegment,
+    ReturnType, Token, Type, TypePath,
+};
+
+/// Mod to handle stripping paths off the front of types.
+
+fn unqualify_type_path(typ: TypePath) -> TypePath {
+    // If we've still got more than one
+    // path segment then this is referring to a type within
+    // C++ namespaces. Strip them off for now, until cxx supports
+    // nested mods within a cxx::bridge.
+    // This is 'safe' because earlier code will already have
+    // failed with 'DuplicateType' if we had several types called
+    // the same thing.
+    let last_seg = typ.path.segments.into_iter().last().unwrap();
+    let ident = &last_seg.ident;
+    let args = match last_seg.arguments {
+        PathArguments::AngleBracketed(mut ab) => {
+            ab.args = unqualify_punctuated(ab.args);
+            PathArguments::AngleBracketed(ab)
+        }
+        _ => last_seg.arguments.clone(),
+    };
+    let last_seg: PathSegment = parse_quote!( #ident #args );
+    parse_quote!(
+        #last_seg
+    )
+}
+
+fn unqualify_punctuated<P>(pun: Punctuated<GenericArgument, P>) -> Punctuated<GenericArgument, P>
+where
+    P: Default,
+{
+    let mut new_pun = Punctuated::new();
+    for arg in pun.into_iter() {
+        new_pun.push(match arg {
+            GenericArgument::Type(t) => GenericArgument::Type(unqualify_type(t)),
+            _ => arg,
+        });
+    }
+    new_pun
+}
+
+fn unqualify_type(typ: Type) -> Type {
+    match typ {
+        Type::Path(typ) => Type::Path(unqualify_type_path(typ)),
+        Type::Reference(mut typeref) => {
+            typeref.elem = unqualify_boxed_type(typeref.elem);
+            Type::Reference(typeref)
+        }
+        Type::Ptr(mut typeptr) => {
+            typeptr.elem = unqualify_boxed_type(typeptr.elem);
+            Type::Ptr(typeptr)
+        }
+        _ => typ,
+    }
+}
+
+fn unqualify_boxed_type(typ: Box<Type>) -> Box<Type> {
+    Box::new(unqualify_type(*typ))
+}
+
+pub(crate) fn unqualify_ret_type(ret_type: ReturnType) -> ReturnType {
+    match ret_type {
+        ReturnType::Type(tok, boxed_type) => {
+            ReturnType::Type(tok, unqualify_boxed_type(boxed_type))
+        }
+        _ => ret_type,
+    }
+}
+
+pub(crate) fn unqualify_params(
+    params: Punctuated<FnArg, Token![,]>,
+) -> Punctuated<FnArg, Token![,]> {
+    params
+        .into_iter()
+        .map(|p| match p {
+            FnArg::Typed(mut pt) => {
+                pt.ty = unqualify_boxed_type(pt.ty);
+                FnArg::Typed(pt)
+            }
+            _ => p,
+        })
+        .collect()
+}
diff --git a/engine/src/conversion/conversion_tests.rs b/engine/src/conversion/conversion_tests.rs
new file mode 100644
index 0000000..b0474d6
--- /dev/null
+++ b/engine/src/conversion/conversion_tests.rs
@@ -0,0 +1,46 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use autocxx_parser::UnsafePolicy;
+#[allow(unused_imports)]
+use syn::parse_quote;
+use syn::ItemMod;
+
+use crate::CppCodegenOptions;
+
+use super::BridgeConverter;
+
+// This mod is for tests which take bindgen output directly.
+// This should be avoided where possible, since these tests will
+// become obsolete or have to change if and when we update
+// bindgen. Instead, please add tests working directly from
+// the original C++ in integration_tests.rs if possible.
+// Also, if you're pasting in code from github issues, it's
+// important to make sure that the underlying code has an
+// acceptable license. That's why this file is currently blank.
+
+#[allow(dead_code)]
+fn do_test(input: ItemMod) {
+    let tc = parse_quote! {};
+    let bc = BridgeConverter::new(&[], &tc);
+    let inclusions = "".into();
+    bc.convert(
+        input,
+        UnsafePolicy::AllFunctionsSafe,
+        inclusions,
+        &CppCodegenOptions::default(),
+    )
+    .unwrap();
+}
+
+// How to add a test here
+//
+// #[test]
+// fn test_xyz() {
+//      do_test(parse_quote!{ /* paste bindgen output here */})
+// }
diff --git a/engine/src/conversion/convert_error.rs b/engine/src/conversion/convert_error.rs
new file mode 100644
index 0000000..0de4f19
--- /dev/null
+++ b/engine/src/conversion/convert_error.rs
@@ -0,0 +1,218 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::set::IndexSet as HashSet;
+
+use itertools::Itertools;
+use syn::Ident;
+use thiserror::Error;
+
+use crate::{
+    known_types,
+    types::{make_ident, Namespace, QualifiedName},
+};
+
+#[derive(Debug, Clone, Error)]
+pub enum ConvertError {
+    #[error("The initial run of 'bindgen' did not generate any content. This might be because none of the requested items for generation could be converted.")]
+    NoContent,
+    #[error("An item was requested using 'generate_pod' which was not safe to hold by value in Rust. {0}")]
+    UnsafePodType(String),
+    #[error("Bindgen generated some unexpected code in a foreign mod section. You may have specified something in a 'generate' directive which is not currently compatible with autocxx.")]
+    UnexpectedForeignItem,
+    #[error("Bindgen generated some unexpected code in its outermost mod section. You may have specified something in a 'generate' directive which is not currently compatible with autocxx.")]
+    UnexpectedOuterItem,
+    #[error("Bindgen generated some unexpected code in an inner namespace mod. You may have specified something in a 'generate' directive which is not currently compatible with autocxx.")]
+    UnexpectedItemInMod,
+    #[error("autocxx was unable to produce a typdef pointing to the complex type {0}.")]
+    ComplexTypedefTarget(String),
+    #[error("Unexpected type for 'this' in the function {}.", .0.to_cpp_name())]
+    UnexpectedThisType(QualifiedName),
+    #[error("autocxx does not yet know how to support the built-in C++ type {} - please raise an issue on github", .0.to_cpp_name())]
+    UnsupportedBuiltInType(QualifiedName),
+    #[error("Type {} has templated arguments and so does the typedef to which it points", .0.to_cpp_name())]
+    ConflictingTemplatedArgsWithTypedef(QualifiedName),
+    #[error("Function {0} has a parameter or return type which is either on the blocklist or a forward declaration")]
+    UnacceptableParam(String),
+    #[error("Function {0} has a return reference parameter, but 0 or >1 input reference parameters, so the lifetime of the output reference cannot be deduced.")]
+    NotOneInputReference(String),
+    #[error("Encountered type not yet supported by autocxx: {0}")]
+    UnsupportedType(String),
+    #[error("Encountered type not yet known by autocxx: {0}")]
+    UnknownType(String),
+    #[error("Encountered mutable static data, not yet supported: {0}")]
+    StaticData(String),
+    #[error("Encountered typedef to itself - this is a known bindgen bug: {0}")]
+    InfinitelyRecursiveTypedef(QualifiedName),
+    #[error("Unexpected 'use' statement encountered: {}", .0.as_ref().map(|s| s.as_str()).unwrap_or("<unknown>"))]
+    UnexpectedUseStatement(Option<String>),
+    #[error("Type {} was parameterized over something complex which we don't yet support", .0.to_cpp_name())]
+    TemplatedTypeContainingNonPathArg(QualifiedName),
+    #[error("Pointer pointed to something unsupported")]
+    InvalidPointee,
+    #[error("The 'generate' or 'generate_pod' directive for '{0}' did not result in any code being generated. Perhaps this was mis-spelled or you didn't qualify the name with any namespaces? Otherwise please report a bug.")]
+    DidNotGenerateAnything(String),
+    #[error("Found an attempt at using a forward declaration ({}) inside a templated cxx type such as UniquePtr or CxxVector. If the forward declaration is a typedef, perhaps autocxx wasn't sure whether or not it involved a forward declaration. If you're sure it didn't, then you may be able to solve this by using instantiable!.", .0.to_cpp_name())]
+    TypeContainingForwardDeclaration(QualifiedName),
+    #[error("Found an attempt at using a type marked as blocked! ({})", .0.to_cpp_name())]
+    Blocked(QualifiedName),
+    #[error("This function or method uses a type where one of the template parameters was incomprehensible to bindgen/autocxx - probably because it uses template specialization.")]
+    UnusedTemplateParam,
+    #[error("Names containing __ are reserved by C++ so not acceptable to cxx")]
+    TooManyUnderscores,
+    #[error("This item relies on a type not known to autocxx ({})", .0.to_cpp_name())]
+    UnknownDependentType(QualifiedName),
+    #[error("This item depends on some other type(s) which autocxx could not generate, some of them are: {}", .0.iter().join(", "))]
+    IgnoredDependent(HashSet<QualifiedName>),
+    #[error("The item name '{0}' is a reserved word in Rust.")]
+    ReservedName(String),
+    #[error("This item name is used in multiple namespaces. At present, autocxx and cxx allow only one type of a given name. This limitation will be fixed in future. (Items found with this name: {})", .0.iter().join(", "))]
+    DuplicateCxxBridgeName(Vec<String>),
+    #[error("This is a method on a type which can't be used as the receiver in Rust (i.e. self/this). This is probably because some type involves template specialization.")]
+    UnsupportedReceiver,
+    #[error("A rust::Box<T> was encountered where T was not known to be a Rust type. Use rust_type!(T): {}", .0.to_cpp_name())]
+    BoxContainingNonRustType(QualifiedName),
+    #[error("A qualified Rust type was found (i.e. one containing ::): {}. Rust types must always be a simple identifier.", .0.to_cpp_name())]
+    RustTypeWithAPath(QualifiedName),
+    #[error("This type is nested within another struct/class, yet is abstract (or is not on the allowlist so we can't be sure). This is not yet supported by autocxx. If you don't believe this type is abstract, add it to the allowlist.")]
+    AbstractNestedType,
+    #[error("This typedef was nested within another struct/class. autocxx is unable to represent inner types if they might be abstract. Unfortunately, autocxx couldn't prove that this type isn't abstract, so it can't represent it.")]
+    NestedOpaqueTypedef,
+    #[error(
+        "This type is nested within another struct/class with protected or private visibility."
+    )]
+    NonPublicNestedType,
+    #[error("This function returns an rvalue reference (&&) which is not yet supported.")]
+    RValueReturn,
+    #[error("This method is private")]
+    PrivateMethod,
+    #[error("autocxx does not know how to generate bindings to operator=")]
+    AssignmentOperator,
+    #[error("This function was marked =delete")]
+    Deleted,
+    #[error("This structure has an rvalue reference field (&&) which is not yet supported.")]
+    RValueReferenceField,
+    #[error("This type was not on the allowlist, so we are not generating methods for it.")]
+    MethodOfNonAllowlistedType,
+    #[error("This type is templated, so we can't generate bindings. We will instead generate bindings for each instantiation.")]
+    MethodOfGenericType,
+    #[error("bindgen generated multiple different APIs (functions/types) with this name. autocxx doesn't know how to disambiguate them, so we won't generate bindings for any of them.")]
+    DuplicateItemsFoundInParsing,
+    #[error(
+        "bindgen generated a move or copy constructor with an unexpected number of parameters."
+    )]
+    ConstructorWithOnlyOneParam,
+    #[error("A copy or move constructor was found to take extra parameters. These are likely to be parameters with defaults, which are not yet supported by autocxx, so this constructor has been ignored.")]
+    ConstructorWithMultipleParams,
+    #[error("A C++ unique_ptr, shared_ptr or weak_ptr was found containing some type that cxx can't accommodate in that position ({})", .0.to_cpp_name())]
+    InvalidTypeForCppPtr(QualifiedName),
+    #[error("A C++ std::vector was found containing some type that cxx can't accommodate as a vector element ({})", .0.to_cpp_name())]
+    InvalidTypeForCppVector(QualifiedName),
+    #[error("Variadic functions are not supported by cxx or autocxx.")]
+    Variadic,
+    #[error("A type had a template inside a std::vector, which is not supported.")]
+    GenericsWithinVector,
+    #[error("This typedef takes generic parameters, not yet supported by autocxx.")]
+    TypedefTakesGenericParameters,
+    #[error("This method belonged to an item in an anonymous namespace, not currently supported.")]
+    MethodInAnonymousNamespace,
+    #[error("We're unable to make a concrete version of this template, because we found an error handling the template.")]
+    ConcreteVersionOfIgnoredTemplate,
+    #[error("bindgen decided to call this type _bindgen_ty_N because it couldn't deduce the correct name for it. That means we can't generate C++ bindings to it.")]
+    BindgenTy,
+}
+
+/// Ensures that error contexts are always created using the constructors in this
+/// mod, therefore undergoing identifier sanitation.
+#[derive(Clone)]
+struct PhantomSanitized;
+
+/// The context of an error, e.g. whether it applies to a function or a method.
+/// This is used to generate suitable rustdoc in the output codegen so that
+/// the errors can be revealed in rust-analyzer-based IDEs, etc.
+#[derive(Clone)]
+pub(crate) struct ErrorContext(ErrorContextType, PhantomSanitized);
+
+/// All idents in this structure are guaranteed to be something we can safely codegen for.
+#[derive(Clone)]
+pub(crate) enum ErrorContextType {
+    Item(Ident),
+    SanitizedItem(Ident),
+    Method { self_ty: Ident, method: Ident },
+}
+
+impl ErrorContext {
+    pub(crate) fn new_for_item(id: Ident) -> Self {
+        match Self::sanitize_error_ident(&id) {
+            None => Self(ErrorContextType::Item(id), PhantomSanitized),
+            Some(sanitized) => Self(ErrorContextType::SanitizedItem(sanitized), PhantomSanitized),
+        }
+    }
+
+    pub(crate) fn new_for_method(self_ty: Ident, method: Ident) -> Self {
+        // If this IgnoredItem relates to a method on a self_ty which we can't represent,
+        // e.g. u8, then forget about trying to attach this error text to something within
+        // an impl block.
+        match Self::sanitize_error_ident(&self_ty) {
+            None => Self(
+                ErrorContextType::Method {
+                    self_ty,
+                    method: Self::sanitize_error_ident(&method).unwrap_or(method),
+                },
+                PhantomSanitized,
+            ),
+            Some(_) => Self(
+                ErrorContextType::SanitizedItem(make_ident(format!("{}_{}", self_ty, method))),
+                PhantomSanitized,
+            ),
+        }
+    }
+
+    /// Because errors may be generated for invalid types or identifiers,
+    /// we may need to scrub the name
+    fn sanitize_error_ident(id: &Ident) -> Option<Ident> {
+        let qn = QualifiedName::new(&Namespace::new(), id.clone());
+        if known_types().conflicts_with_built_in_type(&qn) {
+            Some(make_ident(format!("{}_autocxx_error", qn.get_final_item())))
+        } else {
+            None
+        }
+    }
+
+    pub(crate) fn get_type(&self) -> &ErrorContextType {
+        &self.0
+    }
+
+    pub(crate) fn into_type(self) -> ErrorContextType {
+        self.0
+    }
+}
+
+impl std::fmt::Display for ErrorContext {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match &self.0 {
+            ErrorContextType::Item(id) | ErrorContextType::SanitizedItem(id) => write!(f, "{}", id),
+            ErrorContextType::Method { self_ty, method } => write!(f, "{}::{}", self_ty, method),
+        }
+    }
+}
+
+#[derive(Clone)]
+pub(crate) struct ConvertErrorWithContext(pub(crate) ConvertError, pub(crate) Option<ErrorContext>);
+
+impl std::fmt::Debug for ConvertErrorWithContext {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+impl std::fmt::Display for ConvertErrorWithContext {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
diff --git a/engine/src/conversion/doc_attr.rs b/engine/src/conversion/doc_attr.rs
new file mode 100644
index 0000000..8fe9d0b
--- /dev/null
+++ b/engine/src/conversion/doc_attr.rs
@@ -0,0 +1,18 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use syn::Attribute;
+
+/// Returns the attribute (if any) which contains a doc comment.
+pub(super) fn get_doc_attrs(attrs: &[Attribute]) -> Vec<Attribute> {
+    attrs
+        .iter()
+        .filter(|a| a.path.get_ident().iter().any(|p| *p == "doc"))
+        .cloned()
+        .collect()
+}
diff --git a/engine/src/conversion/error_reporter.rs b/engine/src/conversion/error_reporter.rs
new file mode 100644
index 0000000..7942a32
--- /dev/null
+++ b/engine/src/conversion/error_reporter.rs
@@ -0,0 +1,225 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use syn::ItemEnum;
+
+use super::{
+    api::{AnalysisPhase, Api, ApiName, FuncToConvert, StructDetails, TypedefKind},
+    apivec::ApiVec,
+    convert_error::{ConvertErrorWithContext, ErrorContext},
+    ConvertError,
+};
+use crate::{
+    conversion::convert_error::ErrorContextType,
+    types::{Namespace, QualifiedName},
+};
+
+/// Run some code which may generate a ConvertError.
+/// If it does, try to note the problem in our output APIs
+/// such that users will see documentation of the error.
+pub(crate) fn report_any_error<F, T>(
+    ns: &Namespace,
+    apis: &mut ApiVec<impl AnalysisPhase>,
+    fun: F,
+) -> Option<T>
+where
+    F: FnOnce() -> Result<T, ConvertErrorWithContext>,
+{
+    match fun() {
+        Ok(result) => Some(result),
+        Err(ConvertErrorWithContext(err, None)) => {
+            eprintln!("Ignored item: {}", err);
+            None
+        }
+        Err(ConvertErrorWithContext(err, Some(ctx))) => {
+            let id = match ctx.get_type() {
+                ErrorContextType::Item(id) | ErrorContextType::SanitizedItem(id) => id,
+                ErrorContextType::Method { self_ty, .. } => self_ty,
+            };
+            let name = ApiName::new_from_qualified_name(QualifiedName::new(ns, id.clone()));
+            apis.push(Api::IgnoredItem {
+                name,
+                err,
+                ctx: Some(ctx),
+            });
+            None
+        }
+    }
+}
+
+/// Run some code which generates an API. Add that API, or if
+/// anything goes wrong, instead add a note of the problem in our
+/// output API such that users will see documentation for the problem.
+pub(crate) fn convert_apis<FF, SF, EF, TF, A, B: 'static>(
+    in_apis: ApiVec<A>,
+    out_apis: &mut ApiVec<B>,
+    mut func_conversion: FF,
+    mut struct_conversion: SF,
+    mut enum_conversion: EF,
+    mut typedef_conversion: TF,
+) where
+    A: AnalysisPhase,
+    B: AnalysisPhase,
+    FF: FnMut(
+        ApiName,
+        Box<FuncToConvert>,
+        A::FunAnalysis,
+    ) -> Result<Box<dyn Iterator<Item = Api<B>>>, ConvertErrorWithContext>,
+    SF: FnMut(
+        ApiName,
+        Box<StructDetails>,
+        A::StructAnalysis,
+    ) -> Result<Box<dyn Iterator<Item = Api<B>>>, ConvertErrorWithContext>,
+    EF: FnMut(
+        ApiName,
+        ItemEnum,
+    ) -> Result<Box<dyn Iterator<Item = Api<B>>>, ConvertErrorWithContext>,
+    TF: FnMut(
+        ApiName,
+        TypedefKind,
+        Option<QualifiedName>,
+        A::TypedefAnalysis,
+    ) -> Result<Box<dyn Iterator<Item = Api<B>>>, ConvertErrorWithContext>,
+{
+    out_apis.extend(in_apis.into_iter().flat_map(|api| {
+        let fullname = api.name_info().clone();
+        let result: Result<Box<dyn Iterator<Item = Api<B>>>, ConvertErrorWithContext> = match api {
+            // No changes to any of these...
+            Api::ConcreteType {
+                name,
+                rs_definition,
+                cpp_definition,
+            } => Ok(Box::new(std::iter::once(Api::ConcreteType {
+                name,
+                rs_definition,
+                cpp_definition,
+            }))),
+            Api::ForwardDeclaration { name, err } => {
+                Ok(Box::new(std::iter::once(Api::ForwardDeclaration {
+                    name,
+                    err,
+                })))
+            }
+            Api::OpaqueTypedef {
+                name,
+                forward_declaration,
+            } => Ok(Box::new(std::iter::once(Api::OpaqueTypedef {
+                name,
+                forward_declaration,
+            }))),
+            Api::StringConstructor { name } => {
+                Ok(Box::new(std::iter::once(Api::StringConstructor { name })))
+            }
+            Api::Const { name, const_item } => {
+                Ok(Box::new(std::iter::once(Api::Const { name, const_item })))
+            }
+            Api::CType { name, typename } => {
+                Ok(Box::new(std::iter::once(Api::CType { name, typename })))
+            }
+            Api::RustType { name, path } => {
+                Ok(Box::new(std::iter::once(Api::RustType { name, path })))
+            }
+            Api::RustFn {
+                name,
+                details,
+                receiver,
+            } => Ok(Box::new(std::iter::once(Api::RustFn {
+                name,
+                details,
+                receiver,
+            }))),
+            Api::RustSubclassFn {
+                name,
+                subclass,
+                details,
+            } => Ok(Box::new(std::iter::once(Api::RustSubclassFn {
+                name,
+                subclass,
+                details,
+            }))),
+            Api::Subclass { name, superclass } => Ok(Box::new(std::iter::once(Api::Subclass {
+                name,
+                superclass,
+            }))),
+            Api::IgnoredItem { name, err, ctx } => {
+                Ok(Box::new(std::iter::once(Api::IgnoredItem {
+                    name,
+                    err,
+                    ctx,
+                })))
+            }
+            Api::SubclassTraitItem { name, details } => {
+                Ok(Box::new(std::iter::once(Api::SubclassTraitItem {
+                    name,
+                    details,
+                })))
+            }
+            Api::ExternCppType { name, details, pod } => {
+                Ok(Box::new(std::iter::once(Api::ExternCppType {
+                    name,
+                    details,
+                    pod,
+                })))
+            }
+            // Apply a mapping to the following
+            Api::Enum { name, item } => enum_conversion(name, item),
+            Api::Typedef {
+                name,
+                item,
+                old_tyname,
+                analysis,
+            } => typedef_conversion(name, item, old_tyname, analysis),
+            Api::Function {
+                name,
+                fun,
+                analysis,
+            } => func_conversion(name, fun, analysis),
+            Api::Struct {
+                name,
+                details,
+                analysis,
+            } => struct_conversion(name, details, analysis),
+        };
+        api_or_error(fullname, result)
+    }))
+}
+
+fn api_or_error<T: AnalysisPhase + 'static>(
+    name: ApiName,
+    api_or_error: Result<Box<dyn Iterator<Item = Api<T>>>, ConvertErrorWithContext>,
+) -> Box<dyn Iterator<Item = Api<T>>> {
+    match api_or_error {
+        Ok(opt) => opt,
+        Err(ConvertErrorWithContext(err, ctx)) => {
+            Box::new(std::iter::once(Api::IgnoredItem { name, err, ctx }))
+        }
+    }
+}
+
+/// Run some code which generates an API for an item (as opposed to
+/// a method). Add that API, or if
+/// anything goes wrong, instead add a note of the problem in our
+/// output API such that users will see documentation for the problem.
+pub(crate) fn convert_item_apis<F, A, B: 'static>(
+    in_apis: ApiVec<A>,
+    out_apis: &mut ApiVec<B>,
+    mut fun: F,
+) where
+    F: FnMut(Api<A>) -> Result<Box<dyn Iterator<Item = Api<B>>>, ConvertError>,
+    A: AnalysisPhase,
+    B: AnalysisPhase,
+{
+    out_apis.extend(in_apis.into_iter().flat_map(|api| {
+        let fullname = api.name_info().clone();
+        let tn = api.name().clone();
+        let result = fun(api).map_err(|e| {
+            ConvertErrorWithContext(e, Some(ErrorContext::new_for_item(tn.get_final_ident())))
+        });
+        api_or_error(fullname, result)
+    }))
+}
diff --git a/engine/src/conversion/mod.rs b/engine/src/conversion/mod.rs
new file mode 100644
index 0000000..3043dcf
--- /dev/null
+++ b/engine/src/conversion/mod.rs
@@ -0,0 +1,213 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod analysis;
+mod api;
+mod apivec;
+mod codegen_cpp;
+mod codegen_rs;
+#[cfg(test)]
+mod conversion_tests;
+mod convert_error;
+mod doc_attr;
+mod error_reporter;
+mod parse;
+mod utilities;
+
+use analysis::fun::FnAnalyzer;
+use autocxx_parser::IncludeCppConfig;
+pub(crate) use codegen_cpp::CppCodeGenerator;
+pub(crate) use convert_error::ConvertError;
+use itertools::Itertools;
+use syn::{Item, ItemMod};
+
+use crate::{
+    conversion::analysis::deps::HasDependencies, CppCodegenOptions, CppFilePair, UnsafePolicy,
+};
+
+use self::{
+    analysis::{
+        abstract_types::{discard_ignored_functions, mark_types_abstract},
+        allocators::create_alloc_and_frees,
+        casts::add_casts,
+        check_names,
+        constructor_deps::decorate_types_with_constructor_deps,
+        fun::FnPhase,
+        gc::filter_apis_by_following_edges_from_allowlist,
+        pod::analyze_pod_apis,
+        remove_ignored::filter_apis_by_ignored_dependents,
+        replace_hopeless_typedef_targets,
+        tdef::convert_typedef_targets,
+    },
+    api::AnalysisPhase,
+    apivec::ApiVec,
+    codegen_rs::RsCodeGenerator,
+    parse::ParseBindgen,
+};
+
+const LOG_APIS: bool = true;
+
+/// Converts the bindings generated by bindgen into a form suitable
+/// for use with `cxx`.
+/// In fact, most of the actual operation happens within an
+/// individual `BridgeConversion`.
+///
+/// # Flexibility in handling bindgen output
+///
+/// autocxx is inevitably tied to the details of the bindgen output;
+/// e.g. the creation of a 'root' mod when namespaces are enabled.
+/// At the moment this crate takes the view that it's OK to panic
+/// if the bindgen output is not as expected. It may be in future that
+/// we need to be a bit more graceful, but for now, that's OK.
+pub(crate) struct BridgeConverter<'a> {
+    include_list: &'a [String],
+    config: &'a IncludeCppConfig,
+}
+
+/// C++ and Rust code generation output.
+pub(crate) struct CodegenResults {
+    pub(crate) rs: Vec<Item>,
+    pub(crate) cpp: Option<CppFilePair>,
+    pub(crate) cxxgen_header_name: String,
+}
+
+impl<'a> BridgeConverter<'a> {
+    pub fn new(include_list: &'a [String], config: &'a IncludeCppConfig) -> Self {
+        Self {
+            include_list,
+            config,
+        }
+    }
+
+    fn dump_apis<T: AnalysisPhase>(label: &str, apis: &ApiVec<T>) {
+        if LOG_APIS {
+            log::info!(
+                "APIs after {}:\n{}",
+                label,
+                apis.iter()
+                    .map(|api| { format!("  {:?}", api) })
+                    .sorted()
+                    .join("\n")
+            )
+        }
+    }
+
+    fn dump_apis_with_deps(label: &str, apis: &ApiVec<FnPhase>) {
+        if LOG_APIS {
+            log::info!(
+                "APIs after {}:\n{}",
+                label,
+                apis.iter()
+                    .map(|api| { format!("  {:?}, deps={}", api, api.format_deps()) })
+                    .sorted()
+                    .join("\n")
+            )
+        }
+    }
+
+    /// Convert a TokenStream of bindgen-generated bindings to a form
+    /// suitable for cxx.
+    ///
+    /// This is really the heart of autocxx. It parses the output of `bindgen`
+    /// (although really by "parse" we mean to interpret the structures already built
+    /// up by the `syn` crate).
+    pub(crate) fn convert(
+        &self,
+        mut bindgen_mod: ItemMod,
+        unsafe_policy: UnsafePolicy,
+        inclusions: String,
+        cpp_codegen_options: &CppCodegenOptions,
+    ) -> Result<CodegenResults, ConvertError> {
+        match &mut bindgen_mod.content {
+            None => Err(ConvertError::NoContent),
+            Some((_, items)) => {
+                // Parse the bindgen mod.
+                let items_to_process = items.drain(..).collect();
+                let parser = ParseBindgen::new(self.config);
+                let apis = parser.parse_items(items_to_process)?;
+                Self::dump_apis("parsing", &apis);
+                // Inside parse_results, we now have a list of APIs.
+                // We now enter various analysis phases.
+                // Next, convert any typedefs.
+                // "Convert" means replacing bindgen-style type targets
+                // (e.g. root::std::unique_ptr) with cxx-style targets (e.g. UniquePtr).
+                let apis = convert_typedef_targets(self.config, apis);
+                Self::dump_apis("typedefs", &apis);
+                // Now analyze which of them can be POD (i.e. trivial, movable, pass-by-value
+                // versus which need to be opaque).
+                // Specifically, let's confirm that the items requested by the user to be
+                // POD really are POD, and duly mark any dependent types.
+                // This returns a new list of `Api`s, which will be parameterized with
+                // the analysis results. It also returns an object which can be used
+                // by subsequent phases to work out which objects are POD.
+                let analyzed_apis = analyze_pod_apis(apis, self.config)?;
+                Self::dump_apis("pod analysis", &analyzed_apis);
+                let analyzed_apis = replace_hopeless_typedef_targets(self.config, analyzed_apis);
+                let analyzed_apis = add_casts(analyzed_apis);
+                let analyzed_apis = create_alloc_and_frees(analyzed_apis);
+                // Next, figure out how we materialize different functions.
+                // Some will be simple entries in the cxx::bridge module; others will
+                // require C++ wrapper functions. This is probably the most complex
+                // part of `autocxx`. Again, this returns a new set of `Api`s, but
+                // parameterized by a richer set of metadata.
+                Self::dump_apis("adding casts", &analyzed_apis);
+                let analyzed_apis =
+                    FnAnalyzer::analyze_functions(analyzed_apis, unsafe_policy, self.config);
+                // If any of those functions turned out to be pure virtual, don't attempt
+                // to generate UniquePtr implementations for the type, since it can't
+                // be instantiated.
+                Self::dump_apis("analyze fns", &analyzed_apis);
+                let analyzed_apis = mark_types_abstract(analyzed_apis);
+                Self::dump_apis("marking abstract", &analyzed_apis);
+                // Annotate structs with a note of any copy/move constructors which
+                // we may want to retain to avoid garbage collecting them later.
+                let analyzed_apis = decorate_types_with_constructor_deps(analyzed_apis);
+                Self::dump_apis_with_deps("adding constructor deps", &analyzed_apis);
+                let analyzed_apis = discard_ignored_functions(analyzed_apis);
+                Self::dump_apis_with_deps("ignoring ignorable fns", &analyzed_apis);
+                // Remove any APIs whose names are not compatible with cxx.
+                let analyzed_apis = check_names(analyzed_apis);
+                // During parsing or subsequent processing we might have encountered
+                // items which we couldn't process due to as-yet-unsupported features.
+                // There might be other items depending on such things. Let's remove them
+                // too.
+                let analyzed_apis = filter_apis_by_ignored_dependents(analyzed_apis);
+                Self::dump_apis_with_deps("removing ignored dependents", &analyzed_apis);
+
+                // We now garbage collect the ones we don't need...
+                let mut analyzed_apis =
+                    filter_apis_by_following_edges_from_allowlist(analyzed_apis, self.config);
+                // Determine what variably-sized C types (e.g. int) we need to include
+                analysis::ctypes::append_ctype_information(&mut analyzed_apis);
+                Self::dump_apis_with_deps("GC", &analyzed_apis);
+                // And finally pass them to the code gen phases, which outputs
+                // code suitable for cxx to consume.
+                let cxxgen_header_name = cpp_codegen_options.cxxgen_header_namer.name_header();
+                let cpp = CppCodeGenerator::generate_cpp_code(
+                    inclusions,
+                    &analyzed_apis,
+                    self.config,
+                    cpp_codegen_options,
+                    &cxxgen_header_name,
+                )?;
+                let rs = RsCodeGenerator::generate_rs_code(
+                    analyzed_apis,
+                    self.include_list,
+                    bindgen_mod,
+                    self.config,
+                    cpp.as_ref().map(|file_pair| file_pair.header_name.clone()),
+                );
+                Ok(CodegenResults {
+                    rs,
+                    cpp,
+                    cxxgen_header_name,
+                })
+            }
+        }
+    }
+}
diff --git a/engine/src/conversion/parse/bindgen_semantic_attributes.rs b/engine/src/conversion/parse/bindgen_semantic_attributes.rs
new file mode 100644
index 0000000..8b789ae
--- /dev/null
+++ b/engine/src/conversion/parse/bindgen_semantic_attributes.rs
@@ -0,0 +1,190 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use proc_macro2::{Ident, TokenStream};
+use syn::{
+    parenthesized,
+    parse::{Parse, Parser},
+    Attribute, LitStr,
+};
+
+use crate::conversion::{
+    api::{CppVisibility, Layout, References, SpecialMemberKind, Virtualness},
+    convert_error::{ConvertErrorWithContext, ErrorContext},
+    ConvertError,
+};
+
+/// The set of all annotations that autocxx_bindgen has added
+/// for our benefit.
+#[derive(Debug)]
+pub(crate) struct BindgenSemanticAttributes(Vec<BindgenSemanticAttribute>);
+
+impl BindgenSemanticAttributes {
+    // Remove `bindgen_` attributes. They don't have a corresponding macro defined anywhere,
+    // so they will cause compilation errors if we leave them in.
+    // We may return an error if one of the bindgen attributes shows that the
+    // item can't be processed.
+    pub(crate) fn new_retaining_others(attrs: &mut Vec<Attribute>) -> Self {
+        let metadata = Self::new(attrs);
+        attrs.retain(|a| a.path.segments.last().unwrap().ident != "cpp_semantics");
+        metadata
+    }
+
+    pub(crate) fn new(attrs: &[Attribute]) -> Self {
+        Self(
+            attrs
+                .iter()
+                .filter_map(|attr| {
+                    if attr.path.segments.last().unwrap().ident == "cpp_semantics" {
+                        let r: Result<BindgenSemanticAttribute, syn::Error> = attr.parse_args();
+                        r.ok()
+                    } else {
+                        None
+                    }
+                })
+                .collect(),
+        )
+    }
+
+    /// Some attributes indicate we can never handle a given item. Check for those.
+    pub(crate) fn check_for_fatal_attrs(
+        &self,
+        id_for_context: &Ident,
+    ) -> Result<(), ConvertErrorWithContext> {
+        if self.has_attr("unused_template_param") {
+            Err(ConvertErrorWithContext(
+                ConvertError::UnusedTemplateParam,
+                Some(ErrorContext::new_for_item(id_for_context.clone())),
+            ))
+        } else {
+            Ok(())
+        }
+    }
+
+    /// Whether the given attribute is present.
+    pub(super) fn has_attr(&self, attr_name: &str) -> bool {
+        self.0.iter().any(|a| a.is_ident(attr_name))
+    }
+
+    /// The C++ visibility of the item.
+    pub(super) fn get_cpp_visibility(&self) -> CppVisibility {
+        if self.has_attr("visibility_private") {
+            CppVisibility::Private
+        } else if self.has_attr("visibility_protected") {
+            CppVisibility::Protected
+        } else {
+            CppVisibility::Public
+        }
+    }
+
+    /// Whether the item is virtual.
+    pub(super) fn get_virtualness(&self) -> Virtualness {
+        if self.has_attr("pure_virtual") {
+            Virtualness::PureVirtual
+        } else if self.has_attr("bindgen_virtual") {
+            Virtualness::Virtual
+        } else {
+            Virtualness::None
+        }
+    }
+
+    fn parse_if_present<T: Parse>(&self, annotation: &str) -> Option<T> {
+        self.0
+            .iter()
+            .find(|a| a.is_ident(annotation))
+            .map(|a| a.parse_args().unwrap())
+    }
+
+    fn string_if_present(&self, annotation: &str) -> Option<String> {
+        let ls: Option<LitStr> = self.parse_if_present(annotation);
+        ls.map(|ls| ls.value())
+    }
+
+    /// The in-memory layout of the item.
+    pub(super) fn get_layout(&self) -> Option<Layout> {
+        self.parse_if_present("layout")
+    }
+
+    /// The original C++ name, which bindgen may have changed.
+    pub(super) fn get_original_name(&self) -> Option<String> {
+        self.string_if_present("original_name")
+    }
+
+    /// Whether this is a move constructor or other special member.
+    pub(super) fn special_member_kind(&self) -> Option<SpecialMemberKind> {
+        self.string_if_present("special_member")
+            .map(|kind| match kind.as_str() {
+                "default_ctor" => SpecialMemberKind::DefaultConstructor,
+                "copy_ctor" => SpecialMemberKind::CopyConstructor,
+                "move_ctor" => SpecialMemberKind::MoveConstructor,
+                "dtor" => SpecialMemberKind::Destructor,
+                "assignment_operator" => SpecialMemberKind::AssignmentOperator,
+                _ => panic!("unexpected special_member_kind"),
+            })
+    }
+
+    /// Any reference parameters or return values.
+    pub(super) fn get_reference_parameters_and_return(&self) -> References {
+        let mut results = References::default();
+        for a in &self.0 {
+            if a.is_ident("ret_type_reference") {
+                results.ref_return = true;
+            } else if a.is_ident("ret_type_rvalue_reference") {
+                results.rvalue_ref_return = true;
+            } else if a.is_ident("arg_type_reference") {
+                let r: Result<Ident, syn::Error> = a.parse_args();
+                if let Ok(ls) = r {
+                    results.ref_params.insert(ls);
+                }
+            } else if a.is_ident("arg_type_rvalue_reference") {
+                let r: Result<Ident, syn::Error> = a.parse_args();
+                if let Ok(ls) = r {
+                    results.rvalue_ref_params.insert(ls);
+                }
+            }
+        }
+        results
+    }
+}
+
+#[derive(Debug)]
+struct BindgenSemanticAttribute {
+    annotation_name: Ident,
+    body: Option<TokenStream>,
+}
+
+impl BindgenSemanticAttribute {
+    fn is_ident(&self, name: &str) -> bool {
+        self.annotation_name == name
+    }
+
+    fn parse_args<T: Parse>(&self) -> Result<T, syn::Error> {
+        T::parse.parse2(self.body.as_ref().unwrap().clone())
+    }
+}
+
+impl Parse for BindgenSemanticAttribute {
+    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
+        let annotation_name: Ident = input.parse()?;
+        if input.peek(syn::token::Paren) {
+            let body_contents;
+            parenthesized!(body_contents in input);
+            Ok(Self {
+                annotation_name,
+                body: Some(body_contents.parse()?),
+            })
+        } else if !input.is_empty() {
+            Err(input.error("expected nothing"))
+        } else {
+            Ok(Self {
+                annotation_name,
+                body: None,
+            })
+        }
+    }
+}
diff --git a/engine/src/conversion/parse/mod.rs b/engine/src/conversion/parse/mod.rs
new file mode 100644
index 0000000..3f42ce4
--- /dev/null
+++ b/engine/src/conversion/parse/mod.rs
@@ -0,0 +1,14 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+mod bindgen_semantic_attributes;
+mod parse_bindgen;
+mod parse_foreign_mod;
+
+pub(crate) use bindgen_semantic_attributes::BindgenSemanticAttributes;
+pub(crate) use parse_bindgen::ParseBindgen;
diff --git a/engine/src/conversion/parse/parse_bindgen.rs b/engine/src/conversion/parse/parse_bindgen.rs
new file mode 100644
index 0000000..0818aa5
--- /dev/null
+++ b/engine/src/conversion/parse/parse_bindgen.rs
@@ -0,0 +1,388 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use indexmap::map::IndexMap as HashMap;
+use indexmap::set::IndexSet as HashSet;
+
+use crate::{
+    conversion::{
+        api::{Api, ApiName, NullPhase, StructDetails, SubclassName, TypedefKind, UnanalyzedApi},
+        apivec::ApiVec,
+        ConvertError,
+    },
+    types::Namespace,
+    types::QualifiedName,
+};
+use crate::{
+    conversion::{
+        convert_error::{ConvertErrorWithContext, ErrorContext},
+        error_reporter::report_any_error,
+    },
+    types::validate_ident_ok_for_cxx,
+};
+use autocxx_parser::{IncludeCppConfig, RustPath};
+use syn::{parse_quote, Fields, Ident, Item, Type, TypePath, UseTree};
+
+use super::{
+    super::utilities::generate_utilities, bindgen_semantic_attributes::BindgenSemanticAttributes,
+};
+
+use super::parse_foreign_mod::ParseForeignMod;
+
+/// Parses a bindgen mod in order to understand the APIs within it.
+pub(crate) struct ParseBindgen<'a> {
+    config: &'a IncludeCppConfig,
+    apis: ApiVec<NullPhase>,
+}
+
+fn api_name(ns: &Namespace, id: Ident, attrs: &BindgenSemanticAttributes) -> ApiName {
+    ApiName::new_with_cpp_name(ns, id, attrs.get_original_name())
+}
+
+pub(crate) fn api_name_qualified(
+    ns: &Namespace,
+    id: Ident,
+    attrs: &BindgenSemanticAttributes,
+) -> Result<ApiName, ConvertErrorWithContext> {
+    match validate_ident_ok_for_cxx(&id.to_string()) {
+        Err(e) => {
+            let ctx = ErrorContext::new_for_item(id);
+            Err(ConvertErrorWithContext(e, Some(ctx)))
+        }
+        Ok(..) => Ok(api_name(ns, id, attrs)),
+    }
+}
+
+impl<'a> ParseBindgen<'a> {
+    pub(crate) fn new(config: &'a IncludeCppConfig) -> Self {
+        ParseBindgen {
+            config,
+            apis: ApiVec::new(),
+        }
+    }
+
+    /// Parses items found in the `bindgen` output and returns a set of
+    /// `Api`s together with some other data.
+    pub(crate) fn parse_items(
+        mut self,
+        items: Vec<Item>,
+    ) -> Result<ApiVec<NullPhase>, ConvertError> {
+        let items = Self::find_items_in_root(items)?;
+        if !self.config.exclude_utilities() {
+            generate_utilities(&mut self.apis, self.config);
+        }
+        self.add_apis_from_config();
+        let root_ns = Namespace::new();
+        self.parse_mod_items(items, root_ns);
+        self.confirm_all_generate_directives_obeyed()?;
+        self.replace_extern_cpp_types();
+        Ok(self.apis)
+    }
+
+    /// Some API items are not populated from bindgen output, but instead
+    /// directly from items in the config.
+    fn add_apis_from_config(&mut self) {
+        self.apis
+            .extend(self.config.subclasses.iter().map(|sc| Api::Subclass {
+                name: SubclassName::new(sc.subclass.clone()),
+                superclass: QualifiedName::new_from_cpp_name(&sc.superclass),
+            }));
+        self.apis
+            .extend(self.config.extern_rust_funs.iter().map(|fun| {
+                let id = fun.sig.ident.clone();
+                Api::RustFn {
+                    name: ApiName::new_in_root_namespace(id),
+                    details: fun.clone(),
+                    receiver: fun.receiver.as_ref().map(|receiver_id| {
+                        QualifiedName::new(&Namespace::new(), receiver_id.clone())
+                    }),
+                }
+            }));
+        let unique_rust_types: HashSet<&RustPath> = self.config.rust_types.iter().collect();
+        self.apis.extend(unique_rust_types.into_iter().map(|path| {
+            let id = path.get_final_ident();
+            Api::RustType {
+                name: ApiName::new_in_root_namespace(id.clone()),
+                path: path.clone(),
+            }
+        }));
+        self.apis.extend(
+            self.config
+                .concretes
+                .0
+                .iter()
+                .map(|(cpp_definition, rust_id)| {
+                    let name = ApiName::new_in_root_namespace(rust_id.clone());
+                    Api::ConcreteType {
+                        name,
+                        cpp_definition: cpp_definition.clone(),
+                        rs_definition: None,
+                    }
+                }),
+        );
+    }
+
+    /// We do this last, _after_ we've parsed all the APIs, because we might want to actually
+    /// replace some of the existing APIs (structs/enums/etc.) with replacements.
+    fn replace_extern_cpp_types(&mut self) {
+        let pod_requests: HashSet<_> = self.config.get_pod_requests().iter().collect();
+        let replacements: HashMap<_, _> = self
+            .config
+            .externs
+            .0
+            .iter()
+            .map(|(cpp_definition, details)| {
+                let qn = QualifiedName::new_from_cpp_name(cpp_definition);
+                let pod = pod_requests.contains(&qn.to_cpp_name());
+                (
+                    qn.clone(),
+                    Api::ExternCppType {
+                        name: ApiName::new_from_qualified_name(qn),
+                        details: details.clone(),
+                        pod,
+                    },
+                )
+            })
+            .collect();
+        self.apis
+            .retain(|api| !replacements.contains_key(api.name()));
+        self.apis.extend(replacements.into_iter().map(|(_, v)| v));
+    }
+
+    fn find_items_in_root(items: Vec<Item>) -> Result<Vec<Item>, ConvertError> {
+        for item in items {
+            match item {
+                Item::Mod(root_mod) => {
+                    // With namespaces enabled, bindgen always puts everything
+                    // in a mod called 'root'. We don't want to pass that
+                    // onto cxx, so jump right into it.
+                    assert!(root_mod.ident == "root");
+                    if let Some((_, items)) = root_mod.content {
+                        return Ok(items);
+                    }
+                }
+                _ => return Err(ConvertError::UnexpectedOuterItem),
+            }
+        }
+        Ok(Vec::new())
+    }
+
+    /// Interpret the bindgen-generated .rs for a particular
+    /// mod, which corresponds to a C++ namespace.
+    fn parse_mod_items(&mut self, items: Vec<Item>, ns: Namespace) {
+        // This object maintains some state specific to this namespace, i.e.
+        // this particular mod.
+        let mut mod_converter = ParseForeignMod::new(ns.clone());
+        let mut more_apis = ApiVec::new();
+        for item in items {
+            report_any_error(&ns, &mut more_apis, || {
+                self.parse_item(item, &mut mod_converter, &ns)
+            });
+        }
+        self.apis.append(&mut more_apis);
+        mod_converter.finished(&mut self.apis);
+    }
+
+    fn parse_item(
+        &mut self,
+        item: Item,
+        mod_converter: &mut ParseForeignMod,
+        ns: &Namespace,
+    ) -> Result<(), ConvertErrorWithContext> {
+        match item {
+            Item::ForeignMod(fm) => {
+                mod_converter.convert_foreign_mod_items(fm.items);
+                Ok(())
+            }
+            Item::Struct(s) => {
+                if s.ident.to_string().ends_with("__bindgen_vtable") {
+                    return Ok(());
+                }
+                let annotations = BindgenSemanticAttributes::new(&s.attrs);
+                // cxx::bridge can't cope with type aliases to generic
+                // types at the moment.
+                let name = api_name_qualified(ns, s.ident.clone(), &annotations)?;
+                let err = annotations.check_for_fatal_attrs(&s.ident).err();
+                let api = if ns.is_empty() && self.config.is_rust_type(&s.ident) {
+                    None
+                } else if Self::spot_forward_declaration(&s.fields)
+                    || (Self::spot_zero_length_struct(&s.fields) && err.is_some())
+                {
+                    // Forward declarations are recorded especially because we can't
+                    // store them in UniquePtr or similar.
+                    // Templated forward declarations don't appear with an _unused field (which is what
+                    // we spot in the previous clause) but instead with an _address field.
+                    // So, solely in the case where we're storing up an error about such
+                    // a templated type, we'll also treat such cases as forward declarations.
+                    Some(UnanalyzedApi::ForwardDeclaration { name, err })
+                } else {
+                    let has_rvalue_reference_fields = s.fields.iter().any(|f| {
+                        BindgenSemanticAttributes::new(&f.attrs).has_attr("rvalue_reference")
+                    });
+                    Some(UnanalyzedApi::Struct {
+                        name,
+                        details: Box::new(StructDetails {
+                            vis: annotations.get_cpp_visibility(),
+                            layout: annotations.get_layout(),
+                            item: s,
+                            has_rvalue_reference_fields,
+                        }),
+                        analysis: (),
+                    })
+                };
+                if let Some(api) = api {
+                    if !self.config.is_on_blocklist(&api.name().to_cpp_name()) {
+                        self.apis.push(api);
+                    }
+                }
+                Ok(())
+            }
+            Item::Enum(e) => {
+                let annotations = BindgenSemanticAttributes::new(&e.attrs);
+                let api = UnanalyzedApi::Enum {
+                    name: api_name_qualified(ns, e.ident.clone(), &annotations)?,
+                    item: e,
+                };
+                if !self.config.is_on_blocklist(&api.name().to_cpp_name()) {
+                    self.apis.push(api);
+                }
+                Ok(())
+            }
+            Item::Impl(imp) => {
+                // We *mostly* ignore all impl blocks generated by bindgen.
+                // Methods also appear in 'extern "C"' blocks which
+                // we will convert instead. At that time we'll also construct
+                // synthetic impl blocks.
+                // We do however record which methods were spotted, since
+                // we have no other way of working out which functions are
+                // static methods vs plain functions.
+                mod_converter.convert_impl_items(imp);
+                Ok(())
+            }
+            Item::Mod(itm) => {
+                if let Some((_, items)) = itm.content {
+                    let new_ns = ns.push(itm.ident.to_string());
+                    self.parse_mod_items(items, new_ns);
+                }
+                Ok(())
+            }
+            Item::Use(use_item) => {
+                let mut segs = Vec::new();
+                let mut tree = &use_item.tree;
+                loop {
+                    match tree {
+                        UseTree::Path(up) => {
+                            segs.push(up.ident.clone());
+                            tree = &up.tree;
+                        }
+                        UseTree::Name(un) if un.ident == "root" => break, // we do not add this to any API since we generate equivalent
+                        // use statements in our codegen phase.
+                        UseTree::Rename(urn) => {
+                            let old_id = &urn.ident;
+                            let new_id = &urn.rename;
+                            let new_tyname = QualifiedName::new(ns, new_id.clone());
+                            assert!(segs.remove(0) == "self", "Path didn't start with self");
+                            assert!(
+                                segs.remove(0) == "super",
+                                "Path didn't start with self::super"
+                            );
+                            // This is similar to the path encountered within 'tree'
+                            // but without the self::super prefix which is unhelpful
+                            // in our output mod, because we prefer relative paths
+                            // (we're nested in another mod)
+                            let old_path: TypePath = parse_quote! {
+                                #(#segs)::* :: #old_id
+                            };
+                            let old_tyname = QualifiedName::from_type_path(&old_path);
+                            if new_tyname == old_tyname {
+                                return Err(ConvertErrorWithContext(
+                                    ConvertError::InfinitelyRecursiveTypedef(new_tyname),
+                                    Some(ErrorContext::new_for_item(new_id.clone())),
+                                ));
+                            }
+                            let annotations = BindgenSemanticAttributes::new(&use_item.attrs);
+                            self.apis.push(UnanalyzedApi::Typedef {
+                                name: api_name(ns, new_id.clone(), &annotations),
+                                item: TypedefKind::Use(
+                                    parse_quote! {
+                                        pub use #old_path as #new_id;
+                                    },
+                                    Box::new(Type::Path(old_path)),
+                                ),
+                                old_tyname: Some(old_tyname),
+                                analysis: (),
+                            });
+                            break;
+                        }
+                        _ => {
+                            return Err(ConvertErrorWithContext(
+                                ConvertError::UnexpectedUseStatement(
+                                    segs.into_iter().last().map(|i| i.to_string()),
+                                ),
+                                None,
+                            ))
+                        }
+                    }
+                }
+                Ok(())
+            }
+            Item::Const(const_item) => {
+                let annotations = BindgenSemanticAttributes::new(&const_item.attrs);
+                self.apis.push(UnanalyzedApi::Const {
+                    name: api_name(ns, const_item.ident.clone(), &annotations),
+                    const_item,
+                });
+                Ok(())
+            }
+            Item::Type(ity) => {
+                let annotations = BindgenSemanticAttributes::new(&ity.attrs);
+                // It's known that sometimes bindgen will give us duplicate typedefs with the
+                // same name - see test_issue_264.
+                self.apis.push(UnanalyzedApi::Typedef {
+                    name: api_name(ns, ity.ident.clone(), &annotations),
+                    item: TypedefKind::Type(ity),
+                    old_tyname: None,
+                    analysis: (),
+                });
+                Ok(())
+            }
+            _ => Err(ConvertErrorWithContext(
+                ConvertError::UnexpectedItemInMod,
+                None,
+            )),
+        }
+    }
+
+    fn spot_forward_declaration(s: &Fields) -> bool {
+        Self::spot_field(s, "_unused")
+    }
+
+    fn spot_zero_length_struct(s: &Fields) -> bool {
+        Self::spot_field(s, "_address")
+    }
+
+    fn spot_field(s: &Fields, desired_id: &str) -> bool {
+        s.iter()
+            .filter_map(|f| f.ident.as_ref())
+            .any(|id| id == desired_id)
+    }
+
+    fn confirm_all_generate_directives_obeyed(&self) -> Result<(), ConvertError> {
+        let api_names: HashSet<_> = self
+            .apis
+            .iter()
+            .map(|api| api.name().to_cpp_name())
+            .collect();
+        for generate_directive in self.config.must_generate_list() {
+            if !api_names.contains(&generate_directive) {
+                return Err(ConvertError::DidNotGenerateAnything(generate_directive));
+            }
+        }
+        Ok(())
+    }
+}
diff --git a/engine/src/conversion/parse/parse_foreign_mod.rs b/engine/src/conversion/parse/parse_foreign_mod.rs
new file mode 100644
index 0000000..08c1fd8
--- /dev/null
+++ b/engine/src/conversion/parse/parse_foreign_mod.rs
@@ -0,0 +1,177 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::conversion::api::{ApiName, NullPhase, Provenance};
+use crate::conversion::apivec::ApiVec;
+use crate::conversion::doc_attr::get_doc_attrs;
+use crate::conversion::error_reporter::report_any_error;
+use crate::conversion::{
+    api::{FuncToConvert, UnanalyzedApi},
+    convert_error::ConvertErrorWithContext,
+    convert_error::ErrorContext,
+};
+use crate::{
+    conversion::ConvertError,
+    types::{Namespace, QualifiedName},
+};
+use std::collections::HashMap;
+use syn::{Block, Expr, ExprCall, ForeignItem, Ident, ImplItem, ItemImpl, Stmt, Type};
+
+use super::bindgen_semantic_attributes::BindgenSemanticAttributes;
+
+/// Parses a given bindgen-generated 'mod' into suitable
+/// [Api]s. In bindgen output, a given mod concerns
+/// a specific C++ namespace.
+pub(crate) struct ParseForeignMod {
+    ns: Namespace,
+    // We mostly act upon the functions we see within the 'extern "C"'
+    // block of bindgen output, but we can't actually do this until
+    // we've seen the (possibly subsequent) 'impl' blocks so we can
+    // deduce which functions are actually static methods. Hence
+    // store them.
+    funcs_to_convert: Vec<FuncToConvert>,
+    // Evidence from 'impl' blocks about which of these items
+    // may actually be methods (static or otherwise). Mapping from
+    // function name to type name.
+    method_receivers: HashMap<Ident, QualifiedName>,
+    ignored_apis: ApiVec<NullPhase>,
+}
+
+impl ParseForeignMod {
+    pub(crate) fn new(ns: Namespace) -> Self {
+        Self {
+            ns,
+            funcs_to_convert: Vec::new(),
+            method_receivers: HashMap::new(),
+            ignored_apis: ApiVec::new(),
+        }
+    }
+
+    /// Record information from foreign mod items encountered
+    /// in bindgen output.
+    pub(crate) fn convert_foreign_mod_items(&mut self, foreign_mod_items: Vec<ForeignItem>) {
+        let mut extra_apis = ApiVec::new();
+        for i in foreign_mod_items {
+            report_any_error(&self.ns.clone(), &mut extra_apis, || {
+                self.parse_foreign_item(i)
+            });
+        }
+        self.ignored_apis.append(&mut extra_apis);
+    }
+
+    fn parse_foreign_item(&mut self, i: ForeignItem) -> Result<(), ConvertErrorWithContext> {
+        match i {
+            ForeignItem::Fn(item) => {
+                let annotations = BindgenSemanticAttributes::new(&item.attrs);
+                let doc_attrs = get_doc_attrs(&item.attrs);
+                self.funcs_to_convert.push(FuncToConvert {
+                    provenance: Provenance::Bindgen,
+                    self_ty: None,
+                    ident: item.sig.ident,
+                    doc_attrs,
+                    inputs: item.sig.inputs,
+                    output: item.sig.output,
+                    vis: item.vis,
+                    virtualness: annotations.get_virtualness(),
+                    cpp_vis: annotations.get_cpp_visibility(),
+                    special_member: annotations.special_member_kind(),
+                    unused_template_param: annotations
+                        .has_attr("incomprehensible_param_in_arg_or_return"),
+                    references: annotations.get_reference_parameters_and_return(),
+                    original_name: annotations.get_original_name(),
+                    synthesized_this_type: None,
+                    add_to_trait: None,
+                    is_deleted: annotations.has_attr("deleted"),
+                    synthetic_cpp: None,
+                    variadic: item.sig.variadic.is_some(),
+                });
+                Ok(())
+            }
+            ForeignItem::Static(item) => Err(ConvertErrorWithContext(
+                ConvertError::StaticData(item.ident.to_string()),
+                Some(ErrorContext::new_for_item(item.ident)),
+            )),
+            _ => Err(ConvertErrorWithContext(
+                ConvertError::UnexpectedForeignItem,
+                None,
+            )),
+        }
+    }
+
+    /// Record information from impl blocks encountered in bindgen
+    /// output.
+    pub(crate) fn convert_impl_items(&mut self, imp: ItemImpl) {
+        let ty_id = match *imp.self_ty {
+            Type::Path(typ) => typ.path.segments.last().unwrap().ident.clone(),
+            _ => return,
+        };
+        for i in imp.items {
+            if let ImplItem::Method(itm) = i {
+                let effective_fun_name = match get_called_function(&itm.block) {
+                    Some(id) => id.clone(),
+                    None => itm.sig.ident,
+                };
+                self.method_receivers.insert(
+                    effective_fun_name,
+                    QualifiedName::new(&self.ns, ty_id.clone()),
+                );
+            }
+        }
+    }
+
+    /// Indicate that all foreign mods and all impl blocks have been
+    /// fed into us, and we should process that information to generate
+    /// the resulting APIs.
+    pub(crate) fn finished(mut self, apis: &mut ApiVec<NullPhase>) {
+        apis.append(&mut self.ignored_apis);
+        while !self.funcs_to_convert.is_empty() {
+            let mut fun = self.funcs_to_convert.remove(0);
+            fun.self_ty = self.method_receivers.get(&fun.ident).cloned();
+            apis.push(UnanalyzedApi::Function {
+                name: ApiName::new_with_cpp_name(
+                    &self.ns,
+                    fun.ident.clone(),
+                    fun.original_name.clone(),
+                ),
+                fun: Box::new(fun),
+                analysis: (),
+            })
+        }
+    }
+}
+
+/// bindgen sometimes generates an impl fn called a which calls
+/// a function called a1(), if it's dealing with conflicting names.
+/// We actually care about the name a1, so we have to parse the
+/// name of the actual function call inside the block's body.
+fn get_called_function(block: &Block) -> Option<&Ident> {
+    match block.stmts.first() {
+        Some(Stmt::Expr(Expr::Call(ExprCall { func, .. }))) => match **func {
+            Expr::Path(ref exp) => exp.path.segments.first().map(|ps| &ps.ident),
+            _ => None,
+        },
+        _ => None,
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::get_called_function;
+    use syn::parse_quote;
+    use syn::Block;
+
+    #[test]
+    fn test_get_called_function() {
+        let b: Block = parse_quote! {
+            {
+                call_foo()
+            }
+        };
+        assert_eq!(get_called_function(&b).unwrap().to_string(), "call_foo");
+    }
+}
diff --git a/engine/src/conversion/utilities.rs b/engine/src/conversion/utilities.rs
new file mode 100644
index 0000000..b90b365
--- /dev/null
+++ b/engine/src/conversion/utilities.rs
@@ -0,0 +1,30 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use autocxx_parser::IncludeCppConfig;
+
+use super::{
+    api::{ApiName, NullPhase, UnanalyzedApi},
+    apivec::ApiVec,
+};
+use crate::types::{make_ident, Namespace};
+
+/// Adds items which we always add, cos they're useful.
+/// Any APIs or techniques which do not involve actual C++ interop
+/// shouldn't go here, but instead should go into the main autocxx
+/// src/lib.rs.
+pub(crate) fn generate_utilities(apis: &mut ApiVec<NullPhase>, config: &IncludeCppConfig) {
+    // Unless we've been specifically asked not to do so, we always
+    // generate a 'make_string' function. That pretty much *always* means
+    // we run two passes through bindgen. i.e. the next 'if' is always true,
+    // and we always generate an additional C++ file for our bindings additions,
+    // unless the include_cpp macro has specified ExcludeUtilities.
+    apis.push(UnanalyzedApi::StringConstructor {
+        name: ApiName::new(&Namespace::new(), make_ident(config.get_makestring_name())),
+    });
+}
diff --git a/engine/src/cxxbridge.rs b/engine/src/cxxbridge.rs
new file mode 100644
index 0000000..28163af
--- /dev/null
+++ b/engine/src/cxxbridge.rs
@@ -0,0 +1,45 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use proc_macro2::TokenStream;
+use quote::{ToTokens, TokenStreamExt};
+use syn::ItemMod;
+
+use crate::{do_cxx_cpp_generation, parse_file::CppBuildable, CppCodegenOptions, GeneratedCpp};
+
+/// A struct to represent a cxx::bridge (i.e. some manual bindings)
+/// found in a file. autocxx knows about them so that we can generate C++
+/// for both manual and automatic bindings using the same tooling.
+pub struct CxxBridge {
+    tokens: TokenStream,
+}
+
+impl From<ItemMod> for CxxBridge {
+    fn from(itm: ItemMod) -> Self {
+        Self {
+            tokens: itm.to_token_stream(),
+        }
+    }
+}
+
+impl ToTokens for CxxBridge {
+    fn to_tokens(&self, tokens: &mut TokenStream) {
+        tokens.append_all(self.tokens.clone());
+    }
+}
+
+impl CppBuildable for CxxBridge {
+    fn generate_h_and_cxx(
+        &self,
+        cpp_codegen_options: &CppCodegenOptions,
+    ) -> Result<GeneratedCpp, cxx_gen::Error> {
+        let header_name = cpp_codegen_options.cxxgen_header_namer.name_header();
+        let fp = do_cxx_cpp_generation(self.tokens.clone(), cpp_codegen_options, header_name)?;
+        Ok(GeneratedCpp(vec![fp]))
+    }
+}
diff --git a/engine/src/known_types.rs b/engine/src/known_types.rs
new file mode 100644
index 0000000..377101a
--- /dev/null
+++ b/engine/src/known_types.rs
@@ -0,0 +1,562 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::{
+    conversion::ConvertError,
+    types::{make_ident, QualifiedName},
+};
+use indexmap::map::IndexMap as HashMap;
+use indoc::indoc;
+use once_cell::sync::OnceCell;
+use syn::{parse_quote, Type, TypePath, TypePtr};
+
+//// The behavior of the type.
+#[derive(Debug)]
+enum Behavior {
+    CxxContainerPtr,
+    CxxContainerVector,
+    CxxString,
+    RustStr,
+    RustString,
+    RustByValue,
+    CByValue,
+    CByValueVecSafe,
+    CVariableLengthByValue,
+    CVoid,
+    CChar16,
+    RustContainerByValueSafe,
+}
+
+/// Details about known special types, mostly primitives.
+#[derive(Debug)]
+struct TypeDetails {
+    /// The name used by cxx (in Rust code) for this type.
+    rs_name: String,
+    /// C++ equivalent name for a Rust type.
+    cpp_name: String,
+    /// The behavior of the type.
+    behavior: Behavior,
+    /// Any extra non-canonical names
+    extra_non_canonical_name: Option<String>,
+    has_const_copy_constructor: bool,
+    has_move_constructor: bool,
+}
+
+impl TypeDetails {
+    fn new(
+        rs_name: impl Into<String>,
+        cpp_name: impl Into<String>,
+        behavior: Behavior,
+        extra_non_canonical_name: Option<String>,
+        has_const_copy_constructor: bool,
+        has_move_constructor: bool,
+    ) -> Self {
+        TypeDetails {
+            rs_name: rs_name.into(),
+            cpp_name: cpp_name.into(),
+            behavior,
+            extra_non_canonical_name,
+            has_const_copy_constructor,
+            has_move_constructor,
+        }
+    }
+
+    /// Whether and how to include this in the prelude given to bindgen.
+    fn get_prelude_entry(&self) -> Option<String> {
+        match self.behavior {
+            Behavior::RustString
+            | Behavior::RustStr
+            | Behavior::CxxString
+            | Behavior::CxxContainerPtr
+            | Behavior::CxxContainerVector
+            | Behavior::RustContainerByValueSafe => {
+                let tn = QualifiedName::new_from_cpp_name(&self.rs_name);
+                let cxx_name = tn.get_final_item();
+                let (templating, payload) = match self.behavior {
+                    Behavior::CxxContainerPtr
+                    | Behavior::CxxContainerVector
+                    | Behavior::RustContainerByValueSafe => ("template<typename T> ", "T* ptr"),
+                    _ => ("", "char* ptr"),
+                };
+                Some(format!(
+                    indoc! {"
+                    /**
+                    * <div rustbindgen=\"true\" replaces=\"{}\">
+                    */
+                    {}class {} {{
+                        {};
+                    }};
+                    "},
+                    self.cpp_name, templating, cxx_name, payload
+                ))
+            }
+            _ => None,
+        }
+    }
+
+    fn to_type_path(&self) -> TypePath {
+        let mut segs = self.rs_name.split("::").peekable();
+        if segs.peek().map(|seg| seg.is_empty()).unwrap_or_default() {
+            segs.next();
+            let segs = segs.into_iter().map(make_ident);
+            parse_quote! {
+                ::#(#segs)::*
+            }
+        } else {
+            let segs = segs.into_iter().map(make_ident);
+            parse_quote! {
+                #(#segs)::*
+            }
+        }
+    }
+
+    fn to_typename(&self) -> QualifiedName {
+        QualifiedName::new_from_cpp_name(&self.rs_name)
+    }
+
+    fn get_generic_behavior(&self) -> CxxGenericType {
+        match self.behavior {
+            Behavior::CxxContainerPtr => CxxGenericType::CppPtr,
+            Behavior::CxxContainerVector => CxxGenericType::CppVector,
+            Behavior::RustContainerByValueSafe => CxxGenericType::Rust,
+            _ => CxxGenericType::Not,
+        }
+    }
+}
+
+/// Database of known types.
+#[derive(Default)]
+pub(crate) struct TypeDatabase {
+    by_rs_name: HashMap<QualifiedName, TypeDetails>,
+    canonical_names: HashMap<QualifiedName, QualifiedName>,
+}
+
+/// Returns a database of known types.
+pub(crate) fn known_types() -> &'static TypeDatabase {
+    static KNOWN_TYPES: OnceCell<TypeDatabase> = OnceCell::new();
+    KNOWN_TYPES.get_or_init(create_type_database)
+}
+
+/// The type of payload that a cxx generic can contain.
+#[derive(PartialEq, Clone, Copy)]
+pub enum CxxGenericType {
+    /// Not a generic at all
+    Not,
+    /// Some generic like cxx::UniquePtr where the contents must be a
+    /// complete type.
+    CppPtr,
+    /// Some generic like cxx::Vector where the contents must be a
+    /// complete type, and some types of int are allowed too.
+    CppVector,
+    /// Some generic like rust::Box where forward declarations are OK
+    Rust,
+}
+
+pub struct KnownTypeConstructorDetails {
+    pub has_move_constructor: bool,
+    pub has_const_copy_constructor: bool,
+}
+
+impl TypeDatabase {
+    fn get(&self, ty: &QualifiedName) -> Option<&TypeDetails> {
+        // The following line is important. It says that
+        // when we encounter something like 'std::unique_ptr'
+        // in the bindgen-generated bindings, we'll immediately
+        // start to refer to that as 'UniquePtr' henceforth.
+        let canonical_name = self.canonical_names.get(ty).unwrap_or(ty);
+        self.by_rs_name.get(canonical_name)
+    }
+
+    /// Prelude of C++ for squirting into bindgen. This configures
+    /// bindgen to output simpler types to replace some STL types
+    /// that bindgen just can't cope with. Although we then replace
+    /// those types with cxx types (e.g. UniquePtr), this intermediate
+    /// step is still necessary because bindgen can't otherwise
+    /// give us the templated types (e.g. when faced with the STL
+    /// unique_ptr, bindgen would normally give us std_unique_ptr
+    /// as opposed to std_unique_ptr<T>.)
+    pub(crate) fn get_prelude(&self) -> String {
+        itertools::join(
+            self.by_rs_name
+                .values()
+                .filter_map(|t| t.get_prelude_entry()),
+            "",
+        )
+    }
+
+    /// Returns all known types.
+    pub(crate) fn all_names(&self) -> impl Iterator<Item = &QualifiedName> {
+        self.canonical_names.keys().chain(self.by_rs_name.keys())
+    }
+
+    /// Types which are known to be safe (or unsafe) to hold and pass by
+    /// value in Rust.
+    pub(crate) fn get_pod_safe_types(&self) -> impl Iterator<Item = (QualifiedName, bool)> {
+        let pod_safety = self
+            .all_names()
+            .map(|tn| {
+                (
+                    tn.clone(),
+                    match self.get(tn).unwrap().behavior {
+                        Behavior::CxxContainerPtr
+                        | Behavior::RustStr
+                        | Behavior::RustString
+                        | Behavior::RustByValue
+                        | Behavior::CByValueVecSafe
+                        | Behavior::CByValue
+                        | Behavior::CVariableLengthByValue
+                        | Behavior::CChar16
+                        | Behavior::RustContainerByValueSafe => true,
+                        Behavior::CxxString | Behavior::CxxContainerVector | Behavior::CVoid => {
+                            false
+                        }
+                    },
+                )
+            })
+            .collect::<HashMap<_, _>>();
+        pod_safety.into_iter()
+    }
+
+    pub(crate) fn get_constructor_details(
+        &self,
+        qn: &QualifiedName,
+    ) -> Option<KnownTypeConstructorDetails> {
+        self.get(qn).map(|x| KnownTypeConstructorDetails {
+            has_move_constructor: x.has_move_constructor,
+            has_const_copy_constructor: x.has_const_copy_constructor,
+        })
+    }
+
+    /// Whether this TypePath should be treated as a value in C++
+    /// but a reference in Rust. This only applies to rust::Str
+    /// (C++ name) which is &str in Rust.
+    pub(crate) fn should_dereference_in_cpp(&self, tn: &QualifiedName) -> bool {
+        self.get(tn)
+            .map(|td| matches!(td.behavior, Behavior::RustStr))
+            .unwrap_or(false)
+    }
+
+    /// Whether this can only be passed around using `std::move`
+    pub(crate) fn lacks_copy_constructor(&self, tn: &QualifiedName) -> bool {
+        self.get(tn)
+            .map(|td| {
+                matches!(
+                    td.behavior,
+                    Behavior::CxxContainerPtr | Behavior::CxxContainerVector
+                )
+            })
+            .unwrap_or(false)
+    }
+
+    /// Here we substitute any names which we know are Special from
+    /// our type database, e.g. std::unique_ptr -> UniquePtr.
+    /// We strip off and ignore
+    /// any PathArguments within this TypePath - callers should
+    /// put them back again if needs be.
+    pub(crate) fn consider_substitution(&self, tn: &QualifiedName) -> Option<TypePath> {
+        self.get(tn).map(|td| td.to_type_path())
+    }
+
+    pub(crate) fn special_cpp_name(&self, rs: &QualifiedName) -> Option<String> {
+        self.get(rs).map(|x| x.cpp_name.to_string())
+    }
+
+    pub(crate) fn is_known_type(&self, ty: &QualifiedName) -> bool {
+        self.get(ty).is_some()
+    }
+
+    pub(crate) fn known_type_type_path(&self, ty: &QualifiedName) -> Option<TypePath> {
+        self.get(ty).map(|td| td.to_type_path())
+    }
+
+    /// Get the list of types to give to bindgen to ask it _not_ to
+    /// generate code for.
+    pub(crate) fn get_initial_blocklist(&self) -> impl Iterator<Item = &str> + '_ {
+        self.by_rs_name
+            .iter()
+            .filter_map(|(_, td)| td.get_prelude_entry().map(|_| td.cpp_name.as_str()))
+    }
+
+    /// Whether this is one of the ctypes (mostly variable length integers)
+    /// which we need to wrap.
+    pub(crate) fn is_ctype(&self, ty: &QualifiedName) -> bool {
+        self.get(ty)
+            .map(|td| {
+                matches!(
+                    td.behavior,
+                    Behavior::CVariableLengthByValue | Behavior::CVoid | Behavior::CChar16
+                )
+            })
+            .unwrap_or(false)
+    }
+
+    /// Whether this is a generic type acceptable to cxx. Otherwise,
+    /// if we encounter a generic, we'll replace it with a synthesized concrete
+    /// type.
+    pub(crate) fn cxx_generic_behavior(&self, ty: &QualifiedName) -> CxxGenericType {
+        self.get(ty)
+            .map(|x| x.get_generic_behavior())
+            .unwrap_or(CxxGenericType::Not)
+    }
+
+    pub(crate) fn is_cxx_acceptable_receiver(&self, ty: &QualifiedName) -> bool {
+        self.get(ty).is_none() // at present, none of our known types can have
+                               // methods attached.
+    }
+
+    pub(crate) fn permissible_within_vector(&self, ty: &QualifiedName) -> bool {
+        self.get(ty)
+            .map(|x| matches!(x.behavior, Behavior::CxxString | Behavior::CByValueVecSafe))
+            .unwrap_or(true)
+    }
+
+    pub(crate) fn permissible_within_unique_ptr(&self, ty: &QualifiedName) -> bool {
+        self.get(ty)
+            .map(|x| {
+                matches!(
+                    x.behavior,
+                    Behavior::CxxString | Behavior::CxxContainerVector
+                )
+            })
+            .unwrap_or(true)
+    }
+
+    pub(crate) fn conflicts_with_built_in_type(&self, ty: &QualifiedName) -> bool {
+        self.get(ty).is_some()
+    }
+
+    pub(crate) fn convertible_from_strs(&self, ty: &QualifiedName) -> bool {
+        self.get(ty)
+            .map(|x| matches!(x.behavior, Behavior::CxxString))
+            .unwrap_or(false)
+    }
+
+    fn insert(&mut self, td: TypeDetails) {
+        let rs_name = td.to_typename();
+        if let Some(extra_non_canonical_name) = &td.extra_non_canonical_name {
+            self.canonical_names.insert(
+                QualifiedName::new_from_cpp_name(extra_non_canonical_name),
+                rs_name.clone(),
+            );
+        }
+        self.canonical_names.insert(
+            QualifiedName::new_from_cpp_name(&td.cpp_name),
+            rs_name.clone(),
+        );
+        self.by_rs_name.insert(rs_name, td);
+    }
+
+    pub(crate) fn get_moveit_safe_types(&self) -> impl Iterator<Item = QualifiedName> + '_ {
+        self.all_names()
+            .filter(|tn| {
+                !matches!(
+                    self.get(tn).unwrap().behavior,
+                    Behavior::CxxString | Behavior::CxxContainerVector
+                )
+            })
+            .cloned()
+    }
+}
+
+fn create_type_database() -> TypeDatabase {
+    let mut db = TypeDatabase::default();
+    db.insert(TypeDetails::new(
+        "cxx::UniquePtr",
+        "std::unique_ptr",
+        Behavior::CxxContainerPtr,
+        None,
+        false,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "cxx::CxxVector",
+        "std::vector",
+        Behavior::CxxContainerVector,
+        None,
+        false,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "cxx::SharedPtr",
+        "std::shared_ptr",
+        Behavior::CxxContainerPtr,
+        None,
+        true,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "cxx::WeakPtr",
+        "std::weak_ptr",
+        Behavior::CxxContainerPtr,
+        None,
+        true,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "cxx::CxxString",
+        "std::string",
+        Behavior::CxxString,
+        None,
+        true,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "str",
+        "rust::Str",
+        Behavior::RustStr,
+        None,
+        true,
+        false,
+    ));
+    db.insert(TypeDetails::new(
+        "String",
+        "rust::String",
+        Behavior::RustString,
+        None,
+        true,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "std::boxed::Box",
+        "rust::Box",
+        Behavior::RustContainerByValueSafe,
+        None,
+        false,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "i8",
+        "int8_t",
+        Behavior::CByValueVecSafe,
+        Some("std::os::raw::c_schar".into()),
+        true,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "u8",
+        "uint8_t",
+        Behavior::CByValueVecSafe,
+        Some("std::os::raw::c_uchar".into()),
+        true,
+        true,
+    ));
+    for (cpp_type, rust_type) in (4..7).map(|x| 2i32.pow(x)).flat_map(|x| {
+        vec![
+            (format!("uint{}_t", x), format!("u{}", x)),
+            (format!("int{}_t", x), format!("i{}", x)),
+        ]
+    }) {
+        db.insert(TypeDetails::new(
+            rust_type,
+            cpp_type,
+            Behavior::CByValueVecSafe,
+            None,
+            true,
+            true,
+        ));
+    }
+    db.insert(TypeDetails::new(
+        "bool",
+        "bool",
+        Behavior::CByValue,
+        None,
+        true,
+        true,
+    ));
+
+    db.insert(TypeDetails::new(
+        "std::pin::Pin",
+        "Pin",
+        Behavior::RustByValue, // because this is actually Pin<&something>
+        None,
+        true,
+        false,
+    ));
+
+    let mut insert_ctype = |cname: &str| {
+        let concatenated_name = cname.replace(' ', "");
+        db.insert(TypeDetails::new(
+            format!("autocxx::c_{}", concatenated_name),
+            cname,
+            Behavior::CVariableLengthByValue,
+            Some(format!("std::os::raw::c_{}", concatenated_name)),
+            true,
+            true,
+        ));
+        db.insert(TypeDetails::new(
+            format!("autocxx::c_u{}", concatenated_name),
+            format!("unsigned {}", cname),
+            Behavior::CVariableLengthByValue,
+            Some(format!("std::os::raw::c_u{}", concatenated_name)),
+            true,
+            true,
+        ));
+    };
+
+    insert_ctype("long");
+    insert_ctype("int");
+    insert_ctype("short");
+    insert_ctype("long long");
+
+    db.insert(TypeDetails::new(
+        "f32",
+        "float",
+        Behavior::CByValueVecSafe,
+        None,
+        true,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "f64",
+        "double",
+        Behavior::CByValueVecSafe,
+        None,
+        true,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "::std::os::raw::c_char",
+        "char",
+        Behavior::CByValue,
+        None,
+        true,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "usize",
+        "size_t",
+        Behavior::CByValueVecSafe,
+        None,
+        true,
+        true,
+    ));
+    db.insert(TypeDetails::new(
+        "autocxx::c_void",
+        "void",
+        Behavior::CVoid,
+        Some("std::os::raw::c_void".into()),
+        false,
+        false,
+    ));
+    db.insert(TypeDetails::new(
+        "autocxx::c_char16_t",
+        "char16_t",
+        Behavior::CChar16,
+        Some("c_char16_t".into()),
+        false,
+        false,
+    ));
+    db
+}
+
+pub(crate) fn ensure_pointee_is_valid(ptr: &TypePtr) -> Result<(), ConvertError> {
+    match *ptr.elem {
+        Type::Path(..) => Ok(()),
+        _ => Err(ConvertError::InvalidPointee),
+    }
+}
diff --git a/engine/src/lib.rs b/engine/src/lib.rs
new file mode 100644
index 0000000..4edc4a4
--- /dev/null
+++ b/engine/src/lib.rs
@@ -0,0 +1,735 @@
+//! The core of the `autocxx` engine, used by both the
+//! `autocxx_macro` and also code generators (e.g. `autocxx_build`).
+//! See [IncludeCppEngine] for general description of how this engine works.
+
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// This feature=nightly could be set by build.rs, but since we only care
+// about it for docs, we ask docs.rs to set it in the Cargo.toml.
+#![cfg_attr(feature = "nightly", feature(doc_cfg))]
+#![forbid(unsafe_code)]
+
+mod ast_discoverer;
+mod conversion;
+mod cxxbridge;
+mod known_types;
+mod output_generators;
+mod parse_callbacks;
+mod parse_file;
+mod rust_pretty_printer;
+mod types;
+
+#[cfg(any(test, feature = "build"))]
+mod builder;
+
+use autocxx_parser::{IncludeCppConfig, UnsafePolicy};
+use conversion::BridgeConverter;
+use miette::{SourceOffset, SourceSpan};
+use parse_callbacks::AutocxxParseCallbacks;
+use parse_file::CppBuildable;
+use proc_macro2::TokenStream as TokenStream2;
+use regex::Regex;
+use std::path::PathBuf;
+use std::{
+    fs::File,
+    io::prelude::*,
+    path::Path,
+    process::{Command, Stdio},
+};
+use tempfile::NamedTempFile;
+
+use quote::ToTokens;
+use syn::Result as ParseResult;
+use syn::{
+    parse::{Parse, ParseStream},
+    parse_quote, ItemMod, Macro,
+};
+use thiserror::Error;
+
+use itertools::{join, Itertools};
+use known_types::known_types;
+use log::info;
+use miette::Diagnostic;
+
+/// We use a forked version of bindgen - for now.
+/// We hope to unfork.
+use autocxx_bindgen as bindgen;
+
+#[cfg(any(test, feature = "build"))]
+pub use builder::{
+    Builder, BuilderBuild, BuilderContext, BuilderError, BuilderResult, BuilderSuccess,
+};
+pub use output_generators::{generate_rs_archive, generate_rs_single, RsOutput};
+pub use parse_file::{parse_file, ParseError, ParsedFile};
+
+pub use cxx_gen::HEADER;
+
+#[derive(Clone)]
+/// Some C++ content which should be written to disk and built.
+pub struct CppFilePair {
+    /// Declarations to go into a header file.
+    pub header: Vec<u8>,
+    /// Implementations to go into a .cpp file.
+    pub implementation: Option<Vec<u8>>,
+    /// The name which should be used for the header file
+    /// (important as it may be `#include`d elsewhere)
+    pub header_name: String,
+}
+
+/// All generated C++ content which should be written to disk.
+pub struct GeneratedCpp(pub Vec<CppFilePair>);
+
+/// A [`syn::Error`] which also implements [`miette::Diagnostic`] so can be pretty-printed
+/// to show the affected span of code.
+#[derive(Error, Debug, Diagnostic)]
+#[error("{err}")]
+pub struct LocatedSynError {
+    err: syn::Error,
+    #[source_code]
+    file: String,
+    #[label("error here")]
+    span: SourceSpan,
+}
+
+impl LocatedSynError {
+    fn new(err: syn::Error, file: &str) -> Self {
+        let span = proc_macro_span_to_miette_span(&err.span());
+        Self {
+            err,
+            file: file.to_string(),
+            span,
+        }
+    }
+}
+
+/// Errors which may occur in generating bindings for these C++
+/// functions.
+#[derive(Debug, Error, Diagnostic)]
+pub enum Error {
+    #[error("Bindgen was unable to generate the initial .rs bindings for this file. This may indicate a parsing problem with the C++ headers.")]
+    Bindgen(()),
+    #[error(transparent)]
+    #[diagnostic(transparent)]
+    MacroParsing(LocatedSynError),
+    #[error(transparent)]
+    #[diagnostic(transparent)]
+    BindingsParsing(LocatedSynError),
+    #[error("no C++ include directory was provided.")]
+    NoAutoCxxInc,
+    #[error(transparent)]
+    Conversion(conversion::ConvertError),
+}
+
+/// Result type.
+pub type Result<T, E = Error> = std::result::Result<T, E>;
+
+struct GenerationResults {
+    item_mod: ItemMod,
+    cpp: Option<CppFilePair>,
+    #[allow(dead_code)]
+    inc_dirs: Vec<PathBuf>,
+    cxxgen_header_name: String,
+}
+enum State {
+    NotGenerated,
+    ParseOnly,
+    Generated(Box<GenerationResults>),
+}
+
+const AUTOCXX_CLANG_ARGS: &[&str; 4] = &["-x", "c++", "-std=c++14", "-DBINDGEN"];
+
+/// Implement to learn of header files which get included
+/// by this build process, such that your build system can choose
+/// to rerun the build process if any such file changes in future.
+pub trait RebuildDependencyRecorder: std::fmt::Debug {
+    /// Records that this autocxx build depends on the given
+    /// header file. Full paths will be provided.
+    fn record_header_file_dependency(&self, filename: &str);
+}
+
+#[cfg_attr(doc, aquamarine::aquamarine)]
+/// Core of the autocxx engine.
+///
+/// The basic idea is this. We will run `bindgen` which will spit
+/// out a ton of Rust code corresponding to all the types and functions
+/// defined in C++. We'll then post-process that bindgen output
+/// into a form suitable for ingestion by `cxx`.
+/// (It's the `BridgeConverter` mod which does that.)
+/// Along the way, the `bridge_converter` might tell us of additional
+/// C++ code which we should generate, e.g. wrappers to move things
+/// into and out of `UniquePtr`s.
+///
+/// ```mermaid
+/// flowchart TB
+///     s[(C++ headers)]
+///     s --> lc
+///     rss[(.rs input)]
+///     rss --> parser
+///     parser --> include_cpp_conf
+///     cpp_output[(C++ output)]
+///     rs_output[(.rs output)]
+///     subgraph autocxx[autocxx_engine]
+///     parser[File parser]
+///     subgraph bindgen[autocxx_bindgen]
+///     lc[libclang parse]
+///     bir(bindgen IR)
+///     lc --> bir
+///     end
+///     bgo(bindgen generated bindings)
+///     bir --> bgo
+///     include_cpp_conf(Config from include_cpp)
+///     syn[Parse with syn]
+///     bgo --> syn
+///     conv[['conversion' mod: see below]]
+///     syn --> conv
+///     rsgen(Generated .rs TokenStream)
+///     conv --> rsgen
+///     subgraph cxx_gen
+///     cxx_codegen[cxx_gen C++ codegen]
+///     end
+///     rsgen --> cxx_codegen
+///     end
+///     conv -- autocxx C++ codegen --> cpp_output
+///     rsgen -- autocxx .rs codegen --> rs_output
+///     cxx_codegen -- cxx C++ codegen --> cpp_output
+///     subgraph rustc [rustc build]
+///     subgraph autocxx_macro
+///     include_cpp[autocxx include_cpp macro]
+///     end
+///     subgraph cxx
+///     cxxm[cxx procedural macro]
+///     end
+///     comprs(Fully expanded Rust code)
+///     end
+///     rs_output-. included .->include_cpp
+///     include_cpp --> cxxm
+///     cxxm --> comprs
+///     rss --> rustc
+///     include_cpp_conf -. used to configure .-> bindgen
+///     include_cpp_conf --> conv
+///     link[linker]
+///     cpp_output --> link
+///     comprs --> link
+/// ```
+///
+/// Here's a zoomed-in view of the "conversion" part:
+///
+/// ```mermaid
+/// flowchart TB
+///     syn[(syn parse)]
+///     apis(Unanalyzed APIs)
+///     subgraph parse
+///     syn ==> parse_bindgen
+///     end
+///     parse_bindgen ==> apis
+///     subgraph analysis
+///     typedef[typedef analysis]
+///     pod[POD analysis]
+///     apis ==> typedef
+///     typedef ==> pod
+///     podapis(APIs with POD analysis)
+///     pod ==> podapis
+///     fun[Function materialization analysis]
+///     podapis ==> fun
+///     funapis(APIs with function analysis)
+///     fun ==> funapis
+///     gc[Garbage collection]
+///     funapis ==> gc
+///     ctypes[C int analysis]
+///     gc ==> ctypes
+///     ctypes ==> finalapis
+///     end
+///     finalapis(Analyzed APIs)
+///     codegenrs(.rs codegen)
+///     codegencpp(.cpp codegen)
+///     finalapis ==> codegenrs
+///     finalapis ==> codegencpp
+/// ```
+pub struct IncludeCppEngine {
+    config: IncludeCppConfig,
+    state: State,
+}
+
+impl Parse for IncludeCppEngine {
+    fn parse(input: ParseStream) -> ParseResult<Self> {
+        let config = input.parse::<IncludeCppConfig>()?;
+        let state = if config.parse_only {
+            State::ParseOnly
+        } else {
+            State::NotGenerated
+        };
+        Ok(Self { config, state })
+    }
+}
+
+impl IncludeCppEngine {
+    pub fn new_from_syn(mac: Macro, file_contents: &str) -> Result<Self> {
+        mac.parse_body::<IncludeCppEngine>()
+            .map_err(|e| Error::MacroParsing(LocatedSynError::new(e, file_contents)))
+    }
+
+    pub fn config_mut(&mut self) -> &mut IncludeCppConfig {
+        assert!(
+            matches!(self.state, State::NotGenerated),
+            "Can't alter config after generation commenced"
+        );
+        &mut self.config
+    }
+
+    fn build_header(&self) -> String {
+        join(
+            self.config
+                .inclusions
+                .iter()
+                .map(|path| format!("#include \"{}\"\n", path)),
+            "",
+        )
+    }
+
+    fn make_bindgen_builder(
+        &self,
+        inc_dirs: &[PathBuf],
+        extra_clang_args: &[&str],
+    ) -> bindgen::Builder {
+        let mut builder = bindgen::builder()
+            .clang_args(make_clang_args(inc_dirs, extra_clang_args))
+            .derive_copy(false)
+            .derive_debug(false)
+            .default_enum_style(bindgen::EnumVariation::Rust {
+                non_exhaustive: false,
+            })
+            .size_t_is_usize(true)
+            .enable_cxx_namespaces()
+            .generate_inline_functions(true)
+            .respect_cxx_access_specs(true)
+            .use_specific_virtual_function_receiver(true)
+            .cpp_semantic_attributes(true)
+            .represent_cxx_operators(true)
+            .use_distinct_char16_t(true)
+            .layout_tests(false); // TODO revisit later
+        for item in known_types().get_initial_blocklist() {
+            builder = builder.blocklist_item(item);
+        }
+
+        // 3. Passes allowlist and other options to the bindgen::Builder equivalent
+        //    to --output-style=cxx --allowlist=<as passed in>
+        if let Some(allowlist) = self.config.bindgen_allowlist() {
+            for a in allowlist {
+                // TODO - allowlist type/functions/separately
+                builder = builder
+                    .allowlist_type(&a)
+                    .allowlist_function(&a)
+                    .allowlist_var(&a);
+            }
+        }
+
+        log::info!(
+            "Bindgen flags would be: {}",
+            builder
+                .command_line_flags()
+                .into_iter()
+                .map(|f| format!("\"{}\"", f))
+                .join(" ")
+        );
+        builder
+    }
+
+    pub fn get_rs_filename(&self) -> String {
+        self.config.get_rs_filename()
+    }
+
+    /// Generate the Rust bindings. Call `generate` first.
+    pub fn get_rs_output(&self) -> RsOutput {
+        RsOutput {
+            config: &self.config,
+            rs: match &self.state {
+                State::NotGenerated => panic!("Generate first"),
+                State::Generated(gen_results) => gen_results.item_mod.to_token_stream(),
+                State::ParseOnly => TokenStream2::new(),
+            },
+        }
+    }
+
+    /// Returns the name of the mod which this `include_cpp!` will generate.
+    /// Can and should be used to ensure multiple mods in a file don't conflict.
+    pub fn get_mod_name(&self) -> String {
+        self.config.get_mod_name().to_string()
+    }
+
+    fn parse_bindings(&self, bindings: bindgen::Bindings) -> Result<ItemMod> {
+        // This bindings object is actually a TokenStream internally and we're wasting
+        // effort converting to and from string. We could enhance the bindgen API
+        // in future.
+        let bindings = bindings.to_string();
+        // Manually add the mod ffi {} so that we can ask syn to parse
+        // into a single construct.
+        let bindings = format!("mod bindgen {{ {} }}", bindings);
+        info!("Bindings: {}", bindings);
+        syn::parse_str::<ItemMod>(&bindings)
+            .map_err(|e| Error::BindingsParsing(LocatedSynError::new(e, &bindings)))
+    }
+
+    /// Actually examine the headers to find out what needs generating.
+    /// Most errors occur at this stage as we fail to interpret the C++
+    /// headers properly.
+    ///
+    /// See documentation for this type for flow diagrams and more details.
+    pub fn generate(
+        &mut self,
+        inc_dirs: Vec<PathBuf>,
+        extra_clang_args: &[&str],
+        dep_recorder: Option<Box<dyn RebuildDependencyRecorder>>,
+        cpp_codegen_options: &CppCodegenOptions,
+    ) -> Result<()> {
+        // If we are in parse only mode, do nothing. This is used for
+        // doc tests to ensure the parsing is valid, but we can't expect
+        // valid C++ header files or linkers to allow a complete build.
+        match self.state {
+            State::ParseOnly => return Ok(()),
+            State::NotGenerated => {}
+            State::Generated(_) => panic!("Only call generate once"),
+        }
+
+        let mod_name = self.config.get_mod_name();
+        let mut builder = self.make_bindgen_builder(&inc_dirs, extra_clang_args);
+        if let Some(dep_recorder) = dep_recorder {
+            builder = builder.parse_callbacks(Box::new(AutocxxParseCallbacks(dep_recorder)));
+        }
+        let header_contents = self.build_header();
+        self.dump_header_if_so_configured(&header_contents, &inc_dirs, extra_clang_args);
+        let header_and_prelude = format!("{}\n\n{}", known_types().get_prelude(), header_contents);
+        log::info!("Header and prelude for bindgen:\n{}", header_and_prelude);
+        builder = builder.header_contents("example.hpp", &header_and_prelude);
+
+        let bindings = builder.generate().map_err(Error::Bindgen)?;
+        let bindings = self.parse_bindings(bindings)?;
+
+        let converter = BridgeConverter::new(&self.config.inclusions, &self.config);
+
+        let conversion = converter
+            .convert(
+                bindings,
+                self.config.unsafe_policy.clone(),
+                header_contents,
+                cpp_codegen_options,
+            )
+            .map_err(Error::Conversion)?;
+        let mut items = conversion.rs;
+        let mut new_bindings: ItemMod = parse_quote! {
+            #[allow(non_snake_case)]
+            #[allow(dead_code)]
+            #[allow(non_upper_case_globals)]
+            #[allow(non_camel_case_types)]
+            mod #mod_name {
+            }
+        };
+        new_bindings.content.as_mut().unwrap().1.append(&mut items);
+        info!(
+            "New bindings:\n{}",
+            rust_pretty_printer::pretty_print(&new_bindings.to_token_stream())
+        );
+        self.state = State::Generated(Box::new(GenerationResults {
+            item_mod: new_bindings,
+            cpp: conversion.cpp,
+            inc_dirs,
+            cxxgen_header_name: conversion.cxxgen_header_name,
+        }));
+        Ok(())
+    }
+
+    /// Return the include directories used for this include_cpp invocation.
+    #[cfg(any(test, feature = "build"))]
+    fn include_dirs(&self) -> impl Iterator<Item = &PathBuf> {
+        match &self.state {
+            State::Generated(gen_results) => gen_results.inc_dirs.iter(),
+            _ => panic!("Must call generate() before include_dirs()"),
+        }
+    }
+
+    fn dump_header_if_so_configured(
+        &self,
+        header: &str,
+        inc_dirs: &[PathBuf],
+        extra_clang_args: &[&str],
+    ) {
+        if let Ok(output_path) = std::env::var("AUTOCXX_PREPROCESS") {
+            self.make_preprocessed_file(
+                &PathBuf::from(output_path),
+                header,
+                inc_dirs,
+                extra_clang_args,
+            );
+        }
+        #[cfg(feature = "reproduction_case")]
+        if let Ok(output_path) = std::env::var("AUTOCXX_REPRO_CASE") {
+            let tf = NamedTempFile::new().unwrap();
+            self.make_preprocessed_file(
+                &PathBuf::from(tf.path()),
+                header,
+                inc_dirs,
+                extra_clang_args,
+            );
+            let header = std::fs::read(tf.path()).unwrap();
+            let header = String::from_utf8_lossy(&header);
+            let output_path = PathBuf::from(output_path);
+            let config = self.config.to_token_stream().to_string();
+            let json = serde_json::json!({
+                "header": header,
+                "config": config
+            });
+            let f = File::create(&output_path).unwrap();
+            serde_json::to_writer(f, &json).unwrap();
+        }
+    }
+
+    fn make_preprocessed_file(
+        &self,
+        output_path: &Path,
+        header: &str,
+        inc_dirs: &[PathBuf],
+        extra_clang_args: &[&str],
+    ) {
+        // Include a load of system headers at the end of the preprocessed output,
+        // because we would like to be able to generate bindings from the
+        // preprocessed header, and then build those bindings. The C++ parts
+        // of those bindings might need things inside these various headers;
+        // we make sure all these definitions and declarations are inside
+        // this one header file so that the reduction process does not have
+        // to refer to local headers on the reduction machine too.
+        let suffix = ALL_KNOWN_SYSTEM_HEADERS
+            .iter()
+            .map(|hdr| format!("#include <{}>\n", hdr))
+            .join("\n");
+        let input = format!("/*\nautocxx config:\n\n{:?}\n\nend autocxx config.\nautocxx preprocessed input:\n*/\n\n{}\n\n/* autocxx: extra headers added below for completeness. */\n\n{}\n{}\n",
+            self.config, header, suffix, cxx_gen::HEADER);
+        let mut tf = NamedTempFile::new().unwrap();
+        write!(tf, "{}", input).unwrap();
+        let tp = tf.into_temp_path();
+        preprocess(&tp, &PathBuf::from(output_path), inc_dirs, extra_clang_args).unwrap();
+    }
+}
+
+/// This is a list of all the headers known to be included in generated
+/// C++ by cxx. We only use this when `AUTOCXX_PERPROCESS` is set to true,
+/// in an attempt to make the resulting preprocessed header more hermetic.
+/// We clearly should _not_ use this in any other circumstance; obviously
+/// we'd then want to add an API to cxx_gen such that we could retrieve
+/// that information from source.
+static ALL_KNOWN_SYSTEM_HEADERS: &[&str] = &[
+    "memory",
+    "string",
+    "algorithm",
+    "array",
+    "cassert",
+    "cstddef",
+    "cstdint",
+    "cstring",
+    "exception",
+    "functional",
+    "initializer_list",
+    "iterator",
+    "memory",
+    "new",
+    "stdexcept",
+    "type_traits",
+    "utility",
+    "vector",
+    "sys/types.h",
+];
+
+pub fn do_cxx_cpp_generation(
+    rs: TokenStream2,
+    cpp_codegen_options: &CppCodegenOptions,
+    cxxgen_header_name: String,
+) -> Result<CppFilePair, cxx_gen::Error> {
+    let mut opt = cxx_gen::Opt::default();
+    opt.cxx_impl_annotations = cpp_codegen_options.cxx_impl_annotations.clone();
+    let cxx_generated = cxx_gen::generate_header_and_cc(rs, &opt)?;
+    Ok(CppFilePair {
+        header: strip_system_headers(
+            cxx_generated.header,
+            cpp_codegen_options.suppress_system_headers,
+        ),
+        header_name: cxxgen_header_name,
+        implementation: Some(strip_system_headers(
+            cxx_generated.implementation,
+            cpp_codegen_options.suppress_system_headers,
+        )),
+    })
+}
+
+pub(crate) fn strip_system_headers(input: Vec<u8>, suppress_system_headers: bool) -> Vec<u8> {
+    if suppress_system_headers {
+        std::str::from_utf8(&input)
+            .unwrap()
+            .lines()
+            .filter(|l| !l.starts_with("#include <"))
+            .join("\n")
+            .as_bytes()
+            .to_vec()
+    } else {
+        input
+    }
+}
+
+impl CppBuildable for IncludeCppEngine {
+    /// Generate C++-side bindings for these APIs. Call `generate` first.
+    fn generate_h_and_cxx(
+        &self,
+        cpp_codegen_options: &CppCodegenOptions,
+    ) -> Result<GeneratedCpp, cxx_gen::Error> {
+        let mut files = Vec::new();
+        match &self.state {
+            State::ParseOnly => panic!("Cannot generate C++ in parse-only mode"),
+            State::NotGenerated => panic!("Call generate() first"),
+            State::Generated(gen_results) => {
+                let rs = gen_results.item_mod.to_token_stream();
+                files.push(do_cxx_cpp_generation(
+                    rs,
+                    cpp_codegen_options,
+                    gen_results.cxxgen_header_name.clone(),
+                )?);
+                if let Some(cpp_file_pair) = &gen_results.cpp {
+                    files.push(cpp_file_pair.clone());
+                }
+            }
+        };
+        Ok(GeneratedCpp(files))
+    }
+}
+
+/// Get clang args as if we were operating clang the same way as we operate
+/// bindgen.
+pub fn make_clang_args<'a>(
+    incs: &'a [PathBuf],
+    extra_args: &'a [&str],
+) -> impl Iterator<Item = String> + 'a {
+    // AUTOCXX_CLANG_ARGS come first so that any defaults defined there(e.g. for the `-std`
+    // argument) can be overridden by extra_args.
+    AUTOCXX_CLANG_ARGS
+        .iter()
+        .map(|s| s.to_string())
+        .chain(incs.iter().map(|i| format!("-I{}", i.to_str().unwrap())))
+        .chain(extra_args.iter().map(|s| s.to_string()))
+}
+
+/// Preprocess a file using the same options
+/// as is used by autocxx. Input: listing_path, output: preprocess_path.
+pub fn preprocess(
+    listing_path: &Path,
+    preprocess_path: &Path,
+    incs: &[PathBuf],
+    extra_clang_args: &[&str],
+) -> Result<(), std::io::Error> {
+    let mut cmd = Command::new(get_clang_path());
+    cmd.arg("-E");
+    cmd.arg("-C");
+    cmd.args(make_clang_args(incs, extra_clang_args));
+    cmd.arg(listing_path.to_str().unwrap());
+    cmd.stderr(Stdio::inherit());
+    let result = cmd.output().expect("failed to execute clang++");
+    assert!(result.status.success(), "failed to preprocess");
+    let mut file = File::create(preprocess_path)?;
+    file.write_all(&result.stdout)?;
+    Ok(())
+}
+
+/// Get the path to clang which is effective for any preprocessing
+/// operations done by autocxx.
+pub fn get_clang_path() -> String {
+    // `CLANG_PATH` is the environment variable that clang-sys uses to specify
+    // the path to Clang, so in most cases where someone is using a compiler
+    // that's not on the path, things should just work. We also check `CXX`,
+    // since some users may have set that.
+    std::env::var("CLANG_PATH")
+        .or_else(|_| std::env::var("CXX"))
+        .unwrap_or_else(|_| "clang++".to_string())
+}
+
+/// Function to generate the desired name of the header containing autocxx's
+/// extra generated C++.
+/// Newtype wrapper so we can give it a [`Default`].
+pub struct AutocxxgenHeaderNamer<'a>(pub Box<dyn 'a + Fn(String) -> String>);
+
+impl Default for AutocxxgenHeaderNamer<'static> {
+    fn default() -> Self {
+        Self(Box::new(|mod_name| format!("autocxxgen_{}.h", mod_name)))
+    }
+}
+
+impl AutocxxgenHeaderNamer<'_> {
+    fn name_header(&self, mod_name: String) -> String {
+        self.0(mod_name)
+    }
+}
+
+/// Function to generate the desired name of the header containing cxx's
+/// declarations.
+/// Newtype wrapper so we can give it a [`Default`].
+pub struct CxxgenHeaderNamer<'a>(pub Box<dyn 'a + Fn() -> String>);
+
+impl Default for CxxgenHeaderNamer<'static> {
+    fn default() -> Self {
+        Self(Box::new(|| "cxxgen.h".into()))
+    }
+}
+
+impl CxxgenHeaderNamer<'_> {
+    fn name_header(&self) -> String {
+        self.0()
+    }
+}
+
+/// Options for C++ codegen
+#[derive(Default)]
+pub struct CppCodegenOptions<'a> {
+    /// Whether to avoid generating `#include <some-system-header>`.
+    /// You may wish to do this to make a hermetic test case with no
+    /// external dependencies.
+    pub suppress_system_headers: bool,
+    /// Optionally, a prefix to go at `#include "<here>cxx.h". This is a header file from the `cxx`
+    /// crate.
+    pub path_to_cxx_h: Option<String>,
+    /// Optionally, a prefix to go at `#include "<here>cxxgen.h". This is a header file which we
+    /// generate.
+    pub path_to_cxxgen_h: Option<String>,
+    /// Optionally, a function called to determine the name that will be used
+    /// for the autocxxgen.h file.
+    /// The function is passed the name of the module generated by each `include_cpp`,
+    /// configured via `name`. These will be unique.
+    pub autocxxgen_header_namer: AutocxxgenHeaderNamer<'a>,
+    /// A function to generate the name of the cxxgen.h header that should be output.
+    pub cxxgen_header_namer: CxxgenHeaderNamer<'a>,
+    /// An annotation optionally to include on each C++ function.
+    /// For example to export the symbol from a library.
+    pub cxx_impl_annotations: Option<String>,
+}
+
+fn proc_macro_span_to_miette_span(span: &proc_macro2::Span) -> SourceSpan {
+    // A proc_macro2::Span stores its location as a byte offset. But there are
+    // no APIs to get that offset out.
+    // We could use `.start()` and `.end()` to get the line + column numbers, but it appears
+    // they're a little buggy. Hence we do this, to get the offsets directly across into
+    // miette.
+    struct Err;
+    let r: Result<(usize, usize), Err> = (|| {
+        let span_desc = format!("{:?}", span);
+        let re = Regex::new(r"(\d+)..(\d+)").unwrap();
+        let captures = re.captures(&span_desc).ok_or(Err)?;
+        let start = captures.get(1).ok_or(Err)?;
+        let start: usize = start.as_str().parse().map_err(|_| Err)?;
+        let start = start.saturating_sub(1); // proc_macro::Span offsets seem to be off-by-one
+        let end = captures.get(2).ok_or(Err)?;
+        let end: usize = end.as_str().parse().map_err(|_| Err)?;
+        let end = end.saturating_sub(1); // proc_macro::Span offsets seem to be off-by-one
+        Ok((start, end.saturating_sub(start)))
+    })();
+    let (start, end) = r.unwrap_or((0, 0));
+    SourceSpan::new(SourceOffset::from(start), SourceOffset::from(end))
+}
diff --git a/engine/src/output_generators.rs b/engine/src/output_generators.rs
new file mode 100644
index 0000000..a862558
--- /dev/null
+++ b/engine/src/output_generators.rs
@@ -0,0 +1,46 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use autocxx_parser::{IncludeCppConfig, MultiBindings};
+use proc_macro2::TokenStream;
+
+/// Opaque structure representing the Rust which needs to be generated
+/// for a given `include_cpp!` macro. You will want to pass this into
+/// either [`generate_rs_single`] or [`generate_rs_archive`].
+pub struct RsOutput<'a> {
+    pub(crate) config: &'a IncludeCppConfig,
+    pub(crate) rs: TokenStream,
+}
+
+/// Creates an on-disk archive (actually a JSON file) of the Rust side of the bindings
+/// for multiple `include_cpp` macros. If you use this, you will want to tell
+/// `autocxx_macro` how to find this file using the `AUTOCXX_RS_ARCHIVE`
+/// environment variable.
+pub fn generate_rs_archive<'a>(rs_outputs: impl Iterator<Item = RsOutput<'a>>) -> String {
+    let mut multi_bindings = MultiBindings::default();
+    for rs in rs_outputs {
+        multi_bindings.insert(rs.config, rs.rs);
+    }
+    serde_json::to_string(&multi_bindings).expect("Unable to encode JSON archive")
+}
+
+/// A single Rust file to be written to disk.
+pub struct RsInclude {
+    pub code: String,
+    pub filename: String,
+}
+
+/// Gets the Rust code corresponding to a single [`RsOutput`]. You can write this
+/// to a file which can simply be `include!`ed by `autocxx_macro` when you give
+/// it the `AUTOCXX_RS_FILE` environment variable.
+pub fn generate_rs_single(rs_output: RsOutput) -> RsInclude {
+    RsInclude {
+        code: rs_output.rs.to_string(),
+        filename: rs_output.config.get_rs_filename(),
+    }
+}
diff --git a/engine/src/parse_callbacks.rs b/engine/src/parse_callbacks.rs
new file mode 100644
index 0000000..61098c0
--- /dev/null
+++ b/engine/src/parse_callbacks.rs
@@ -0,0 +1,23 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::panic::UnwindSafe;
+
+use crate::RebuildDependencyRecorder;
+use autocxx_bindgen::callbacks::ParseCallbacks;
+
+#[derive(Debug)]
+pub(crate) struct AutocxxParseCallbacks(pub(crate) Box<dyn RebuildDependencyRecorder>);
+
+impl UnwindSafe for AutocxxParseCallbacks {}
+
+impl ParseCallbacks for AutocxxParseCallbacks {
+    fn include_file(&self, filename: &str) {
+        self.0.record_header_file_dependency(filename);
+    }
+}
diff --git a/engine/src/parse_file.rs b/engine/src/parse_file.rs
new file mode 100644
index 0000000..3571d19
--- /dev/null
+++ b/engine/src/parse_file.rs
@@ -0,0 +1,414 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use crate::ast_discoverer::{Discoveries, DiscoveryErr};
+use crate::output_generators::RsOutput;
+use crate::{
+    cxxbridge::CxxBridge, Error as EngineError, GeneratedCpp, IncludeCppEngine,
+    RebuildDependencyRecorder,
+};
+use crate::{CppCodegenOptions, LocatedSynError};
+use autocxx_parser::directive_names::SUBCLASS;
+use autocxx_parser::{AllowlistEntry, RustPath, Subclass, SubclassAttrs};
+use indexmap::set::IndexSet as HashSet;
+use miette::Diagnostic;
+use quote::ToTokens;
+use std::{io::Read, path::PathBuf};
+use std::{panic::UnwindSafe, path::Path, rc::Rc};
+use syn::{token::Brace, Item, ItemMod};
+use thiserror::Error;
+
+/// Errors which may occur when parsing a Rust source file to discover
+/// and interpret include_cxx macros.
+#[derive(Error, Diagnostic, Debug)]
+pub enum ParseError {
+    #[error("unable to open the source file: {0}")]
+    FileOpen(std::io::Error),
+    #[error("the .rs file couldn't be read: {0}")]
+    FileRead(std::io::Error),
+    #[error("syntax error interpreting Rust code: {0}")]
+    #[diagnostic(transparent)]
+    Syntax(LocatedSynError),
+    #[error("generate!/generate_ns! was used at the same time as generate_all!")]
+    ConflictingAllowlist,
+    #[error("the subclass attribute couldn't be parsed: {0}")]
+    #[diagnostic(transparent)]
+    SubclassSyntax(LocatedSynError),
+    /// The include CPP macro could not be expanded into
+    /// Rust bindings to C++, because of some problem during the conversion
+    /// process. This could be anything from a C++ parsing error to some
+    /// C++ feature that autocxx can't yet handle and isn't able to skip
+    /// over. It could also cover errors in your syntax of the `include_cpp`
+    /// macro or the directives inside.
+    #[error("the include_cpp! macro couldn't be expanded into Rust bindings to C++: {0}")]
+    #[diagnostic(transparent)]
+    AutocxxCodegenError(EngineError),
+    /// There are two or more `include_cpp` macros with the same
+    /// mod name.
+    #[error("there are two or more include_cpp! mods with the same mod name")]
+    ConflictingModNames,
+    #[error("dynamic discovery was enabled but no mod was found")]
+    ZeroModsForDynamicDiscovery,
+    #[error("dynamic discovery was enabled but multiple mods were found")]
+    MultipleModsForDynamicDiscovery,
+    #[error("a problem occurred while discovering C++ APIs used within the Rust: {0}")]
+    Discovery(DiscoveryErr),
+}
+
+/// Parse a Rust file, and spot any include_cpp macros within it.
+pub fn parse_file<P1: AsRef<Path>>(
+    rs_file: P1,
+    auto_allowlist: bool,
+) -> Result<ParsedFile, ParseError> {
+    let mut source_code = String::new();
+    let mut file = std::fs::File::open(rs_file).map_err(ParseError::FileOpen)?;
+    file.read_to_string(&mut source_code)
+        .map_err(ParseError::FileRead)?;
+    proc_macro2::fallback::force();
+    let source = syn::parse_file(&source_code)
+        .map_err(|e| ParseError::Syntax(LocatedSynError::new(e, &source_code)))?;
+    parse_file_contents(source, auto_allowlist, &source_code)
+}
+
+fn parse_file_contents(
+    source: syn::File,
+    auto_allowlist: bool,
+    file_contents: &str,
+) -> Result<ParsedFile, ParseError> {
+    #[derive(Default)]
+    struct State {
+        auto_allowlist: bool,
+        results: Vec<Segment>,
+        extra_superclasses: Vec<Subclass>,
+        discoveries: Discoveries,
+    }
+    impl State {
+        fn parse_item(
+            &mut self,
+            item: Item,
+            mod_path: Option<RustPath>,
+            file_contents: &str,
+        ) -> Result<(), ParseError> {
+            let result = match item {
+                Item::Macro(mac)
+                    if mac
+                        .mac
+                        .path
+                        .segments
+                        .last()
+                        .map(|s| s.ident == "include_cpp")
+                        .unwrap_or(false) =>
+                {
+                    Segment::Autocxx(
+                        crate::IncludeCppEngine::new_from_syn(mac.mac, file_contents)
+                            .map_err(ParseError::AutocxxCodegenError)?,
+                    )
+                }
+                Item::Mod(itm)
+                    if itm
+                        .attrs
+                        .iter()
+                        .any(|attr| attr.path.to_token_stream().to_string() == "cxx :: bridge") =>
+                {
+                    Segment::Cxx(CxxBridge::from(itm))
+                }
+                Item::Mod(itm) => {
+                    if let Some((brace, items)) = itm.content {
+                        let mut mod_state = State {
+                            auto_allowlist: self.auto_allowlist,
+                            ..Default::default()
+                        };
+                        let mod_path = match &mod_path {
+                            None => RustPath::new_from_ident(itm.ident.clone()),
+                            Some(mod_path) => mod_path.append(itm.ident.clone()),
+                        };
+                        for item in items {
+                            mod_state.parse_item(item, Some(mod_path.clone()), file_contents)?
+                        }
+                        self.extra_superclasses.extend(mod_state.extra_superclasses);
+                        self.discoveries.extend(mod_state.discoveries);
+                        Segment::Mod(
+                            mod_state.results,
+                            (
+                                brace,
+                                ItemMod {
+                                    content: None,
+                                    ..itm
+                                },
+                            ),
+                        )
+                    } else {
+                        Segment::Other(Item::Mod(itm))
+                    }
+                }
+                Item::Struct(ref its) if self.auto_allowlist => {
+                    let attrs = &its.attrs;
+                    let is_superclass_attr = attrs.iter().find(|attr| {
+                        attr.path
+                            .segments
+                            .last()
+                            .map(|seg| seg.ident == "is_subclass" || seg.ident == SUBCLASS)
+                            .unwrap_or(false)
+                    });
+                    if let Some(is_superclass_attr) = is_superclass_attr {
+                        if !is_superclass_attr.tokens.is_empty() {
+                            let subclass = its.ident.clone();
+                            let args: SubclassAttrs =
+                                is_superclass_attr.parse_args().map_err(|e| {
+                                    ParseError::SubclassSyntax(LocatedSynError::new(
+                                        e,
+                                        file_contents,
+                                    ))
+                                })?;
+                            if let Some(superclass) = args.superclass {
+                                self.extra_superclasses.push(Subclass {
+                                    superclass,
+                                    subclass,
+                                })
+                            }
+                        }
+                    }
+                    self.discoveries
+                        .search_item(&item, mod_path)
+                        .map_err(ParseError::Discovery)?;
+                    Segment::Other(item)
+                }
+                _ => {
+                    self.discoveries
+                        .search_item(&item, mod_path)
+                        .map_err(ParseError::Discovery)?;
+                    Segment::Other(item)
+                }
+            };
+            self.results.push(result);
+            Ok(())
+        }
+    }
+    let mut state = State {
+        auto_allowlist,
+        ..Default::default()
+    };
+    for item in source.items {
+        state.parse_item(item, None, file_contents)?
+    }
+    let State {
+        auto_allowlist,
+        mut results,
+        mut extra_superclasses,
+        mut discoveries,
+    } = state;
+
+    let must_handle_discovered_things = discoveries.found_rust()
+        || !extra_superclasses.is_empty()
+        || (auto_allowlist && discoveries.found_allowlist());
+
+    // We do not want to enter this 'if' block unless the above conditions are true,
+    // since we may emit errors.
+    if must_handle_discovered_things {
+        let mut autocxx_seg_iterator = results.iter_mut().filter_map(|seg| match seg {
+            Segment::Autocxx(engine) => Some(engine),
+            _ => None,
+        });
+        let our_seg = autocxx_seg_iterator.next();
+        match our_seg {
+            None => return Err(ParseError::ZeroModsForDynamicDiscovery),
+            Some(engine) => {
+                engine
+                    .config_mut()
+                    .subclasses
+                    .append(&mut extra_superclasses);
+                if auto_allowlist {
+                    for cpp in discoveries.cpp_list {
+                        engine
+                            .config_mut()
+                            .allowlist
+                            .push(AllowlistEntry::Item(cpp))
+                            .map_err(|_| ParseError::ConflictingAllowlist)?;
+                    }
+                }
+                engine
+                    .config_mut()
+                    .extern_rust_funs
+                    .append(&mut discoveries.extern_rust_funs);
+                engine
+                    .config_mut()
+                    .rust_types
+                    .append(&mut discoveries.extern_rust_types);
+            }
+        }
+        if autocxx_seg_iterator.next().is_some() {
+            return Err(ParseError::MultipleModsForDynamicDiscovery);
+        }
+    }
+    let autocxx_seg_iterator = results.iter_mut().filter_map(|seg| match seg {
+        Segment::Autocxx(engine) => Some(engine),
+        _ => None,
+    });
+    for seg in autocxx_seg_iterator {
+        seg.config.confirm_complete();
+    }
+    Ok(ParsedFile(results))
+}
+
+/// A Rust file parsed by autocxx. May contain zero or more autocxx 'engines',
+/// i.e. the `IncludeCpp` class, corresponding to zero or more include_cpp
+/// macros within this file. Also contains `syn::Item` structures for all
+/// the rest of the Rust code, such that it can be reconstituted if necessary.
+pub struct ParsedFile(Vec<Segment>);
+
+#[allow(clippy::large_enum_variant)]
+enum Segment {
+    Autocxx(IncludeCppEngine),
+    Cxx(CxxBridge),
+    Mod(Vec<Segment>, (Brace, ItemMod)),
+    Other(Item),
+}
+
+pub trait CppBuildable {
+    fn generate_h_and_cxx(
+        &self,
+        cpp_codegen_options: &CppCodegenOptions,
+    ) -> Result<GeneratedCpp, cxx_gen::Error>;
+}
+
+impl ParsedFile {
+    /// Get all the autocxx `include_cpp` macros found in this file.
+    pub fn get_autocxxes(&self) -> impl Iterator<Item = &IncludeCppEngine> {
+        fn do_get_autocxxes(segments: &[Segment]) -> impl Iterator<Item = &IncludeCppEngine> {
+            segments
+                .iter()
+                .flat_map(|s| -> Box<dyn Iterator<Item = &IncludeCppEngine>> {
+                    match s {
+                        Segment::Autocxx(includecpp) => Box::new(std::iter::once(includecpp)),
+                        Segment::Mod(segments, _) => Box::new(do_get_autocxxes(segments)),
+                        _ => Box::new(std::iter::empty()),
+                    }
+                })
+        }
+
+        do_get_autocxxes(&self.0)
+    }
+
+    /// Get all the areas of Rust code which need to be built for these bindings.
+    /// A shortcut for `get_autocxxes()` then calling `get_rs_output` on each.
+    pub fn get_rs_outputs(&self) -> impl Iterator<Item = RsOutput> {
+        self.get_autocxxes().map(|autocxx| autocxx.get_rs_output())
+    }
+
+    /// Get all items which can result in C++ code
+    pub fn get_cpp_buildables(&self) -> impl Iterator<Item = &dyn CppBuildable> {
+        fn do_get_cpp_buildables(segments: &[Segment]) -> impl Iterator<Item = &dyn CppBuildable> {
+            segments
+                .iter()
+                .flat_map(|s| -> Box<dyn Iterator<Item = &dyn CppBuildable>> {
+                    match s {
+                        Segment::Autocxx(includecpp) => {
+                            Box::new(std::iter::once(includecpp as &dyn CppBuildable))
+                        }
+                        Segment::Cxx(cxxbridge) => {
+                            Box::new(std::iter::once(cxxbridge as &dyn CppBuildable))
+                        }
+                        Segment::Mod(segments, _) => Box::new(do_get_cpp_buildables(segments)),
+                        _ => Box::new(std::iter::empty()),
+                    }
+                })
+        }
+
+        do_get_cpp_buildables(&self.0)
+    }
+
+    fn get_autocxxes_mut(&mut self) -> impl Iterator<Item = &mut IncludeCppEngine> {
+        fn do_get_autocxxes_mut(
+            segments: &mut [Segment],
+        ) -> impl Iterator<Item = &mut IncludeCppEngine> {
+            segments
+                .iter_mut()
+                .flat_map(|s| -> Box<dyn Iterator<Item = &mut IncludeCppEngine>> {
+                    match s {
+                        Segment::Autocxx(includecpp) => Box::new(std::iter::once(includecpp)),
+                        Segment::Mod(segments, _) => Box::new(do_get_autocxxes_mut(segments)),
+                        _ => Box::new(std::iter::empty()),
+                    }
+                })
+        }
+
+        do_get_autocxxes_mut(&mut self.0)
+    }
+
+    /// Determines the include dirs that were set for each include_cpp, so they can be
+    /// used as input to a `cc::Build`.
+    #[cfg(any(test, feature = "build"))]
+    pub(crate) fn include_dirs(&self) -> impl Iterator<Item = &PathBuf> {
+        fn do_get_include_dirs(segments: &[Segment]) -> impl Iterator<Item = &PathBuf> {
+            segments
+                .iter()
+                .flat_map(|s| -> Box<dyn Iterator<Item = &PathBuf>> {
+                    match s {
+                        Segment::Autocxx(includecpp) => Box::new(includecpp.include_dirs()),
+                        Segment::Mod(segments, _) => Box::new(do_get_include_dirs(segments)),
+                        _ => Box::new(std::iter::empty()),
+                    }
+                })
+        }
+
+        do_get_include_dirs(&self.0)
+    }
+
+    pub fn resolve_all(
+        &mut self,
+        autocxx_inc: Vec<PathBuf>,
+        extra_clang_args: &[&str],
+        dep_recorder: Option<Box<dyn RebuildDependencyRecorder>>,
+        cpp_codegen_options: &CppCodegenOptions,
+    ) -> Result<(), ParseError> {
+        let mut mods_found = HashSet::new();
+        let inner_dep_recorder: Option<Rc<dyn RebuildDependencyRecorder>> =
+            dep_recorder.map(Rc::from);
+        for include_cpp in self.get_autocxxes_mut() {
+            #[allow(clippy::manual_map)] // because of dyn shenanigans
+            let dep_recorder: Option<Box<dyn RebuildDependencyRecorder>> = match &inner_dep_recorder
+            {
+                None => None,
+                Some(inner_dep_recorder) => Some(Box::new(CompositeDepRecorder::new(
+                    inner_dep_recorder.clone(),
+                ))),
+            };
+            if !mods_found.insert(include_cpp.get_mod_name()) {
+                return Err(ParseError::ConflictingModNames);
+            }
+            include_cpp
+                .generate(
+                    autocxx_inc.clone(),
+                    extra_clang_args,
+                    dep_recorder,
+                    cpp_codegen_options,
+                )
+                .map_err(ParseError::AutocxxCodegenError)?
+        }
+        Ok(())
+    }
+}
+
+/// Shenanigans required to share the same RebuildDependencyRecorder
+/// with all of the include_cpp instances in this one file.
+#[derive(Debug, Clone)]
+struct CompositeDepRecorder(Rc<dyn RebuildDependencyRecorder>);
+
+impl CompositeDepRecorder {
+    fn new(inner: Rc<dyn RebuildDependencyRecorder>) -> Self {
+        CompositeDepRecorder(inner)
+    }
+}
+
+impl UnwindSafe for CompositeDepRecorder {}
+
+impl RebuildDependencyRecorder for CompositeDepRecorder {
+    fn record_header_file_dependency(&self, filename: &str) {
+        self.0.record_header_file_dependency(filename);
+    }
+}
diff --git a/engine/src/rust_pretty_printer.rs b/engine/src/rust_pretty_printer.rs
new file mode 100644
index 0000000..9c23cbc
--- /dev/null
+++ b/engine/src/rust_pretty_printer.rs
@@ -0,0 +1,40 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use proc_macro2::TokenStream;
+use std::io::Write;
+use std::process::{Command, Stdio};
+
+enum Error {
+    Run(std::io::Error),
+    Write(std::io::Error),
+    Utf8(std::string::FromUtf8Error),
+    Wait(std::io::Error),
+}
+
+pub(crate) fn pretty_print(ts: &TokenStream) -> String {
+    reformat_or_else(ts.to_string())
+}
+
+fn reformat_or_else(text: impl std::fmt::Display) -> String {
+    match reformat(&text) {
+        Ok(s) => s,
+        Err(_) => text.to_string(),
+    }
+}
+
+fn reformat(text: impl std::fmt::Display) -> Result<String, Error> {
+    let mut rustfmt = Command::new("rustfmt")
+        .stdin(Stdio::piped())
+        .stdout(Stdio::piped())
+        .spawn()
+        .map_err(Error::Run)?;
+    write!(rustfmt.stdin.take().unwrap(), "{}", text).map_err(Error::Write)?;
+    let output = rustfmt.wait_with_output().map_err(Error::Wait)?;
+    String::from_utf8(output.stdout).map_err(Error::Utf8)
+}
diff --git a/engine/src/types.rs b/engine/src/types.rs
new file mode 100644
index 0000000..0d11895
--- /dev/null
+++ b/engine/src/types.rs
@@ -0,0 +1,259 @@
+// Copyright 2020 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use itertools::Itertools;
+use proc_macro2::Span;
+use quote::ToTokens;
+use std::iter::Peekable;
+use std::{fmt::Display, sync::Arc};
+use syn::{parse_quote, Ident, PathSegment, TypePath};
+
+use crate::{conversion::ConvertError, known_types::known_types};
+
+pub(crate) fn make_ident<S: AsRef<str>>(id: S) -> Ident {
+    Ident::new(id.as_ref(), Span::call_site())
+}
+
+/// Newtype wrapper for a C++ namespace.
+#[derive(Debug, PartialEq, PartialOrd, Eq, Hash, Clone)]
+#[allow(clippy::rc_buffer)]
+pub struct Namespace(Arc<Vec<String>>);
+
+impl Namespace {
+    pub(crate) fn new() -> Self {
+        Self(Arc::new(Vec::new()))
+    }
+
+    #[must_use]
+    pub(crate) fn push(&self, segment: String) -> Self {
+        let mut bigger = (*self.0).clone();
+        bigger.push(segment);
+        Namespace(Arc::new(bigger))
+    }
+
+    pub(crate) fn is_empty(&self) -> bool {
+        self.0.is_empty()
+    }
+
+    pub(crate) fn iter(&self) -> impl Iterator<Item = &String> {
+        self.0.iter()
+    }
+
+    #[cfg(test)]
+    pub(crate) fn from_user_input(input: &str) -> Self {
+        Self(Arc::new(input.split("::").map(|x| x.to_string()).collect()))
+    }
+
+    pub(crate) fn depth(&self) -> usize {
+        self.0.len()
+    }
+}
+
+impl Display for Namespace {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.write_str(&self.0.join("::"))
+    }
+}
+
+impl<'a> IntoIterator for &'a Namespace {
+    type Item = &'a String;
+
+    type IntoIter = std::slice::Iter<'a, String>;
+
+    fn into_iter(self) -> Self::IntoIter {
+        self.0.iter()
+    }
+}
+
+/// Any time we store a qualified name, we should use this. Stores the type
+/// and its namespace. Namespaces should be stored without any
+/// 'bindgen::root' prefix; that means a type not in any C++
+/// namespace should have an empty namespace segment list.
+/// Some types have names that change as they flow through the
+/// autocxx pipeline. e.g. you start with std::string
+/// and end up with CxxString. This TypeName type can store
+/// either. It doesn't directly have functionality to convert
+/// from one to the other; `replace_type_path_without_arguments`
+/// does that.
+#[derive(Debug, PartialEq, PartialOrd, Eq, Hash, Clone)]
+pub struct QualifiedName(Namespace, String);
+
+impl QualifiedName {
+    /// From a TypePath which starts with 'root'
+    pub(crate) fn from_type_path(typ: &TypePath) -> Self {
+        let mut seg_iter = typ.path.segments.iter().peekable();
+        let first_seg = seg_iter.next().unwrap().ident.clone();
+        if first_seg == "root" {
+            // This is a C++ type prefixed with a namespace,
+            // e.g. std::string or something the user has defined.
+            Self::from_segments(seg_iter) // all but 'root'
+        } else {
+            // This is actually a Rust type e.g.
+            // std::os::raw::c_ulong. Start iterating from the beginning again.
+            Self::from_segments(typ.path.segments.iter().peekable())
+        }
+    }
+
+    fn from_segments<'a, T: Iterator<Item = &'a PathSegment>>(mut seg_iter: Peekable<T>) -> Self {
+        let mut ns = Namespace::new();
+        while let Some(seg) = seg_iter.next() {
+            if seg_iter.peek().is_some() {
+                ns = ns.push(seg.ident.to_string());
+            } else {
+                return Self(ns, seg.ident.to_string());
+            }
+        }
+        unreachable!()
+    }
+
+    /// Create from a type encountered in the code.
+    pub(crate) fn new(ns: &Namespace, id: Ident) -> Self {
+        Self(ns.clone(), id.to_string())
+    }
+
+    /// Create from user input, e.g. a name in an AllowPOD directive.
+    pub(crate) fn new_from_cpp_name(id: &str) -> Self {
+        let mut seg_iter = id.split("::").peekable();
+        let mut ns = Namespace::new();
+        while let Some(seg) = seg_iter.next() {
+            if seg_iter.peek().is_some() {
+                if !seg.to_string().is_empty() {
+                    ns = ns.push(seg.to_string());
+                }
+            } else {
+                return Self(ns, seg.to_string());
+            }
+        }
+        unreachable!()
+    }
+
+    /// Return the actual type name, without any namespace
+    /// qualification. Avoid unless you have a good reason.
+    pub(crate) fn get_final_item(&self) -> &str {
+        &self.1
+    }
+
+    /// cxx doesn't accept names containing double underscores,
+    /// but these are OK elsewhere in our output mod.
+    pub(crate) fn validate_ok_for_cxx(&self) -> Result<(), ConvertError> {
+        validate_ident_ok_for_cxx(self.get_final_item())
+    }
+
+    /// Return the actual type name as an [Ident], without any namespace
+    /// qualification. Avoid unless you have a good reason.
+    pub(crate) fn get_final_ident(&self) -> Ident {
+        make_ident(self.get_final_item())
+    }
+
+    pub(crate) fn get_namespace(&self) -> &Namespace {
+        &self.0
+    }
+
+    pub(crate) fn get_bindgen_path_idents(&self) -> Vec<Ident> {
+        ["bindgen", "root"]
+            .iter()
+            .map(make_ident)
+            .chain(self.ns_segment_iter().map(make_ident))
+            .chain(std::iter::once(self.get_final_ident()))
+            .collect()
+    }
+
+    /// Output the fully-qualified C++ name of this type.
+    pub(crate) fn to_cpp_name(&self) -> String {
+        let special_cpp_name = known_types().special_cpp_name(self);
+        match special_cpp_name {
+            Some(name) => name,
+            None => self.0.iter().chain(std::iter::once(&self.1)).join("::"),
+        }
+    }
+
+    pub(crate) fn get_final_cpp_item(&self) -> String {
+        let special_cpp_name = known_types().special_cpp_name(self);
+        match special_cpp_name {
+            Some(name) => name,
+            None => self.1.to_string(),
+        }
+    }
+
+    pub(crate) fn to_type_path(&self) -> TypePath {
+        if let Some(known_type_path) = known_types().known_type_type_path(self) {
+            known_type_path
+        } else {
+            let root = "root".to_string();
+            let segs = std::iter::once(&root)
+                .chain(self.ns_segment_iter())
+                .chain(std::iter::once(&self.1))
+                .map(make_ident);
+            parse_quote! {
+                #(#segs)::*
+            }
+        }
+    }
+
+    /// Iterator over segments in the namespace of this name.
+    pub(crate) fn ns_segment_iter(&self) -> impl Iterator<Item = &String> {
+        self.0.iter()
+    }
+
+    /// Iterate over all segments of this name.
+    pub(crate) fn segment_iter(&self) -> impl Iterator<Item = String> + '_ {
+        self.ns_segment_iter()
+            .cloned()
+            .chain(std::iter::once(self.get_final_item().to_string()))
+    }
+}
+
+impl Display for QualifiedName {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        for seg in &self.0 {
+            f.write_str(seg)?;
+            f.write_str("::")?;
+        }
+        f.write_str(&self.1)
+    }
+}
+
+/// cxx doesn't allow identifiers containing __. These are OK elsewhere
+/// in our output mod. It would be nice in future to think of a way we
+/// can enforce this using the Rust type system, e.g. a newtype
+/// wrapper for a CxxCompatibleIdent which is used in any context
+/// where code will be output as part of the `#[cxx::bridge]` mod.
+pub fn validate_ident_ok_for_cxx(id: &str) -> Result<(), ConvertError> {
+    validate_ident_ok_for_rust(id)?;
+    if id.contains("__") {
+        Err(ConvertError::TooManyUnderscores)
+    } else if id.starts_with("_bindgen_ty_") {
+        Err(ConvertError::BindgenTy)
+    } else {
+        Ok(())
+    }
+}
+
+pub fn validate_ident_ok_for_rust(label: &str) -> Result<(), ConvertError> {
+    let id = make_ident(label);
+    syn::parse2::<syn::Ident>(id.into_token_stream())
+        .map_err(|_| ConvertError::ReservedName(label.to_string()))
+        .map(|_| ())
+}
+
+#[cfg(test)]
+mod tests {
+    use super::QualifiedName;
+
+    #[test]
+    fn test_ints() {
+        assert_eq!(
+            QualifiedName::new_from_cpp_name("i8").to_cpp_name(),
+            "int8_t"
+        );
+        assert_eq!(
+            QualifiedName::new_from_cpp_name("u64").to_cpp_name(),
+            "uint64_t"
+        );
+    }
+}
