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"
+        );
+    }
+}
