Snap for 6439596 from e1c27fbb652359e38f38e41ee173366b50e1466c to qt-aml-tzdata-release

Change-Id: If509b9ec0bcfa8c3709ffd86b7d752bb467c960d
diff --git a/Android.bp b/Android.bp
index 9a59d4d..14f2d00 100644
--- a/Android.bp
+++ b/Android.bp
@@ -30,12 +30,6 @@
         windows: {
             enabled: true,
         },
-        host: {
-            cflags: [
-                "-O0",
-                "-g",
-            ],
-        },
     },
 }
 
@@ -48,7 +42,6 @@
     srcs: [
         "aidl.cpp",
         "aidl_apicheck.cpp",
-        "aidl_const_expressions.cpp",
         "aidl_language.cpp",
         "aidl_language_l.ll",
         "aidl_language_y.yy",
@@ -69,11 +62,10 @@
         "line_reader.cpp",
         "io_delegate.cpp",
         "options.cpp",
+        "type_cpp.cpp",
+        "type_java.cpp",
+        "type_namespace.cpp",
     ],
-    yacc: {
-        gen_location_hh: true,
-        gen_position_hh: true,
-    },
 }
 
 // aidl executable
@@ -110,6 +102,7 @@
         "-Wextra",
         "-Werror",
         "-g",
+        "-DUNIT_TEST",
     ],
 
     srcs: [
@@ -127,63 +120,33 @@
         "tests/test_data_ping_responder.cpp",
         "tests/test_data_string_constants.cpp",
         "tests/test_util.cpp",
+        "type_cpp_unittest.cpp",
+        "type_java_unittest.cpp",
     ],
 
     static_libs: [
         "libaidl-common",
         "libbase",
         "libcutils",
-        "libgmock",
     ],
     target: {
+        host: {
+            static_libs: ["libgmock_host"],
+        },
         android: {
             static_libs: [
+                "libgmock",
                 "liblog",
             ],
         },
     },
 }
 
-cc_fuzz {
-    name: "aidl_parser_fuzzer",
-    host_supported: true,
-    dictionary: "tests/aidl_parser_fuzzer.dict",
-
-    fuzz_config: {
-        cc: [
-            "smoreland@google.com",
-            "jiyong@google.com",
-            "jeongik@google.com",
-        ],
-    },
-
-    srcs: [
-        "tests/aidl_parser_fuzzer.cpp",
-        "tests/fake_io_delegate.cpp",
-        "tests/test_util.cpp",
-    ],
-    static_libs: [
-        "libaidl-common",
-        "libbase",
-        "libcutils",
-    ],
-    target: {
-        android: {
-            static_libs: [
-                "liblog",
-            ],
-        },
-    },
-    // Enable this to show additional information about what is being parsed during fuzzing.
-    // cflags: ["-DFUZZ_LOG"],
-}
-
 //
 // Everything below here is used for integration testing of generated AIDL code.
 //
-cc_test {
+cc_binary {
     name: "aidl_test_sentinel_searcher",
-    gtest: false,
     srcs: ["tests/aidl_test_sentinel_searcher.cpp"],
     cflags: [
         "-Wall",
@@ -207,13 +170,7 @@
     ],
 }
 
-filegroup {
-    name: "libaidl-integration-test-files",
-    srcs: ["tests/android/aidl/tests/*.aidl"],
-    path: "tests",
-}
-
-cc_library_static {
+cc_library_shared {
     name: "libaidl-integration-test",
     defaults: ["aidl_test_defaults"],
     aidl: {
@@ -222,24 +179,22 @@
         include_dirs: ["frameworks/native/aidl/binder"],
     },
     srcs: [
-        ":libaidl-integration-test-files",
+        "tests/android/aidl/tests/*.aidl",
         "tests/simple_parcelable.cpp",
     ],
 }
 
-cc_test {
+cc_binary {
     name: "aidl_test_service",
-    gtest: false,
     defaults: ["aidl_test_defaults"],
-    static_libs: ["libaidl-integration-test"],
+    shared_libs: ["libaidl-integration-test"],
     srcs: ["tests/aidl_test_service.cpp"],
 }
 
-cc_test {
+cc_binary {
     name: "aidl_test_client",
-    gtest: false,
     defaults: ["aidl_test_defaults"],
-    static_libs: ["libaidl-integration-test"],
+    shared_libs: ["libaidl-integration-test"],
     srcs: [
         "tests/aidl_test_client.cpp",
         "tests/aidl_test_client_file_descriptors.cpp",
@@ -266,7 +221,9 @@
     manifest: "tests/java_app/AndroidManifest.xml",
     resource_dirs: ["tests/java_app/resources"],
     srcs: [
-        "tests/android/aidl/tests/*.aidl",
+        "tests/android/aidl/tests/ITestService.aidl",
+        "tests/android/aidl/tests/INamedCallback.aidl",
+        "tests/android/aidl/tests/StructuredParcelable.aidl",
         "tests/java_app/src/android/aidl/tests/NullableTests.java",
         "tests/java_app/src/android/aidl/tests/SimpleParcelable.java",
         "tests/java_app/src/android/aidl/tests/TestFailException.java",
diff --git a/aidl.cpp b/aidl.cpp
index b0e2489..25609c0 100644
--- a/aidl.cpp
+++ b/aidl.cpp
@@ -46,6 +46,9 @@
 #include "logging.h"
 #include "options.h"
 #include "os.h"
+#include "type_cpp.h"
+#include "type_java.h"
+#include "type_namespace.h"
 
 #ifndef O_BINARY
 #  define O_BINARY  0
@@ -149,6 +152,62 @@
     return valid;
 }
 
+bool register_types(const AidlStructuredParcelable* parcel, TypeNamespace* types) {
+  for (const auto& v : parcel->GetFields()) {
+    if (!types->MaybeAddContainerType(v->GetType())) {
+      return false;
+    }
+
+    const ValidatableType* type = types->GetReturnType(v->GetType(), *parcel);
+    if (type == nullptr) {
+      return false;
+    }
+    v->GetMutableType()->SetLanguageType(type);
+  }
+  return true;
+}
+
+bool register_types(const AidlInterface* c, TypeNamespace* types) {
+  for (const auto& m : c->GetMethods()) {
+    if (!types->MaybeAddContainerType(m->GetType())) {
+      return false;
+    }
+
+    const ValidatableType* return_type = types->GetReturnType(m->GetType(), *c);
+
+    if (return_type == nullptr) {
+      return false;
+    }
+    m->GetMutableType()->SetLanguageType(return_type);
+
+    set<string> argument_names;
+
+    int index = 1;
+    for (const auto& arg : m->GetArguments()) {
+      if (!types->MaybeAddContainerType(arg->GetType())) {
+        return false;
+      }
+
+      const ValidatableType* arg_type = types->GetArgType(*arg, index, *c);
+      if (arg_type == nullptr) {
+        return false;
+      }
+      arg->GetMutableType()->SetLanguageType(arg_type);
+    }
+  }
+
+  for (const std::unique_ptr<AidlConstantDeclaration>& constant : c->GetConstantDeclarations()) {
+    AidlTypeSpecifier* specifier = constant->GetMutableType();
+    const ValidatableType* return_type = types->GetReturnType(*specifier, *c);
+    if (return_type == nullptr) {
+      return false;
+    }
+    specifier->SetLanguageType(return_type);
+  }
+
+  return true;
+}
+
 bool write_dep_file(const Options& options, const AidlDefinedType& defined_type,
                     const vector<string>& imports, const IoDelegate& io_delegate,
                     const string& input_file, const string& output_file) {
@@ -253,7 +312,6 @@
   set<int> usedIds;
   bool hasUnassignedIds = false;
   bool hasAssignedIds = false;
-  int newId = kMinUserSetMethodId;
   for (const auto& item : items) {
     // However, meta transactions that are added by the AIDL compiler are
     // exceptions. They have fixed IDs but allowed to be with user-defined
@@ -266,34 +324,40 @@
     }
     if (item->HasId()) {
       hasAssignedIds = true;
+      // Ensure that the user set id is not duplicated.
+      if (usedIds.find(item->GetId()) != usedIds.end()) {
+        // We found a duplicate id, so throw an error.
+        AIDL_ERROR(item) << "Found duplicate method id (" << item->GetId() << ") for method "
+                         << item->GetName();
+        return false;
+      }
+      // Ensure that the user set id is within the appropriate limits
+      if (item->GetId() < kMinUserSetMethodId || item->GetId() > kMaxUserSetMethodId) {
+        AIDL_ERROR(item) << "Found out of bounds id (" << item->GetId() << ") for method "
+                         << item->GetName() << ". Value for id must be between "
+                         << kMinUserSetMethodId << " and " << kMaxUserSetMethodId << " inclusive.";
+        return false;
+      }
+      usedIds.insert(item->GetId());
     } else {
-      item->SetId(newId++);
       hasUnassignedIds = true;
     }
-
     if (hasAssignedIds && hasUnassignedIds) {
       AIDL_ERROR(item) << "You must either assign id's to all methods or to none of them.";
       return false;
     }
-
-    // Ensure that the user set id is not duplicated.
-    if (usedIds.find(item->GetId()) != usedIds.end()) {
-      // We found a duplicate id, so throw an error.
-      AIDL_ERROR(item) << "Found duplicate method id (" << item->GetId() << ") for method "
-                       << item->GetName();
-      return false;
-    }
-    usedIds.insert(item->GetId());
-
-    // Ensure that the user set id is within the appropriate limits
-    if (item->GetId() < kMinUserSetMethodId || item->GetId() > kMaxUserSetMethodId) {
-      AIDL_ERROR(item) << "Found out of bounds id (" << item->GetId() << ") for method "
-                       << item->GetName() << ". Value for id must be between "
-                       << kMinUserSetMethodId << " and " << kMaxUserSetMethodId << " inclusive.";
-      return false;
-    }
   }
 
+  // In the case that all methods have unassigned id's, set a unique id for them.
+  if (hasUnassignedIds) {
+    int newId = kMinUserSetMethodId;
+    for (const auto& item : items) {
+      assert(newId <= kMaxUserSetMethoId);
+      if (item->IsUserDefined()) {
+        item->SetId(newId++);
+      }
+    }
+  }
   return true;
 }
 
@@ -347,7 +411,7 @@
 namespace internals {
 
 bool parse_preprocessed_file(const IoDelegate& io_delegate, const string& filename,
-                             AidlTypenames* typenames) {
+                             TypeNamespace* types, AidlTypenames& typenames) {
   bool success = true;
   unique_ptr<LineReader> line_reader = io_delegate.GetLineReader(filename);
   if (!line_reader) {
@@ -384,17 +448,20 @@
       }
       AidlParcelable* doc = new AidlParcelable(
           location, new AidlQualifiedName(location, class_name, ""), package, "" /* comments */);
-      typenames->AddPreprocessedType(unique_ptr<AidlParcelable>(doc));
+      types->AddParcelableType(*doc, filename);
+      typenames.AddPreprocessedType(unique_ptr<AidlParcelable>(doc));
     } else if (decl == "structured_parcelable") {
       auto temp = new std::vector<std::unique_ptr<AidlVariableDeclaration>>();
       AidlStructuredParcelable* doc =
           new AidlStructuredParcelable(location, new AidlQualifiedName(location, class_name, ""),
                                        package, "" /* comments */, temp);
-      typenames->AddPreprocessedType(unique_ptr<AidlStructuredParcelable>(doc));
+      types->AddParcelableType(*doc, filename);
+      typenames.AddPreprocessedType(unique_ptr<AidlStructuredParcelable>(doc));
     } else if (decl == "interface") {
       auto temp = new std::vector<std::unique_ptr<AidlMember>>();
       AidlInterface* doc = new AidlInterface(location, class_name, "", false, temp, package);
-      typenames->AddPreprocessedType(unique_ptr<AidlInterface>(doc));
+      types->AddBinderType(*doc, filename);
+      typenames.AddPreprocessedType(unique_ptr<AidlInterface>(doc));
     } else {
       success = false;
       break;
@@ -409,7 +476,7 @@
 }
 
 AidlError load_and_validate_aidl(const std::string& input_file_name, const Options& options,
-                                 const IoDelegate& io_delegate, AidlTypenames* typenames,
+                                 const IoDelegate& io_delegate, TypeNamespace* types,
                                  vector<AidlDefinedType*>* defined_types,
                                  vector<string>* imported_files) {
   AidlError err = AidlError::OK;
@@ -419,24 +486,18 @@
   //////////////////////////////////////////////////////////////////////////
 
   // Parse the main input file
-  std::unique_ptr<Parser> main_parser = Parser::Parse(input_file_name, io_delegate, *typenames);
+  std::unique_ptr<Parser> main_parser =
+      Parser::Parse(input_file_name, io_delegate, types->typenames_);
   if (main_parser == nullptr) {
     return AidlError::PARSE_ERROR;
   }
-  int num_interfaces_or_structured_parcelables = 0;
-  for (AidlDefinedType* type : main_parser->GetDefinedTypes()) {
-    if (type->AsInterface() != nullptr || type->AsStructuredParcelable() != nullptr) {
-      num_interfaces_or_structured_parcelables++;
-    }
-  }
-  if (num_interfaces_or_structured_parcelables > 1) {
-    AIDL_ERROR(input_file_name) << "You must declare only one type per a file.";
+  if (!types->AddDefinedTypes(main_parser->GetDefinedTypes(), input_file_name)) {
     return AidlError::BAD_TYPE;
   }
 
   // Import the preprocessed file
   for (const string& s : options.PreprocessedFiles()) {
-    if (!parse_preprocessed_file(io_delegate, s, typenames)) {
+    if (!parse_preprocessed_file(io_delegate, s, types, types->typenames_)) {
       err = AidlError::BAD_PRE_PROCESSED_FILE;
     }
   }
@@ -470,7 +531,7 @@
   set<string> import_candidates(type_from_import_statements);
   import_candidates.insert(unresolved_types.begin(), unresolved_types.end());
   for (const auto& import : import_candidates) {
-    if (typenames->IsIgnorableImport(import)) {
+    if (types->HasImportType(import)) {
       // There are places in the Android tree where an import doesn't resolve,
       // but we'll pick the type up through the preprocessed types.
       // This seems like an error, but legacy support demands we support it...
@@ -488,12 +549,16 @@
 
     import_paths.emplace_back(import_path);
 
-    std::unique_ptr<Parser> import_parser = Parser::Parse(import_path, io_delegate, *typenames);
+    std::unique_ptr<Parser> import_parser =
+        Parser::Parse(import_path, io_delegate, types->typenames_);
     if (import_parser == nullptr) {
       cerr << "error while importing " << import_path << " for " << import << endl;
       err = AidlError::BAD_IMPORT;
       continue;
     }
+    if (!types->AddDefinedTypes(import_parser->GetDefinedTypes(), import_path)) {
+      return AidlError::BAD_TYPE;
+    }
   }
   if (err != AidlError::OK) {
     return err;
@@ -502,12 +567,16 @@
   for (const auto& imported_file : options.ImportFiles()) {
     import_paths.emplace_back(imported_file);
 
-    std::unique_ptr<Parser> import_parser = Parser::Parse(imported_file, io_delegate, *typenames);
+    std::unique_ptr<Parser> import_parser =
+        Parser::Parse(imported_file, io_delegate, types->typenames_);
     if (import_parser == nullptr) {
       AIDL_ERROR(imported_file) << "error while importing " << imported_file;
       err = AidlError::BAD_IMPORT;
       continue;
     }
+    if (!types->AddDefinedTypes(import_parser->GetDefinedTypes(), imported_file)) {
+      return AidlError::BAD_TYPE;
+    }
   }
   if (err != AidlError::OK) {
     return err;
@@ -520,32 +589,34 @@
     // using fully qualified names.
     return AidlError::BAD_TYPE;
   }
+  if (!is_check_api) {
+    for (const auto defined_type : main_parser->GetDefinedTypes()) {
+      AidlInterface* interface = defined_type->AsInterface();
+      AidlStructuredParcelable* parcelable = defined_type->AsStructuredParcelable();
 
-  typenames->IterateTypes([&](const AidlDefinedType& type) {
-    AidlEnumDeclaration* enum_decl = const_cast<AidlEnumDeclaration*>(type.AsEnumDeclaration());
-    if (enum_decl != nullptr) {
-      // BackingType is filled in for all known enums, including imported enums,
-      // because other types that may use enums, such as Interface or
-      // StructuredParcelable, need to know the enum BackingType when
-      // generating code.
-      if (auto backing_type = enum_decl->BackingType(*typenames); backing_type != nullptr) {
-        enum_decl->SetBackingType(std::unique_ptr<const AidlTypeSpecifier>(backing_type));
-      } else {
-        // Default to byte type for enums.
-        auto byte_type =
-            std::make_unique<AidlTypeSpecifier>(AIDL_LOCATION_HERE, "byte", false, nullptr, "");
-        byte_type->Resolve(*typenames);
-        enum_decl->SetBackingType(std::move(byte_type));
+      // Link the AIDL type with the type of the target language. This will
+      // be removed when the migration to AidlTypenames is done.
+      defined_type->SetLanguageType(types->GetDefinedType(*defined_type));
+
+      if (interface != nullptr) {
+        if (!register_types(interface, types)) {
+          return AidlError::BAD_TYPE;
+        }
       }
-
-      enum_decl->Autofill();
+      if (parcelable != nullptr) {
+        if (!register_types(parcelable, types)) {
+          return AidlError::BAD_TYPE;
+        }
+      }
     }
-  });
+  }
 
   //////////////////////////////////////////////////////////////////////////
   // Validation phase
   //////////////////////////////////////////////////////////////////////////
 
+  AidlTypenames& typenames = types->typenames_;
+
   // For legacy reasons, by default, compiling an unstructured parcelable (which contains no output)
   // is allowed. This must not be returned as an error until the very end of this procedure since
   // this may be considered a success, and we should first check that there are not other, more
@@ -555,15 +626,9 @@
   const int num_defined_types = main_parser->GetDefinedTypes().size();
   for (const auto defined_type : main_parser->GetDefinedTypes()) {
     CHECK(defined_type != nullptr);
-
-    // Language specific validation
-    if (!defined_type->LanguageSpecificCheckValid(options.TargetLanguage())) {
-      return AidlError::BAD_TYPE;
-    }
-
     AidlParcelable* unstructuredParcelable = defined_type->AsUnstructuredParcelable();
     if (unstructuredParcelable != nullptr) {
-      if (!unstructuredParcelable->CheckValid(*typenames)) {
+      if (!unstructuredParcelable->CheckValid(typenames)) {
         return AidlError::BAD_TYPE;
       }
       bool isStable = unstructuredParcelable->IsStableParcelable();
@@ -584,19 +649,10 @@
       continue;
     }
 
-    if (defined_type->IsVintfStability() &&
-        (options.GetStability() != Options::Stability::VINTF || !options.IsStructured())) {
-      AIDL_ERROR(defined_type)
-          << "Must compile @VintfStability type w/ aidl_interface 'stability: \"vintf\"'";
-      return AidlError::NOT_STRUCTURED;
-    }
-
-    // Ensure that a type is either an interface, structured parcelable, or
-    // enum.
+    // Ensure that a type is either an interface or a structured parcelable
     AidlInterface* interface = defined_type->AsInterface();
     AidlStructuredParcelable* parcelable = defined_type->AsStructuredParcelable();
-    AidlEnumDeclaration* enum_decl = defined_type->AsEnumDeclaration();
-    CHECK(!!interface + !!parcelable + !!enum_decl == 1);
+    CHECK(interface != nullptr || parcelable != nullptr);
 
     // Ensure that foo.bar.IFoo is defined in <some_path>/foo/bar/IFoo.aidl
     if (num_defined_types == 1 && !check_filename(input_file_name, *defined_type)) {
@@ -607,7 +663,7 @@
     if (!is_check_api) {
       // No need to do this for check api because all typespecs are already
       // using fully qualified name and we don't import in AIDL files.
-      if (!defined_type->CheckValid(*typenames)) {
+      if (!defined_type->CheckValid(typenames)) {
         return AidlError::BAD_TYPE;
       }
     }
@@ -617,7 +673,7 @@
       if (options.Version() > 0) {
         AidlTypeSpecifier* ret =
             new AidlTypeSpecifier(AIDL_LOCATION_HERE, "int", false, nullptr, "");
-        ret->Resolve(*typenames);
+        ret->Resolve(typenames);
         vector<unique_ptr<AidlArgument>>* args = new vector<unique_ptr<AidlArgument>>();
         AidlMethod* method =
             new AidlMethod(AIDL_LOCATION_HERE, false, ret, "getInterfaceVersion", args, "",
@@ -627,49 +683,19 @@
       if (!check_and_assign_method_ids(interface->GetMethods())) {
         return AidlError::BAD_METHOD_ID;
       }
-
-      // Verify and resolve the constant declarations
-      for (const auto& constant : interface->GetConstantDeclarations()) {
-        switch (constant->GetValue().GetType()) {
-          case AidlConstantValue::Type::STRING:    // fall-through
-          case AidlConstantValue::Type::INT8:      // fall-through
-          case AidlConstantValue::Type::INT32:     // fall-through
-          case AidlConstantValue::Type::INT64:     // fall-through
-          case AidlConstantValue::Type::FLOATING:  // fall-through
-          case AidlConstantValue::Type::UNARY:     // fall-through
-          case AidlConstantValue::Type::BINARY: {
-            bool success = constant->CheckValid(*typenames);
-            if (!success) {
-              return AidlError::BAD_TYPE;
-            }
-            if (constant->ValueString(cpp::ConstantValueDecorator).empty()) {
-              return AidlError::BAD_TYPE;
-            }
-            break;
-          }
-          default:
-            LOG(FATAL) << "Unrecognized constant type: "
-                       << static_cast<int>(constant->GetValue().GetType());
-            break;
-        }
-      }
     }
   }
 
-  typenames->IterateTypes([&](const AidlDefinedType& type) {
-    if (options.IsStructured() && type.AsUnstructuredParcelable() != nullptr &&
-        !type.AsUnstructuredParcelable()->IsStableParcelable()) {
-      err = AidlError::NOT_STRUCTURED;
-      LOG(ERROR) << type.GetCanonicalName()
-                 << " is not structured, but this is a structured interface.";
-    }
-    if (options.GetStability() == Options::Stability::VINTF && !type.IsVintfStability()) {
-      err = AidlError::NOT_STRUCTURED;
-      LOG(ERROR) << type.GetCanonicalName()
-                 << " does not have VINTF level stability, but this interface requires it.";
-    }
-  });
-
+  if (options.IsStructured()) {
+    typenames.IterateTypes([&](const AidlDefinedType& type) {
+      if (type.AsUnstructuredParcelable() != nullptr &&
+          !type.AsUnstructuredParcelable()->IsStableParcelable()) {
+        err = AidlError::NOT_STRUCTURED;
+        LOG(ERROR) << type.GetCanonicalName()
+                   << " is not structured, but this is a structured interface.";
+      }
+    });
+  }
   if (err != AidlError::OK) {
     return err;
   }
@@ -695,13 +721,30 @@
 int compile_aidl(const Options& options, const IoDelegate& io_delegate) {
   const Options::Language lang = options.TargetLanguage();
   for (const string& input_file : options.InputFiles()) {
-    AidlTypenames typenames;
+    // Create type namespace that will hold the types identified by the parser.
+    // This two namespaces that are specific to the target language will be
+    // unified to AidlTypenames which is agnostic to the target language.
+    cpp::TypeNamespace cpp_types;
+    cpp_types.Init();
+
+    java::JavaTypeNamespace java_types;
+    java_types.Init();
+
+    TypeNamespace* types;
+    if (options.IsCppOutput()) {
+      types = &cpp_types;
+    } else if (lang == Options::Language::JAVA) {
+      types = &java_types;
+    } else {
+      LOG(FATAL) << "Unsupported target language." << endl;
+      return 1;
+    }
 
     vector<AidlDefinedType*> defined_types;
     vector<string> imported_files;
 
-    AidlError aidl_err = internals::load_and_validate_aidl(
-        input_file, options, io_delegate, &typenames, &defined_types, &imported_files);
+    AidlError aidl_err = internals::load_and_validate_aidl(input_file, options, io_delegate, types,
+                                                           &defined_types, &imported_files);
     bool allowError = aidl_err == AidlError::FOUND_PARCELABLE && !options.FailOnParcelable();
     if (aidl_err != AidlError::OK && !allowError) {
       return 1;
@@ -727,9 +770,10 @@
       bool success = false;
       if (lang == Options::Language::CPP) {
         success =
-            cpp::GenerateCpp(output_file_name, options, typenames, *defined_type, io_delegate);
+            cpp::GenerateCpp(output_file_name, options, cpp_types, *defined_type, io_delegate);
       } else if (lang == Options::Language::NDK) {
-        ndk::GenerateNdk(output_file_name, options, typenames, *defined_type, io_delegate);
+        ndk::GenerateNdk(output_file_name, options, cpp_types.typenames_, *defined_type,
+                         io_delegate);
         success = true;
       } else if (lang == Options::Language::JAVA) {
         if (defined_type->AsUnstructuredParcelable() != nullptr) {
@@ -737,7 +781,7 @@
           success = true;
         } else {
           success =
-              java::generate_java(output_file_name, defined_type, typenames, io_delegate, options);
+              java::generate_java(output_file_name, defined_type, &java_types, io_delegate, options);
         }
       } else {
         LOG(FATAL) << "Should not reach here" << endl;
@@ -754,18 +798,19 @@
 bool dump_mappings(const Options& options, const IoDelegate& io_delegate) {
   android::aidl::mappings::SignatureMap all_mappings;
   for (const string& input_file : options.InputFiles()) {
-    AidlTypenames typenames;
+    java::JavaTypeNamespace java_types;
+    java_types.Init();
     vector<AidlDefinedType*> defined_types;
     vector<string> imported_files;
 
     AidlError aidl_err = internals::load_and_validate_aidl(
-        input_file, options, io_delegate, &typenames, &defined_types, &imported_files);
+        input_file, options, io_delegate, &java_types, &defined_types, &imported_files);
     if (aidl_err != AidlError::OK) {
       LOG(WARNING) << "AIDL file is invalid.\n";
       continue;
     }
     for (const auto defined_type : defined_types) {
-      auto mappings = mappings::generate_mappings(defined_type, typenames);
+      auto mappings = mappings::generate_mappings(defined_type);
       all_mappings.insert(mappings.begin(), mappings.end());
     }
   }
@@ -806,9 +851,10 @@
 
 bool dump_api(const Options& options, const IoDelegate& io_delegate) {
   for (const auto& file : options.InputFiles()) {
-    AidlTypenames typenames;
+    java::JavaTypeNamespace ns;
+    ns.Init();
     vector<AidlDefinedType*> defined_types;
-    if (internals::load_and_validate_aidl(file, options, io_delegate, &typenames, &defined_types,
+    if (internals::load_and_validate_aidl(file, options, io_delegate, &ns, &defined_types,
                                           nullptr) == AidlError::OK) {
       for (const auto type : defined_types) {
         unique_ptr<CodeWriter> writer =
@@ -825,5 +871,5 @@
   return true;
 }
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/aidl.h b/aidl.h
index 955b280..7b5628f 100644
--- a/aidl.h
+++ b/aidl.h
@@ -25,6 +25,7 @@
 #include "import_resolver.h"
 #include "io_delegate.h"
 #include "options.h"
+#include "type_namespace.h"
 
 namespace android {
 namespace aidl {
@@ -55,14 +56,14 @@
 namespace internals {
 
 AidlError load_and_validate_aidl(const std::string& input_file_name, const Options& options,
-                                 const IoDelegate& io_delegate, AidlTypenames* typenames,
+                                 const IoDelegate& io_delegate, TypeNamespace* types,
                                  vector<AidlDefinedType*>* defined_types,
                                  vector<string>* imported_files);
 
 bool parse_preprocessed_file(const IoDelegate& io_delegate, const std::string& filename,
-                             AidlTypenames* typenames);
+                             TypeNamespace* types, AidlTypenames& typenames);
 
 } // namespace internals
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/aidl_apicheck.cpp b/aidl_apicheck.cpp
index 97ab848..4bedd17 100644
--- a/aidl_apicheck.cpp
+++ b/aidl_apicheck.cpp
@@ -1,6 +1,5 @@
 /*
- * Copyright (C) 2018, The Android Open Source Project
- *
+ * Copyright (C) 2018, The Android Open Source Project *
  * 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
@@ -17,15 +16,13 @@
 #include "aidl.h"
 #include "aidl_language.h"
 #include "import_resolver.h"
-#include "logging.h"
 #include "options.h"
+#include "type_java.h"
 
 #include <map>
 #include <string>
 #include <vector>
 
-#include <android-base/strings.h>
-
 namespace android {
 namespace aidl {
 
@@ -178,47 +175,13 @@
   return compatible;
 }
 
-static bool are_compatible_enums(const AidlEnumDeclaration& older,
-                                 const AidlEnumDeclaration& newer) {
-  if (!are_compatible_types(older.GetBackingType(), newer.GetBackingType())) {
-    AIDL_ERROR(newer) << "Changed backing types.";
-    return false;
-  }
-
-  std::map<std::string, const AidlConstantValue*> old_enum_map;
-  for (const auto& enumerator : older.GetEnumerators()) {
-    old_enum_map[enumerator->GetName()] = enumerator->GetValue();
-  }
-  std::map<std::string, const AidlConstantValue*> new_enum_map;
-  for (const auto& enumerator : newer.GetEnumerators()) {
-    new_enum_map[enumerator->GetName()] = enumerator->GetValue();
-  }
-
-  bool compatible = true;
-  for (const auto& [name, value] : old_enum_map) {
-    if (new_enum_map.find(name) == new_enum_map.end()) {
-      AIDL_ERROR(newer) << "Removed enumerator from " << older.GetCanonicalName() << ": " << name;
-      compatible = false;
-      continue;
-    }
-    const string old_value =
-        old_enum_map[name]->ValueString(older.GetBackingType(), AidlConstantValueDecorator);
-    const string new_value =
-        new_enum_map[name]->ValueString(newer.GetBackingType(), AidlConstantValueDecorator);
-    if (old_value != new_value) {
-      AIDL_ERROR(newer) << "Changed enumerator value: " << older.GetCanonicalName() << "::" << name
-                        << " from " << old_value << " to " << new_value << ".";
-      compatible = false;
-    }
-  }
-  return compatible;
-}
-
 bool check_api(const Options& options, const IoDelegate& io_delegate) {
   CHECK(options.IsStructured());
   CHECK(options.InputFiles().size() == 2) << "--checkapi requires two inputs "
                                           << "but got " << options.InputFiles().size();
-  AidlTypenames old_tns;
+
+  java::JavaTypeNamespace old_ns;
+  old_ns.Init();
   const string old_dir = options.InputFiles().at(0);
   vector<AidlDefinedType*> old_types;
   vector<string> old_files = io_delegate.ListFiles(old_dir);
@@ -227,10 +190,8 @@
     return false;
   }
   for (const auto& file : old_files) {
-    if (!android::base::EndsWith(file, ".aidl")) continue;
-
     vector<AidlDefinedType*> types;
-    if (internals::load_and_validate_aidl(file, options, io_delegate, &old_tns, &types,
+    if (internals::load_and_validate_aidl(file, options, io_delegate, &old_ns, &types,
                                           nullptr /* imported_files */) != AidlError::OK) {
       AIDL_ERROR(file) << "Failed to read.";
       return false;
@@ -238,7 +199,8 @@
     old_types.insert(old_types.end(), types.begin(), types.end());
   }
 
-  AidlTypenames new_tns;
+  java::JavaTypeNamespace new_ns;
+  new_ns.Init();
   const string new_dir = options.InputFiles().at(1);
   vector<AidlDefinedType*> new_types;
   vector<string> new_files = io_delegate.ListFiles(new_dir);
@@ -247,10 +209,8 @@
     return false;
   }
   for (const auto& file : new_files) {
-    if (!android::base::EndsWith(file, ".aidl")) continue;
-
     vector<AidlDefinedType*> types;
-    if (internals::load_and_validate_aidl(file, options, io_delegate, &new_tns, &types,
+    if (internals::load_and_validate_aidl(file, options, io_delegate, &new_ns, &types,
                                           nullptr /* imported_files */) != AidlError::OK) {
       AIDL_ERROR(file) << "Failed to read.";
       return false;
@@ -273,39 +233,26 @@
     }
     const auto new_type = found->second;
 
-    if (old_type->AsInterface() != nullptr) {
-      if (new_type->AsInterface() == nullptr) {
-        AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()
-                             << " is changed from " << old_type->GetPreprocessDeclarationName()
-                             << " to " << new_type->GetPreprocessDeclarationName();
-        compatible = false;
-        continue;
-      }
+    const bool old_is_iface = old_type->AsInterface() != nullptr;
+    const bool new_is_iface = new_type->AsInterface() != nullptr;
+    if (old_is_iface != new_is_iface) {
+      AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()
+                           << " is changed from " << old_type->GetPreprocessDeclarationName()
+                           << " to " << new_type->GetPreprocessDeclarationName();
+      compatible = false;
+      continue;
+    }
+
+    if (old_is_iface) {
       compatible &=
           are_compatible_interfaces(*(old_type->AsInterface()), *(new_type->AsInterface()));
-    } else if (old_type->AsStructuredParcelable() != nullptr) {
-      if (new_type->AsStructuredParcelable() == nullptr) {
-        AIDL_ERROR(new_type) << "Parcelable" << new_type->GetCanonicalName()
-                             << " is not structured. ";
-        compatible = false;
-        continue;
-      }
+    } else {
+      CHECK(old_type->AsStructuredParcelable() != nullptr)
+          << "Parcelable" << old_type->GetCanonicalName() << " is not structured. ";
+      CHECK(new_type->AsStructuredParcelable() != nullptr)
+          << "Parcelable" << new_type->GetCanonicalName() << " is not structured. ";
       compatible &= are_compatible_parcelables(*(old_type->AsStructuredParcelable()),
                                                *(new_type->AsStructuredParcelable()));
-    } else if (old_type->AsEnumDeclaration() != nullptr) {
-      if (new_type->AsEnumDeclaration() == nullptr) {
-        AIDL_ERROR(new_type) << "Type mismatch: " << old_type->GetCanonicalName()
-                             << " is changed from " << old_type->GetPreprocessDeclarationName()
-                             << " to " << new_type->GetPreprocessDeclarationName();
-        compatible = false;
-        continue;
-      }
-      compatible &=
-          are_compatible_enums(*(old_type->AsEnumDeclaration()), *(new_type->AsEnumDeclaration()));
-    } else {
-      AIDL_ERROR(old_type) << "Unsupported type " << old_type->GetPreprocessDeclarationName()
-                           << " for " << old_type->GetCanonicalName();
-      compatible = false;
     }
   }
 
diff --git a/aidl_const_expressions.cpp b/aidl_const_expressions.cpp
deleted file mode 100644
index dbd1f8b..0000000
--- a/aidl_const_expressions.cpp
+++ /dev/null
@@ -1,886 +0,0 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "aidl_language.h"
-#include "logging.h"
-
-#include <stdlib.h>
-#include <algorithm>
-#include <iostream>
-#include <memory>
-
-#include <android-base/parsedouble.h>
-#include <android-base/parseint.h>
-#include <android-base/strings.h>
-
-using android::base::ConsumeSuffix;
-using android::base::Join;
-using std::string;
-using std::unique_ptr;
-using std::vector;
-
-#define SHOULD_NOT_REACH() CHECK(false) << LOG(FATAL) << ": should not reach here: "
-#define OPEQ(__y__) (string(op_) == string(__y__))
-#define COMPUTE_UNARY(__op__) \
-  if (op == string(#__op__)) return __op__ val;
-#define COMPUTE_BINARY(__op__) \
-  if (op == string(#__op__)) return lval __op__ rval;
-#define OP_IS_BIN_ARITHMETIC (OPEQ("+") || OPEQ("-") || OPEQ("*") || OPEQ("/") || OPEQ("%"))
-#define OP_IS_BIN_BITFLIP (OPEQ("|") || OPEQ("^") || OPEQ("&"))
-#define OP_IS_BIN_COMP \
-  (OPEQ("<") || OPEQ(">") || OPEQ("<=") || OPEQ(">=") || OPEQ("==") || OPEQ("!="))
-#define OP_IS_BIN_SHIFT (OPEQ(">>") || OPEQ("<<"))
-#define OP_IS_BIN_LOGICAL (OPEQ("||") || OPEQ("&&"))
-
-// NOLINT to suppress missing parentheses warnings about __def__.
-#define SWITCH_KIND(__cond__, __action__, __def__) \
-  switch (__cond__) {                              \
-    case Type::BOOLEAN:                            \
-      __action__(bool);                            \
-    case Type::INT8:                               \
-      __action__(int8_t);                          \
-    case Type::INT32:                              \
-      __action__(int32_t);                         \
-    case Type::INT64:                              \
-      __action__(int64_t);                         \
-    default:                                       \
-      __def__; /* NOLINT */                        \
-  }
-
-template <class T>
-T handleUnary(const string& op, T val) {
-  COMPUTE_UNARY(+)
-  COMPUTE_UNARY(-)
-  COMPUTE_UNARY(!)
-  COMPUTE_UNARY(~)
-  // Should not reach here.
-  SHOULD_NOT_REACH() << "Could not handleUnary for " << op << " " << val;
-  return static_cast<T>(0xdeadbeef);
-}
-
-template <class T>
-T handleBinaryCommon(T lval, const string& op, T rval) {
-  COMPUTE_BINARY(+)
-  COMPUTE_BINARY(-)
-  COMPUTE_BINARY(*)
-  COMPUTE_BINARY(/)
-  COMPUTE_BINARY(%)
-  COMPUTE_BINARY(|)
-  COMPUTE_BINARY(^)
-  COMPUTE_BINARY(&)
-  // comparison operators: return 0 or 1 by nature.
-  COMPUTE_BINARY(==)
-  COMPUTE_BINARY(!=)
-  COMPUTE_BINARY(<)
-  COMPUTE_BINARY(>)
-  COMPUTE_BINARY(<=)
-  COMPUTE_BINARY(>=)
-  // Should not reach here.
-  SHOULD_NOT_REACH() << "Could not handleBinaryCommon for " << lval << " " << op << " " << rval;
-  return static_cast<T>(0xdeadbeef);
-}
-
-template <class T>
-T handleShift(T lval, const string& op, int64_t rval) {
-  // just cast rval to int64_t and it should fit.
-  COMPUTE_BINARY(>>)
-  COMPUTE_BINARY(<<)
-  // Should not reach here.
-  SHOULD_NOT_REACH() << "Could not handleShift for " << lval << " " << op << " " << rval;
-  return static_cast<T>(0xdeadbeef);
-}
-
-bool handleLogical(bool lval, const string& op, bool rval) {
-  COMPUTE_BINARY(||);
-  COMPUTE_BINARY(&&);
-  // Should not reach here.
-  SHOULD_NOT_REACH() << "Could not handleLogical for " << lval << " " << op << " " << rval;
-  return false;
-}
-
-static bool isValidLiteralChar(char c) {
-  return !(c <= 0x1f ||  // control characters are < 0x20
-           c >= 0x7f ||  // DEL is 0x7f
-           c == '\\');   // Disallow backslashes for future proofing.
-}
-
-bool AidlUnaryConstExpression::IsCompatibleType(Type type, const string& op) {
-  // Verify the unary type here
-  switch (type) {
-    case Type::BOOLEAN:  // fall-through
-    case Type::INT8:     // fall-through
-    case Type::INT32:    // fall-through
-    case Type::INT64:
-      return true;
-    case Type::FLOATING:
-      return (op == "+" || op == "-");
-    default:
-      return false;
-  }
-}
-
-bool AidlBinaryConstExpression::AreCompatibleTypes(Type t1, Type t2) {
-  switch (t1) {
-    case Type::STRING:
-      if (t2 == Type::STRING) {
-        return true;
-      }
-      break;
-    case Type::BOOLEAN:  // fall-through
-    case Type::INT8:     // fall-through
-    case Type::INT32:    // fall-through
-    case Type::INT64:
-      switch (t2) {
-        case Type::BOOLEAN:  // fall-through
-        case Type::INT8:     // fall-through
-        case Type::INT32:    // fall-through
-        case Type::INT64:
-          return true;
-          break;
-        default:
-          break;
-      }
-      break;
-    default:
-      break;
-  }
-
-  return false;
-}
-
-// Returns the promoted kind for both operands
-AidlConstantValue::Type AidlBinaryConstExpression::UsualArithmeticConversion(Type left,
-                                                                             Type right) {
-  // These are handled as special cases
-  CHECK(left != Type::STRING && right != Type::STRING);
-  CHECK(left != Type::FLOATING && right != Type::FLOATING);
-
-  // Kinds in concern: bool, (u)int[8|32|64]
-  if (left == right) return left;  // easy case
-  if (left == Type::BOOLEAN) return right;
-  if (right == Type::BOOLEAN) return left;
-
-  return left < right ? right : left;
-}
-
-// Returns the promoted integral type where INT32 is the smallest type
-AidlConstantValue::Type AidlBinaryConstExpression::IntegralPromotion(Type in) {
-  return (Type::INT32 < in) ? in : Type::INT32;
-}
-
-template <typename T>
-T AidlConstantValue::cast() const {
-  CHECK(is_evaluated_ == true);
-
-#define CASE_CAST_T(__type__) return static_cast<T>(static_cast<__type__>(final_value_));
-
-  SWITCH_KIND(final_type_, CASE_CAST_T, SHOULD_NOT_REACH(); return 0;);
-}
-
-AidlConstantValue* AidlConstantValue::Boolean(const AidlLocation& location, bool value) {
-  return new AidlConstantValue(location, Type::BOOLEAN, value ? "true" : "false");
-}
-
-AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location, char value) {
-  if (!isValidLiteralChar(value)) {
-    AIDL_ERROR(location) << "Invalid character literal " << value;
-    return new AidlConstantValue(location, Type::ERROR, "");
-  }
-  return new AidlConstantValue(location, Type::CHARACTER, string("'") + value + "'");
-}
-
-AidlConstantValue* AidlConstantValue::Floating(const AidlLocation& location,
-                                               const std::string& value) {
-  return new AidlConstantValue(location, Type::FLOATING, value);
-}
-
-bool AidlConstantValue::IsHex(const string& value) {
-  if (value.length() > (sizeof("0x") - 1)) {
-    if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X')) {
-      return true;
-    }
-  }
-  return false;
-}
-
-bool AidlConstantValue::ParseIntegral(const string& value, int64_t* parsed_value,
-                                      Type* parsed_type) {
-  bool isLong = false;
-
-  if (parsed_value == nullptr || parsed_type == nullptr) {
-    return false;
-  }
-
-  if (IsHex(value)) {
-    bool parseOK = false;
-    uint32_t rawValue32;
-
-    // AIDL considers 'const int foo = 0xffffffff' as -1, but if we want to
-    // handle that when computing constant expressions, then we need to
-    // represent 0xffffffff as a uint32_t. However, AIDL only has signed types;
-    // so we parse as an unsigned int when possible and then cast to a signed
-    // int. One example of this is in ICameraService.aidl where a constant int
-    // is used for bit manipulations which ideally should be handled with an
-    // unsigned int.
-    parseOK = android::base::ParseUint<uint32_t>(value, &rawValue32);
-    if (parseOK) {
-      *parsed_value = static_cast<int32_t>(rawValue32);
-      *parsed_type = Type::INT32;
-    } else {
-      parseOK = android::base::ParseInt<int64_t>(value, parsed_value);
-      if (!parseOK) {
-        *parsed_type = Type::ERROR;
-        return false;
-      }
-
-      *parsed_type = Type::INT64;
-    }
-    return true;
-  }
-
-  if (value[value.size() - 1] == 'l' || value[value.size() - 1] == 'L') {
-    isLong = true;
-    *parsed_type = Type::INT64;
-  }
-
-  string value_substr = value.substr(0, isLong ? value.size() - 1 : value.size());
-  bool parseOK = android::base::ParseInt<int64_t>(value_substr, parsed_value);
-  if (!parseOK) {
-    *parsed_type = Type::ERROR;
-    return false;
-  }
-
-  if (!isLong) {
-    // guess literal type.
-    if (*parsed_value <= INT8_MAX && *parsed_value >= INT8_MIN) {
-      *parsed_type = Type::INT8;
-    } else if (*parsed_value <= INT32_MAX && *parsed_value >= INT32_MIN) {
-      *parsed_type = Type::INT32;
-    } else {
-      *parsed_type = Type::INT64;
-    }
-  }
-  return true;
-}
-
-AidlConstantValue* AidlConstantValue::Integral(const AidlLocation& location, const string& value) {
-  CHECK(!value.empty());
-
-  Type parsed_type;
-  int64_t parsed_value = 0;
-  bool success = ParseIntegral(value, &parsed_value, &parsed_type);
-  if (!success) {
-    return nullptr;
-  }
-
-  return new AidlConstantValue(location, parsed_type, parsed_value, value);
-}
-
-AidlConstantValue* AidlConstantValue::Array(
-    const AidlLocation& location, std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values) {
-  return new AidlConstantValue(location, Type::ARRAY, std::move(values));
-}
-
-AidlConstantValue* AidlConstantValue::String(const AidlLocation& location, const string& value) {
-  for (size_t i = 0; i < value.length(); ++i) {
-    if (!isValidLiteralChar(value[i])) {
-      AIDL_ERROR(location) << "Found invalid character at index " << i << " in string constant '"
-                           << value << "'";
-      return new AidlConstantValue(location, Type::ERROR, "");
-    }
-  }
-
-  return new AidlConstantValue(location, Type::STRING, value);
-}
-
-AidlConstantValue* AidlConstantValue::ShallowIntegralCopy(const AidlConstantValue& other) {
-  // TODO(b/142894901): Perform full proper copy
-  AidlTypeSpecifier type = AidlTypeSpecifier(AIDL_LOCATION_HERE, "long", false, nullptr, "");
-  // TODO(b/142722772) CheckValid() should be called before ValueString()
-  if (!other.CheckValid()) {
-    AIDL_FATAL(other) << "Invalid value for ShallowIntegralCopy";
-  }
-  if (!other.evaluate(type)) {
-    AIDL_FATAL(other) << "Unsupported type for ShallowIntegralCopy: " << ToString(other.GetType());
-  }
-
-  AidlConstantValue* result =
-      Integral(AIDL_LOCATION_HERE, other.ValueString(type, AidlConstantValueDecorator));
-  if (result == nullptr) {
-    AIDL_FATAL(other) << "Unable to perform ShallowIntegralCopy.";
-  }
-  return result;
-}
-
-string AidlConstantValue::ValueString(const AidlTypeSpecifier& type,
-                                      const ConstantValueDecorator& decorator) const {
-  if (type.IsGeneric()) {
-    AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
-    return "";
-  }
-  if (!is_evaluated_) {
-    // TODO(b/142722772) CheckValid() should be called before ValueString()
-    bool success = CheckValid();
-    success &= evaluate(type);
-    if (!success) {
-      // the detailed error message shall be printed in evaluate
-      return "";
-    }
-  }
-  if (!is_valid_) {
-    AIDL_ERROR(this) << "Invalid constant value: " + value_;
-    return "";
-  }
-  const string& type_string = type.GetName();
-  int err = 0;
-
-  switch (final_type_) {
-    case Type::CHARACTER:
-      if (type_string == "char") {
-        return decorator(type, final_string_value_);
-      }
-      err = -1;
-      break;
-    case Type::STRING:
-      if (type_string == "String") {
-        return decorator(type, final_string_value_);
-      }
-      err = -1;
-      break;
-    case Type::BOOLEAN:  // fall-through
-    case Type::INT8:     // fall-through
-    case Type::INT32:    // fall-through
-    case Type::INT64:
-      if (type_string == "byte") {
-        if (final_value_ > INT8_MAX || final_value_ < INT8_MIN) {
-          err = -1;
-          break;
-        }
-        return decorator(type, std::to_string(static_cast<int8_t>(final_value_)));
-      } else if (type_string == "int") {
-        if (final_value_ > INT32_MAX || final_value_ < INT32_MIN) {
-          err = -1;
-          break;
-        }
-        return decorator(type, std::to_string(static_cast<int32_t>(final_value_)));
-      } else if (type_string == "long") {
-        return decorator(type, std::to_string(final_value_));
-      } else if (type_string == "boolean") {
-        return decorator(type, final_value_ ? "true" : "false");
-      }
-      err = -1;
-      break;
-    case Type::ARRAY: {
-      if (!type.IsArray()) {
-        err = -1;
-        break;
-      }
-      vector<string> value_strings;
-      value_strings.reserve(values_.size());
-      bool success = true;
-
-      for (const auto& value : values_) {
-        const AidlTypeSpecifier& array_base = type.ArrayBase();
-        const string value_string = value->ValueString(array_base, decorator);
-        if (value_string.empty()) {
-          success = false;
-          break;
-        }
-        value_strings.push_back(value_string);
-      }
-      if (!success) {
-        err = -1;
-        break;
-      }
-
-      return decorator(type, "{" + Join(value_strings, ", ") + "}");
-    }
-    case Type::FLOATING: {
-      std::string_view raw_view(value_.c_str());
-      bool is_float_literal = ConsumeSuffix(&raw_view, "f");
-      std::string stripped_value = std::string(raw_view);
-
-      if (type_string == "double") {
-        double parsed_value;
-        if (!android::base::ParseDouble(stripped_value, &parsed_value)) {
-          AIDL_ERROR(this) << "Could not parse " << value_;
-          err = -1;
-          break;
-        }
-        return decorator(type, std::to_string(parsed_value));
-      }
-      if (is_float_literal && type_string == "float") {
-        float parsed_value;
-        if (!android::base::ParseFloat(stripped_value, &parsed_value)) {
-          AIDL_ERROR(this) << "Could not parse " << value_;
-          err = -1;
-          break;
-        }
-        return decorator(type, std::to_string(parsed_value) + "f");
-      }
-      err = -1;
-      break;
-    }
-    default:
-      err = -1;
-      break;
-  }
-
-  CHECK(err != 0);
-  AIDL_ERROR(this) << "Invalid type specifier for " << ToString(final_type_) << ": " << type_string;
-  return "";
-}
-
-bool AidlConstantValue::CheckValid() const {
-  // Nothing needs to be checked here. The constant value will be validated in
-  // the constructor or in the evaluate() function.
-  if (is_evaluated_) return is_valid_;
-
-  switch (type_) {
-    case Type::BOOLEAN:    // fall-through
-    case Type::INT8:       // fall-through
-    case Type::INT32:      // fall-through
-    case Type::INT64:      // fall-through
-    case Type::ARRAY:      // fall-through
-    case Type::CHARACTER:  // fall-through
-    case Type::STRING:     // fall-through
-    case Type::FLOATING:   // fall-through
-    case Type::UNARY:      // fall-through
-    case Type::BINARY:
-      is_valid_ = true;
-      break;
-    default:
-      AIDL_FATAL(this) << "Unrecognized constant value type: " << ToString(type_);
-      return false;
-  }
-
-  return true;
-}
-
-bool AidlConstantValue::evaluate(const AidlTypeSpecifier& type) const {
-  if (is_evaluated_) {
-    return is_valid_;
-  }
-  int err = 0;
-  is_evaluated_ = true;
-
-  switch (type_) {
-    case Type::ARRAY: {
-      if (!type.IsArray()) {
-        AIDL_ERROR(this) << "Invalid constant array type: " << type.GetName();
-        err = -1;
-        break;
-      }
-      Type array_type = Type::ERROR;
-      bool success = true;
-      for (const auto& value : values_) {
-        success = value->CheckValid();
-        if (success) {
-          success = value->evaluate(type.ArrayBase());
-          if (!success) {
-            AIDL_ERROR(this) << "Invalid array element: " << value->value_;
-            break;
-          }
-          if (array_type == Type::ERROR) {
-            array_type = value->final_type_;
-          } else if (!AidlBinaryConstExpression::AreCompatibleTypes(array_type,
-                                                                    value->final_type_)) {
-            AIDL_ERROR(this) << "Incompatible array element type: " << ToString(value->final_type_)
-                             << ". Expecting type compatible with " << ToString(array_type);
-            success = false;
-            break;
-          }
-        } else {
-          break;
-        }
-      }
-      if (!success) {
-        err = -1;
-        break;
-      }
-      final_type_ = type_;
-      break;
-    }
-    case Type::BOOLEAN:
-      if ((value_ != "true") && (value_ != "false")) {
-        AIDL_ERROR(this) << "Invalid constant boolean value: " << value_;
-        err = -1;
-        break;
-      }
-      final_value_ = (value_ == "true") ? 1 : 0;
-      final_type_ = type_;
-      break;
-    case Type::INT8:   // fall-through
-    case Type::INT32:  // fall-through
-    case Type::INT64:
-      // Parsing happens in the constructor
-      final_type_ = type_;
-      break;
-    case Type::CHARACTER:  // fall-through
-    case Type::STRING:
-      final_string_value_ = value_;
-      final_type_ = type_;
-      break;
-    case Type::FLOATING:
-      // Just parse on the fly in ValueString
-      final_type_ = type_;
-      break;
-    default:
-      AIDL_FATAL(this) << "Unrecognized constant value type: " << ToString(type_);
-      err = -1;
-  }
-
-  return (err == 0) ? true : false;
-}
-
-string AidlConstantValue::ToString(Type type) {
-  switch (type) {
-    case Type::ARRAY:
-      return "a literal array";
-    case Type::BOOLEAN:
-      return "a literal boolean";
-    case Type::CHARACTER:
-      return "a literal char";
-    case Type::INT8:
-      return "an int8 literal";
-    case Type::INT32:
-      return "an int32 literal";
-    case Type::INT64:
-      return "an int64 literal";
-    case Type::STRING:
-      return "a literal string";
-    case Type::ERROR:
-      LOG(FATAL) << "aidl internal error: error type failed to halt program";
-      return "";
-    case Type::UNARY:
-      return "a unary expression";
-    case Type::BINARY:
-      return "a binary expression";
-    default:
-      LOG(FATAL) << "aidl internal error: unknown constant type: " << static_cast<int>(type);
-      return "";  // not reached
-  }
-}
-
-bool AidlUnaryConstExpression::CheckValid() const {
-  if (is_evaluated_) return is_valid_;
-  CHECK(unary_ != nullptr);
-
-  is_valid_ = unary_->CheckValid();
-  if (!is_valid_) {
-    final_type_ = Type::ERROR;
-    return false;
-  }
-
-  return true;
-}
-
-bool AidlUnaryConstExpression::evaluate(const AidlTypeSpecifier& type) const {
-  if (is_evaluated_) {
-    return is_valid_;
-  }
-  is_evaluated_ = true;
-
-  // Recursively evaluate the expression tree
-  if (!unary_->is_evaluated_) {
-    // TODO(b/142722772) CheckValid() should be called before ValueString()
-    bool success = CheckValid();
-    success &= unary_->evaluate(type);
-    if (!success) {
-      is_valid_ = false;
-      return false;
-    }
-  }
-  if (!unary_->is_valid_ || !IsCompatibleType(unary_->final_type_, op_)) {
-    AIDL_ERROR(type) << "Invalid constant unary expression: " + value_;
-    is_valid_ = false;
-    return false;
-  }
-  final_type_ = unary_->final_type_;
-
-  if (final_type_ == Type::FLOATING) {
-    // don't do anything here. ValueString() will handle everything.
-    is_valid_ = true;
-    return true;
-  }
-
-#define CASE_UNARY(__type__)                                                    \
-  final_value_ = handleUnary(op_, static_cast<__type__>(unary_->final_value_)); \
-  return true;
-
-  SWITCH_KIND(final_type_, CASE_UNARY, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
-              is_valid_ = false; return false;)
-}
-
-string AidlUnaryConstExpression::ValueString(const AidlTypeSpecifier& type,
-                                             const ConstantValueDecorator& decorator) const {
-  if (type.IsGeneric()) {
-    AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
-    return "";
-  }
-  if (!is_evaluated_) {
-    // TODO(b/142722772) CheckValid() should be called before ValueString()
-    bool success = CheckValid();
-    success &= evaluate(type);
-    if (!success) {
-      // A detailed error message shall be printed in evaluate()
-      return "";
-    }
-  }
-  if (!is_valid_) {
-    AIDL_ERROR(this) << "Invalid constant unary expression";
-    return "";
-  }
-
-  return AidlConstantValue::ValueString(type, decorator);
-}
-
-bool AidlBinaryConstExpression::CheckValid() const {
-  bool success = false;
-  if (is_evaluated_) return is_valid_;
-  CHECK(left_val_ != nullptr);
-  CHECK(right_val_ != nullptr);
-
-  success = left_val_->CheckValid();
-  if (!success) {
-    final_type_ = Type::ERROR;
-    AIDL_ERROR(this) << "Invalid left operand in binary expression: " + value_;
-  }
-
-  success = right_val_->CheckValid();
-  if (!success) {
-    AIDL_ERROR(this) << "Invalid right operand in binary expression: " + value_;
-    final_type_ = Type::ERROR;
-  }
-
-  if (final_type_ == Type::ERROR) {
-    is_valid_ = false;
-    return false;
-  }
-
-  is_valid_ = true;
-  return true;
-}
-
-bool AidlBinaryConstExpression::evaluate(const AidlTypeSpecifier& type) const {
-  if (is_evaluated_) {
-    return is_valid_;
-  }
-  is_evaluated_ = true;
-  CHECK(left_val_ != nullptr);
-  CHECK(right_val_ != nullptr);
-
-  // Recursively evaluate the binary expression tree
-  if (!left_val_->is_evaluated_ || !right_val_->is_evaluated_) {
-    // TODO(b/142722772) CheckValid() should be called before ValueString()
-    bool success = CheckValid();
-    success &= left_val_->evaluate(type);
-    success &= right_val_->evaluate(type);
-    if (!success) {
-      is_valid_ = false;
-      return false;
-    }
-  }
-  if (!left_val_->is_valid_ || !right_val_->is_valid_) {
-    is_valid_ = false;
-    return false;
-  }
-  is_valid_ = AreCompatibleTypes(left_val_->final_type_, right_val_->final_type_);
-  if (!is_valid_) {
-    return false;
-  }
-
-  bool isArithmeticOrBitflip = OP_IS_BIN_ARITHMETIC || OP_IS_BIN_BITFLIP;
-
-  // Handle String case first
-  if (left_val_->final_type_ == Type::STRING) {
-    if (!OPEQ("+")) {
-      // invalid operation on strings
-      final_type_ = Type::ERROR;
-      is_valid_ = false;
-      return false;
-    }
-
-    // Remove trailing " from lhs
-    const string& lhs = left_val_->final_string_value_;
-    if (lhs.back() != '"') {
-      AIDL_ERROR(this) << "'" << lhs << "' is missing a trailing quote.";
-      final_type_ = Type::ERROR;
-      is_valid_ = false;
-      return false;
-    }
-    const string& rhs = right_val_->final_string_value_;
-    // Remove starting " from rhs
-    if (rhs.front() != '"') {
-      AIDL_ERROR(this) << "'" << rhs << "' is missing a leading quote.";
-      final_type_ = Type::ERROR;
-      is_valid_ = false;
-      return false;
-    }
-
-    final_string_value_ = string(lhs.begin(), lhs.end() - 1).append(rhs.begin() + 1, rhs.end());
-    final_type_ = Type::STRING;
-    return true;
-  }
-
-  // TODO(b/139877950) Add support for handling overflows
-
-  // CASE: + - *  / % | ^ & < > <= >= == !=
-  if (isArithmeticOrBitflip || OP_IS_BIN_COMP) {
-    if (op_ == "/" && right_val_->final_value_ == 0) {
-      final_type_ = Type::ERROR;
-      is_valid_ = false;
-      AIDL_ERROR(this) << "Divide by 0! const_expr: " + value_;
-      return false;
-    }
-
-    // promoted kind for both operands.
-    Type promoted = UsualArithmeticConversion(IntegralPromotion(left_val_->final_type_),
-                                              IntegralPromotion(right_val_->final_type_));
-    // result kind.
-    final_type_ = isArithmeticOrBitflip
-                      ? promoted        // arithmetic or bitflip operators generates promoted type
-                      : Type::BOOLEAN;  // comparison operators generates bool
-
-#define CASE_BINARY_COMMON(__type__)                                                     \
-  final_value_ = handleBinaryCommon(static_cast<__type__>(left_val_->final_value_), op_, \
-                                    static_cast<__type__>(right_val_->final_value_));    \
-  return true;
-
-    SWITCH_KIND(promoted, CASE_BINARY_COMMON, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
-                is_valid_ = false; return false;)
-  }
-
-  // CASE: << >>
-  string newOp = op_;
-  if (OP_IS_BIN_SHIFT) {
-    final_type_ = IntegralPromotion(left_val_->final_type_);
-    // instead of promoting rval, simply casting it to int64 should also be good.
-    int64_t numBits = right_val_->cast<int64_t>();
-    if (numBits < 0) {
-      // shifting with negative number of bits is undefined in C. In HIDL it
-      // is defined as shifting into the other direction.
-      newOp = OPEQ("<<") ? ">>" : "<<";
-      numBits = -numBits;
-    }
-
-#define CASE_SHIFT(__type__)                                                                  \
-  final_value_ = handleShift(static_cast<__type__>(left_val_->final_value_), newOp, numBits); \
-  return true;
-
-    SWITCH_KIND(final_type_, CASE_SHIFT, SHOULD_NOT_REACH(); final_type_ = Type::ERROR;
-                is_valid_ = false; return false;)
-  }
-
-  // CASE: && ||
-  if (OP_IS_BIN_LOGICAL) {
-    final_type_ = Type::BOOLEAN;
-    // easy; everything is bool.
-    final_value_ = handleLogical(left_val_->final_value_, op_, right_val_->final_value_);
-    return true;
-  }
-
-  SHOULD_NOT_REACH();
-  is_valid_ = false;
-  return false;
-}
-
-string AidlBinaryConstExpression::ValueString(const AidlTypeSpecifier& type,
-                                              const ConstantValueDecorator& decorator) const {
-  if (type.IsGeneric()) {
-    AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
-    return "";
-  }
-  if (!is_evaluated_) {
-    // TODO(b/142722772) CheckValid() should be called before ValueString()
-    bool success = CheckValid();
-    success &= evaluate(type);
-    if (!success) {
-      AIDL_ERROR(this) << "Invalid constant binary expression";
-      return "";
-    }
-  }
-  if (!is_valid_) {
-    AIDL_ERROR(this) << "Invalid constant binary expression";
-    return "";
-  }
-
-  return AidlConstantValue::ValueString(type, decorator);
-}
-
-AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type parsed_type,
-                                     int64_t parsed_value, const string& checked_value)
-    : AidlNode(location),
-      type_(parsed_type),
-      value_(checked_value),
-      is_valid_(true),
-      is_evaluated_(true),
-      final_type_(parsed_type),
-      final_value_(parsed_value) {
-  CHECK(!value_.empty() || type_ == Type::ERROR);
-  CHECK(type_ == Type::INT8 || type_ == Type::INT32 || type_ == Type::INT64);
-}
-
-AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
-                                     const string& checked_value)
-    : AidlNode(location),
-      type_(type),
-      value_(checked_value),
-      is_valid_(false),
-      is_evaluated_(false),
-      final_type_(type) {
-  CHECK(!value_.empty() || type_ == Type::ERROR);
-  switch (type_) {
-    case Type::INT8:
-    case Type::INT32:
-    case Type::INT64:
-    case Type::ARRAY:
-      AIDL_FATAL(this) << "Invalid type: " << ToString(type_);
-      break;
-    default:
-      break;
-  }
-}
-
-AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
-                                     std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values)
-    : AidlNode(location),
-      type_(type),
-      values_(std::move(*values)),
-      is_valid_(false),
-      is_evaluated_(false),
-      final_type_(type) {
-  CHECK(type_ == Type::ARRAY);
-}
-
-AidlUnaryConstExpression::AidlUnaryConstExpression(const AidlLocation& location, const string& op,
-                                                   std::unique_ptr<AidlConstantValue> rval)
-    : AidlConstantValue(location, Type::UNARY, op + rval->value_),
-      unary_(std::move(rval)),
-      op_(op) {
-  final_type_ = Type::UNARY;
-}
-
-AidlBinaryConstExpression::AidlBinaryConstExpression(const AidlLocation& location,
-                                                     std::unique_ptr<AidlConstantValue> lval,
-                                                     const string& op,
-                                                     std::unique_ptr<AidlConstantValue> rval)
-    : AidlConstantValue(location, Type::BINARY, lval->value_ + op + rval->value_),
-      left_val_(std::move(lval)),
-      right_val_(std::move(rval)),
-      op_(op) {
-  final_type_ = Type::BINARY;
-}
diff --git a/aidl_language.cpp b/aidl_language.cpp
index e27dbbe..547816a 100644
--- a/aidl_language.cpp
+++ b/aidl_language.cpp
@@ -1,19 +1,3 @@
-/*
- * Copyright (C) 2015, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
 #include "aidl_language.h"
 #include "aidl_typenames.h"
 
@@ -21,6 +5,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <algorithm>
+#include <cassert>
 #include <iostream>
 #include <set>
 #include <sstream>
@@ -33,8 +18,8 @@
 
 #include "aidl_language_y.h"
 #include "logging.h"
-
-#include "aidl.h"
+#include "type_java.h"
+#include "type_namespace.h"
 
 #ifdef _WIN32
 int isatty(int  fd)
@@ -54,22 +39,6 @@
 using std::unique_ptr;
 using std::vector;
 
-namespace {
-bool is_java_keyword(const char* str) {
-  static const std::vector<std::string> kJavaKeywords{
-      "abstract", "assert", "boolean",    "break",     "byte",       "case",      "catch",
-      "char",     "class",  "const",      "continue",  "default",    "do",        "double",
-      "else",     "enum",   "extends",    "final",     "finally",    "float",     "for",
-      "goto",     "if",     "implements", "import",    "instanceof", "int",       "interface",
-      "long",     "native", "new",        "package",   "private",    "protected", "public",
-      "return",   "short",  "static",     "strictfp",  "super",      "switch",    "synchronized",
-      "this",     "throw",  "throws",     "transient", "try",        "void",      "volatile",
-      "while",    "true",   "false",      "null",
-  };
-  return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) != kJavaKeywords.end();
-}
-}  // namespace
-
 void yylex_init(void **);
 void yylex_destroy(void *);
 void yyset_in(FILE *f, void *);
@@ -107,125 +76,30 @@
 
 static const string kNullable("nullable");
 static const string kUtf8InCpp("utf8InCpp");
-static const string kVintfStability("VintfStability");
 static const string kUnsupportedAppUsage("UnsupportedAppUsage");
 static const string kSystemApi("SystemApi");
 static const string kStableParcelable("JavaOnlyStableParcelable");
-static const string kBacking("Backing");
 
-static const std::map<string, std::map<std::string, std::string>> kAnnotationParameters{
-    {kNullable, {}},
-    {kUtf8InCpp, {}},
-    {kVintfStability, {}},
-    {kUnsupportedAppUsage,
-     {{"expectedSignature", "String"},
-      {"implicitMember", "String"},
-      {"maxTargetSdk", "int"},
-      {"publicAlternatives", "String"},
-      {"trackingBug", "long"}}},
-    {kSystemApi, {}},
-    {kStableParcelable, {}},
-    {kBacking, {{"type", "String"}}}};
+static const set<string> kAnnotationNames{kNullable, kUtf8InCpp, kUnsupportedAppUsage, kSystemApi,
+                                          kStableParcelable};
 
-AidlAnnotation* AidlAnnotation::Parse(
-    const AidlLocation& location, const string& name,
-    std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list) {
-  if (kAnnotationParameters.find(name) == kAnnotationParameters.end()) {
+AidlAnnotation* AidlAnnotation::Parse(const AidlLocation& location, const string& name) {
+  if (kAnnotationNames.find(name) == kAnnotationNames.end()) {
     std::ostringstream stream;
     stream << "'" << name << "' is not a recognized annotation. ";
     stream << "It must be one of:";
-    for (const auto& kv : kAnnotationParameters) {
-      stream << " " << kv.first;
+    for (const string& kv : kAnnotationNames) {
+      stream << " " << kv;
     }
     stream << ".";
     AIDL_ERROR(location) << stream.str();
     return nullptr;
   }
-  if (parameter_list == nullptr) {
-    return new AidlAnnotation(location, name);
-  }
-
-  return new AidlAnnotation(location, name, std::move(*parameter_list));
+  return new AidlAnnotation(location, name);
 }
 
 AidlAnnotation::AidlAnnotation(const AidlLocation& location, const string& name)
-    : AidlAnnotation(location, name, {}) {}
-
-AidlAnnotation::AidlAnnotation(
-    const AidlLocation& location, const string& name,
-    std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters)
-    : AidlNode(location), name_(name), parameters_(std::move(parameters)) {}
-
-bool AidlAnnotation::CheckValid() const {
-  auto supported_params_iterator = kAnnotationParameters.find(GetName());
-  if (supported_params_iterator == kAnnotationParameters.end()) {
-    AIDL_ERROR(this) << GetName() << " annotation does not have any supported parameters.";
-    return false;
-  }
-  const auto& supported_params = supported_params_iterator->second;
-  for (const auto& name_and_param : parameters_) {
-    const std::string& param_name = name_and_param.first;
-    const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
-    if (!param->CheckValid()) {
-      AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
-                       << GetName() << ".";
-      return false;
-    }
-    auto parameter_mapping_it = supported_params.find(param_name);
-    if (parameter_mapping_it == supported_params.end()) {
-      std::ostringstream stream;
-      stream << "Parameter " << param_name << " not supported ";
-      stream << "for annotation " << GetName() << ".";
-      stream << "It must be one of:";
-      for (const auto& kv : supported_params) {
-        stream << " " << kv.first;
-      }
-      AIDL_ERROR(this) << stream.str();
-      return false;
-    }
-    AidlTypeSpecifier type{AIDL_LOCATION_HERE, parameter_mapping_it->second, false, nullptr, ""};
-    const std::string param_value = param->ValueString(type, AidlConstantValueDecorator);
-    // Assume error on empty string.
-    if (param_value == "") {
-      AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
-                       << GetName() << ".";
-      return false;
-    }
-  }
-  return true;
-}
-
-std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
-    const ConstantValueDecorator& decorator) const {
-  std::map<std::string, std::string> raw_params;
-  const auto& supported_params = kAnnotationParameters.at(GetName());
-  for (const auto& name_and_param : parameters_) {
-    const std::string& param_name = name_and_param.first;
-    const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
-    AidlTypeSpecifier type{AIDL_LOCATION_HERE, supported_params.at(param_name), false, nullptr, ""};
-    if (!param->CheckValid()) {
-      AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
-                       << GetName() << ".";
-      raw_params.clear();
-      return raw_params;
-    }
-
-    raw_params.emplace(param_name, param->ValueString(type, decorator));
-  }
-  return raw_params;
-}
-
-std::string AidlAnnotation::ToString(const ConstantValueDecorator& decorator) const {
-  if (parameters_.empty()) {
-    return "@" + GetName();
-  } else {
-    vector<string> param_strings;
-    for (const auto& [name, value] : AnnotationParams(decorator)) {
-      param_strings.emplace_back(name + "=" + value);
-    }
-    return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
-  }
-}
+    : AidlNode(location), name_(name) {}
 
 static bool HasAnnotation(const vector<AidlAnnotation>& annotations, const string& name) {
   for (const auto& a : annotations) {
@@ -236,16 +110,6 @@
   return false;
 }
 
-static const AidlAnnotation* GetAnnotation(const vector<AidlAnnotation>& annotations,
-                                           const string& name) {
-  for (const auto& a : annotations) {
-    if (a.GetName() == name) {
-      return &a;
-    }
-  }
-  return nullptr;
-}
-
 AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
 
 bool AidlAnnotatable::IsNullable() const {
@@ -256,29 +120,8 @@
   return HasAnnotation(annotations_, kUtf8InCpp);
 }
 
-bool AidlAnnotatable::IsVintfStability() const {
-  return HasAnnotation(annotations_, kVintfStability);
-}
-
-const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
-  return GetAnnotation(annotations_, kUnsupportedAppUsage);
-}
-
-const AidlTypeSpecifier* AidlAnnotatable::BackingType(const AidlTypenames& typenames) const {
-  auto annotation = GetAnnotation(annotations_, kBacking);
-  if (annotation != nullptr) {
-    auto annotation_params = annotation->AnnotationParams(AidlConstantValueDecorator);
-    if (auto it = annotation_params.find("type"); it != annotation_params.end()) {
-      const string& type = it->second;
-      AidlTypeSpecifier* type_specifier =
-          new AidlTypeSpecifier(AIDL_LOCATION_HERE,
-                                // Strip the quotes off the type String.
-                                type.substr(1, type.length() - 2), false, nullptr, "");
-      type_specifier->Resolve(typenames);
-      return type_specifier;
-    }
-  }
-  return nullptr;
+bool AidlAnnotatable::IsUnsupportedAppUsage() const {
+  return HasAnnotation(annotations_, kUnsupportedAppUsage);
 }
 
 bool AidlAnnotatable::IsSystemApi() const {
@@ -289,20 +132,10 @@
   return HasAnnotation(annotations_, kStableParcelable);
 }
 
-bool AidlAnnotatable::CheckValidAnnotations() const {
-  for (const auto& annotation : GetAnnotations()) {
-    if (!annotation.CheckValid()) {
-      return false;
-    }
-  }
-
-  return true;
-}
-
 string AidlAnnotatable::ToString() const {
   vector<string> ret;
   for (const auto& a : annotations_) {
-    ret.emplace_back(a.ToString(AidlConstantValueDecorator));
+    ret.emplace_back(a.ToString());
   }
   std::sort(ret.begin(), ret.end());
   return Join(ret, " ");
@@ -316,8 +149,7 @@
       unresolved_name_(unresolved_name),
       is_array_(is_array),
       type_params_(type_params),
-      comments_(comments),
-      split_name_(Split(unresolved_name, ".")) {}
+      comments_(comments) {}
 
 AidlTypeSpecifier AidlTypeSpecifier::ArrayBase() const {
   AIDL_FATAL_IF(!is_array_, this);
@@ -351,20 +183,16 @@
   return ret;
 }
 
-bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames) {
-  CHECK(!IsResolved());
+bool AidlTypeSpecifier::Resolve(android::aidl::AidlTypenames& typenames) {
+  assert(!IsResolved());
   pair<string, bool> result = typenames.ResolveTypename(unresolved_name_);
   if (result.second) {
     fully_qualified_name_ = result.first;
-    split_name_ = Split(fully_qualified_name_, ".");
   }
   return result.second;
 }
 
 bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
-  if (!CheckValidAnnotations()) {
-    return false;
-  }
   if (IsGeneric()) {
     const string& type_name = GetName();
     const int num = GetTypeParameters().size();
@@ -403,11 +231,6 @@
       AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
       return false;
     }
-    const auto definedType = typenames.TryGetDefinedType(GetName());
-    if (definedType != nullptr && definedType->AsEnumDeclaration() != nullptr && !IsArray()) {
-      AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
-      return false;
-    }
   }
   return true;
 }
@@ -452,7 +275,7 @@
 
 std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
   if (default_value_ != nullptr) {
-    return default_value_->ValueString(GetType(), decorator);
+    return GetDefaultValue()->As(GetType(), decorator);
   } else {
     return "";
   }
@@ -504,6 +327,207 @@
 
 AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
 
+AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
+                                     const std::string& checked_value)
+    : AidlNode(location), type_(type), value_(checked_value) {
+  CHECK(!value_.empty() || type_ == Type::ERROR);
+  CHECK(type_ != Type::ARRAY);
+}
+
+AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
+                                     std::vector<std::unique_ptr<AidlConstantValue>>* values)
+    : AidlNode(location), type_(type), values_(std::move(*values)) {}
+
+static bool isValidLiteralChar(char c) {
+  return !(c <= 0x1f ||  // control characters are < 0x20
+           c >= 0x7f ||  // DEL is 0x7f
+           c == '\\');   // Disallow backslashes for future proofing.
+}
+
+AidlConstantValue* AidlConstantValue::Boolean(const AidlLocation& location, bool value) {
+  return new AidlConstantValue(location, Type::BOOLEAN, value ? "true" : "false");
+}
+
+AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location, char value) {
+  if (!isValidLiteralChar(value)) {
+    AIDL_ERROR(location) << "Invalid character literal " << value;
+    return new AidlConstantValue(location, Type::ERROR, "");
+  }
+  return new AidlConstantValue(location, Type::CHARACTER, std::string("'") + value + "'");
+}
+
+AidlConstantValue* AidlConstantValue::Floating(const AidlLocation& location,
+                                               const std::string& value) {
+  return new AidlConstantValue(location, Type::FLOATING, value);
+}
+
+AidlConstantValue* AidlConstantValue::Hex(const AidlLocation& location, const std::string& value) {
+  return new AidlConstantValue(location, Type::HEXIDECIMAL, value);
+}
+
+AidlConstantValue* AidlConstantValue::Integral(const AidlLocation& location,
+                                               const std::string& value) {
+  return new AidlConstantValue(location, Type::INTEGRAL, value);
+}
+
+AidlConstantValue* AidlConstantValue::Array(
+    const AidlLocation& location, std::vector<std::unique_ptr<AidlConstantValue>>* values) {
+  return new AidlConstantValue(location, Type::ARRAY, values);
+}
+
+AidlConstantValue* AidlConstantValue::String(const AidlLocation& location,
+                                             const std::string& value) {
+  for (size_t i = 0; i < value.length(); ++i) {
+    if (!isValidLiteralChar(value[i])) {
+      AIDL_ERROR(location) << "Found invalid character at index " << i << " in string constant '"
+                           << value << "'";
+      return new AidlConstantValue(location, Type::ERROR, "");
+    }
+  }
+
+  return new AidlConstantValue(location, Type::STRING, value);
+}
+
+bool AidlConstantValue::CheckValid() const {
+  // error always logged during creation
+  return type_ != AidlConstantValue::Type::ERROR;
+}
+
+static string TrimIfSuffix(const string& str, const string& suffix) {
+  if (str.size() > suffix.size() &&
+      0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix)) {
+    return str.substr(0, str.size() - suffix.size());
+  }
+  return str;
+}
+
+string AidlConstantValue::As(const AidlTypeSpecifier& type,
+                             const ConstantValueDecorator& decorator) const {
+  if (type.IsGeneric()) {
+    AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
+    return "";
+  }
+
+  const std::string& type_string = type.GetName();
+
+  if ((type_ == Type::ARRAY) != type.IsArray()) {
+    goto mismatch_error;
+  }
+
+  switch (type_) {
+    case AidlConstantValue::Type::ARRAY: {
+      vector<string> raw_values;
+      raw_values.reserve(values_.size());
+
+      bool success = true;
+      for (const auto& value : values_) {
+        const AidlTypeSpecifier& array_base = type.ArrayBase();
+        const std::string raw_value = value->As(array_base, decorator);
+
+        success &= !raw_value.empty();
+        raw_values.push_back(decorator(array_base, raw_value));
+      }
+      if (!success) {
+        AIDL_ERROR(this) << "Default value must be a literal array of " << type_string << ".";
+        return "";
+      }
+      return decorator(type, "{" + Join(raw_values, ", ") + "}");
+    }
+    case AidlConstantValue::Type::BOOLEAN:
+      if (type_string == "boolean") return decorator(type, value_);
+      goto mismatch_error;
+    case AidlConstantValue::Type::CHARACTER:
+      if (type_string == "char") return decorator(type, value_);
+      goto mismatch_error;
+    case AidlConstantValue::Type::FLOATING: {
+      bool is_float_literal = value_.back() == 'f';
+      const std::string raw_value = TrimIfSuffix(value_, "f");
+
+      if (type_string == "double") {
+        double parsed_value;
+        if (!android::base::ParseDouble(raw_value, &parsed_value)) goto parse_error;
+        return decorator(type, std::to_string(parsed_value));
+      }
+      if (is_float_literal && type_string == "float") {
+        float parsed_value;
+        if (!android::base::ParseFloat(raw_value, &parsed_value)) goto parse_error;
+        return decorator(type, std::to_string(parsed_value) + "f");
+      }
+      goto mismatch_error;
+    }
+    case AidlConstantValue::Type::HEXIDECIMAL:
+      // For historical reasons, a hexidecimal int needs to have the specified bits interpreted
+      // as the signed type, so the other types are made consistent with it.
+      if (type_string == "byte") {
+        uint8_t unsigned_value;
+        if (!android::base::ParseUint<uint8_t>(value_, &unsigned_value)) goto parse_error;
+        return decorator(type, std::to_string((int8_t)unsigned_value));
+      }
+      if (type_string == "int") {
+        uint32_t unsigned_value;
+        if (!android::base::ParseUint<uint32_t>(value_, &unsigned_value)) goto parse_error;
+        return decorator(type, std::to_string((int32_t)unsigned_value));
+      }
+      if (type_string == "long") {
+        uint64_t unsigned_value;
+        if (!android::base::ParseUint<uint64_t>(value_, &unsigned_value)) goto parse_error;
+        return decorator(type, std::to_string((int64_t)unsigned_value));
+      }
+      goto mismatch_error;
+    case AidlConstantValue::Type::INTEGRAL:
+      if (type_string == "byte") {
+        if (!android::base::ParseInt<int8_t>(value_, nullptr)) goto parse_error;
+        return decorator(type, value_);
+      }
+      if (type_string == "int") {
+        if (!android::base::ParseInt<int32_t>(value_, nullptr)) goto parse_error;
+        return decorator(type, value_);
+      }
+      if (type_string == "long") {
+        if (!android::base::ParseInt<int64_t>(value_, nullptr)) goto parse_error;
+        return decorator(type, value_);
+      }
+      goto mismatch_error;
+    case AidlConstantValue::Type::STRING:
+      if (type_string == "String") return decorator(type, value_);
+      goto mismatch_error;
+    default:
+      AIDL_FATAL(this) << "Unrecognized constant value type";
+  }
+
+mismatch_error:
+  AIDL_ERROR(this) << "Expecting type " << type_string << " but constant is " << ToString(type_);
+  return "";
+parse_error:
+  AIDL_ERROR(this) << "Could not parse " << value_ << " as " << type_string;
+  return "";
+}
+
+string AidlConstantValue::ToString(Type type) {
+  switch (type) {
+    case Type::ARRAY:
+      return "a literal array";
+    case Type::BOOLEAN:
+      return "a literal boolean";
+    case Type::CHARACTER:
+      return "a literal char";
+    case Type::FLOATING:
+      return "a floating-point literal";
+    case Type::HEXIDECIMAL:
+      return "a hexidecimal literal";
+    case Type::INTEGRAL:
+      return "an integral literal";
+    case Type::STRING:
+      return "a literal string";
+    case Type::ERROR:
+      LOG(FATAL) << "aidl internal error: error type failed to halt program";
+      return "";
+    default:
+      LOG(FATAL) << "aidl internal error: unknown constant type: " << static_cast<int>(type);
+      return "";  // not reached
+  }
+}
+
 AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
                                                  AidlTypeSpecifier* type, const std::string& name,
                                                  AidlConstantValue* value)
@@ -521,7 +545,7 @@
     return false;
   }
 
-  return true;
+  return !ValueString(AidlConstantValueDecorator).empty();
 }
 
 string AidlConstantDeclaration::ToString() const {
@@ -611,9 +635,6 @@
 
 bool AidlParcelable::CheckValid(const AidlTypenames&) const {
   static const std::set<string> allowed{kStableParcelable};
-  if (!CheckValidAnnotations()) {
-    return false;
-  }
   for (const auto& v : GetAnnotations()) {
     if (allowed.find(v.GetName()) == allowed.end()) {
       std::ostringstream stream;
@@ -651,170 +672,12 @@
 }
 
 bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
-  bool success = true;
   for (const auto& v : GetFields()) {
-    success = success && v->CheckValid(typenames);
-  }
-  return success;
-}
-
-// TODO: we should treat every backend all the same in future.
-bool AidlTypeSpecifier::LanguageSpecificCheckValid(Options::Language lang) const {
-  if (lang == Options::Language::CPP) {
-    if (this->GetName() == "List" && !this->IsGeneric()) {
-      AIDL_ERROR(this) << "List without type isn't supported in cpp.";
+    if (!(v->CheckValid(typenames))) {
       return false;
     }
   }
-  if (this->IsGeneric()) {
-    if (this->GetName() == "List") {
-      if (this->GetTypeParameters().size() != 1) {
-        AIDL_ERROR(this) << "List must have only one type parameter.";
-        return false;
-      }
-      if (lang == Options::Language::CPP) {
-        auto& name = this->GetTypeParameters()[0]->GetName();
-        if (!(name == "String" || name == "IBinder")) {
-          AIDL_ERROR(this) << "List in cpp supports only string and IBinder for now.";
-          return false;
-        }
-      } else if (lang == Options::Language::NDK) {
-        AIDL_ERROR(this) << "NDK backend does not support List yet.";
-        return false;
-      }
 
-    } else if (this->GetName() == "Map") {
-      if (lang != Options::Language::JAVA) {
-        AIDL_ERROR(this) << "Currently, only Java backend supports Map.";
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-// TODO: we should treat every backend all the same in future.
-bool AidlParcelable::LanguageSpecificCheckValid(Options::Language lang) const {
-  if (lang != Options::Language::JAVA) {
-    if (this->IsStableParcelable()) {
-      AIDL_ERROR(this) << "@JavaOnlyStableParcelable supports only Java target.";
-      return false;
-    }
-    const AidlParcelable* unstructuredParcelable = this->AsUnstructuredParcelable();
-    if (unstructuredParcelable != nullptr) {
-      if (unstructuredParcelable->GetCppHeader().empty()) {
-        AIDL_ERROR(unstructuredParcelable)
-            << "Unstructured parcelable must have C++ header defined.";
-        return false;
-      }
-    }
-  }
-  return true;
-}
-
-// TODO: we should treat every backend all the same in future.
-bool AidlStructuredParcelable::LanguageSpecificCheckValid(Options::Language lang) const {
-  if (!AidlParcelable::LanguageSpecificCheckValid(lang)) {
-    return false;
-  }
-  for (const auto& v : this->GetFields()) {
-    if (!v->GetType().LanguageSpecificCheckValid(lang)) {
-      return false;
-    }
-  }
-  return true;
-}
-
-AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
-                               AidlConstantValue* value, const std::string& comments)
-    : AidlNode(location), name_(name), value_(value), comments_(comments) {}
-
-bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
-  if (GetValue() == nullptr) {
-    return false;
-  }
-  if (!GetValue()->CheckValid()) {
-    return false;
-  }
-  if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
-    AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
-    return false;
-  }
-  return true;
-}
-
-string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
-                                   const ConstantValueDecorator& decorator) const {
-  return GetValue()->ValueString(backing_type, decorator);
-}
-
-AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
-                                         std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
-                                         const std::vector<std::string>& package,
-                                         const std::string& comments)
-    : AidlDefinedType(location, name, comments, package), enumerators_(std::move(*enumerators)) {}
-
-void AidlEnumDeclaration::SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type) {
-  backing_type_ = std::move(type);
-}
-
-void AidlEnumDeclaration::Autofill() {
-  const AidlEnumerator* previous = nullptr;
-  for (const auto& enumerator : enumerators_) {
-    if (enumerator->GetValue() == nullptr) {
-      if (previous == nullptr) {
-        enumerator->SetValue(std::unique_ptr<AidlConstantValue>(
-            AidlConstantValue::Integral(AIDL_LOCATION_HERE, "0")));
-      } else {
-        enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
-            AIDL_LOCATION_HERE,
-            std::unique_ptr<AidlConstantValue>(
-                AidlConstantValue::ShallowIntegralCopy(*previous->GetValue())),
-            "+",
-            std::unique_ptr<AidlConstantValue>(
-                AidlConstantValue::Integral(AIDL_LOCATION_HERE, "1"))));
-      }
-    }
-    previous = enumerator.get();
-  }
-}
-
-bool AidlEnumDeclaration::CheckValid(const AidlTypenames&) const {
-  if (backing_type_ == nullptr) {
-    AIDL_ERROR(this) << "Enum declaration missing backing type.";
-    return false;
-  }
-  bool success = true;
-  for (const auto& enumerator : enumerators_) {
-    success = success && enumerator->CheckValid(GetBackingType());
-  }
-  return success;
-}
-
-void AidlEnumDeclaration::Write(CodeWriter* writer) const {
-  writer->Write("%s\n", AidlAnnotatable::ToString().c_str());
-  writer->Write("enum %s {\n", GetName().c_str());
-  writer->Indent();
-  for (const auto& enumerator : GetEnumerators()) {
-    writer->Write("%s = %s,\n", enumerator->GetName().c_str(),
-                  enumerator->ValueString(GetBackingType(), AidlConstantValueDecorator).c_str());
-  }
-  writer->Dedent();
-  writer->Write("}\n");
-}
-
-// TODO: we should treat every backend all the same in future.
-bool AidlInterface::LanguageSpecificCheckValid(Options::Language lang) const {
-  for (const auto& m : this->GetMethods()) {
-    if (!m->GetType().LanguageSpecificCheckValid(lang)) {
-      return false;
-    }
-    for (const auto& arg : m->GetArguments()) {
-      if (!arg->GetType().LanguageSpecificCheckValid(lang)) {
-        return false;
-      }
-    }
-  }
   return true;
 }
 
@@ -857,9 +720,6 @@
 }
 
 bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
-  if (!CheckValidAnnotations()) {
-    return false;
-  }
   // Has to be a pointer due to deleting copy constructor. No idea why.
   map<string, const AidlMethod*> method_names;
   for (const auto& m : GetMethods()) {
@@ -890,29 +750,6 @@
         AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
         return false;
       }
-      const bool can_be_out = typenames.CanBeOutParameter(arg->GetType());
-      if (!arg->DirectionWasSpecified() && can_be_out) {
-        AIDL_ERROR(arg) << "'" << arg->GetType().ToString()
-                        << "' can be an out type, so you must declare it as in, out, or inout.";
-        return false;
-      }
-
-      if (arg->GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
-        AIDL_ERROR(arg) << "'" << arg->ToString() << "' can only be an in parameter.";
-        return false;
-      }
-
-      // check that the name doesn't match a keyword
-      if (is_java_keyword(arg->GetName().c_str())) {
-        AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
-        return false;
-      }
-
-      // Reserve a namespace for internal use
-      if (android::base::StartsWith(arg->GetName(), "_aidl")) {
-        AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
-        return false;
-      }
     }
 
     auto it = method_names.find(m->GetName());
diff --git a/aidl_language.h b/aidl_language.h
index ca2e359..49a4606 100644
--- a/aidl_language.h
+++ b/aidl_language.h
@@ -1,26 +1,10 @@
-/*
- * Copyright (C) 2019, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
 #pragma once
 
 #include "aidl_typenames.h"
 #include "code_writer.h"
 #include "io_delegate.h"
-#include "options.h"
 
+#include <cassert>
 #include <memory>
 #include <string>
 #include <vector>
@@ -33,11 +17,11 @@
 
 using android::aidl::AidlTypenames;
 using android::aidl::CodeWriter;
-using android::aidl::Options;
 using std::shared_ptr;
 using std::string;
 using std::unique_ptr;
 using std::vector;
+
 class AidlNode;
 
 namespace android {
@@ -144,44 +128,29 @@
 namespace android {
 namespace aidl {
 
+class ValidatableType;
 class AidlTypenames;
 
 }  // namespace aidl
 }  // namespace android
 
-class AidlConstantValue;
-class AidlConstantDeclaration;
-
-// Transforms a value string into a language specific form. Raw value as produced by
-// AidlConstantValue.
-using ConstantValueDecorator =
-    std::function<std::string(const AidlTypeSpecifier& type, const std::string& raw_value)>;
-
 class AidlAnnotation : public AidlNode {
  public:
-  static AidlAnnotation* Parse(
-      const AidlLocation& location, const string& name,
-      std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list);
+  static AidlAnnotation* Parse(const AidlLocation& location, const string& name);
 
   AidlAnnotation(const AidlAnnotation&) = default;
   AidlAnnotation(AidlAnnotation&&) = default;
   virtual ~AidlAnnotation() = default;
-  bool CheckValid() const;
 
   const string& GetName() const { return name_; }
-  string ToString(const ConstantValueDecorator& decorator) const;
-  std::map<std::string, std::string> AnnotationParams(
-      const ConstantValueDecorator& decorator) const;
+  string ToString() const { return "@" + name_; }
   const string& GetComments() const { return comments_; }
   void SetComments(const string& comments) { comments_ = comments; }
 
  private:
   AidlAnnotation(const AidlLocation& location, const string& name);
-  AidlAnnotation(const AidlLocation& location, const string& name,
-                 std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters);
   const string name_;
   string comments_;
-  std::map<std::string, std::shared_ptr<AidlConstantValue>> parameters_;
 };
 
 static inline bool operator<(const AidlAnnotation& lhs, const AidlAnnotation& rhs) {
@@ -199,23 +168,15 @@
   AidlAnnotatable(AidlAnnotatable&&) = default;
   virtual ~AidlAnnotatable() = default;
 
-  void Annotate(vector<AidlAnnotation>&& annotations) {
-    for (auto& annotation : annotations) {
-      annotations_.emplace_back(std::move(annotation));
-    }
-  }
+  void Annotate(vector<AidlAnnotation>&& annotations) { annotations_ = std::move(annotations); }
   bool IsNullable() const;
   bool IsUtf8InCpp() const;
-  bool IsVintfStability() const;
+  bool IsUnsupportedAppUsage() const;
   bool IsSystemApi() const;
   bool IsStableParcelable() const;
-
-  const AidlAnnotation* UnsupportedAppUsage() const;
-  const AidlTypeSpecifier* BackingType(const AidlTypenames& typenames) const;
   std::string ToString() const;
 
   const vector<AidlAnnotation>& GetAnnotations() const { return annotations_; }
-  bool CheckValidAnnotations() const;
 
  private:
   vector<AidlAnnotation> annotations_;
@@ -248,7 +209,7 @@
   }
 
   // Returns string representation of this type specifier.
-  // This is GetBaseTypeName() + array modifier or generic type parameters
+  // This is GetBaseTypeName() + array modifieir or generic type parameters
   string ToString() const;
 
   std::string Signature() const;
@@ -257,8 +218,6 @@
 
   const string& GetComments() const { return comments_; }
 
-  const std::vector<std::string> GetSplitName() const { return split_name_; }
-
   void SetComments(const string& comment) { comments_ = comment; }
 
   bool IsResolved() const { return fully_qualified_name_ != ""; }
@@ -271,11 +230,18 @@
 
   // Resolve the base type name to a fully-qualified name. Return false if the
   // resolution fails.
-  bool Resolve(const AidlTypenames& typenames);
+  bool Resolve(android::aidl::AidlTypenames& typenames);
 
   bool CheckValid(const AidlTypenames& typenames) const;
-  bool LanguageSpecificCheckValid(Options::Language lang) const;
 
+  void SetLanguageType(const android::aidl::ValidatableType* language_type) {
+    language_type_ = language_type;
+  }
+
+  template<typename T>
+  const T* GetLanguageType() const {
+    return reinterpret_cast<const T*>(language_type_);
+  }
  private:
   AidlTypeSpecifier(const AidlTypeSpecifier&) = default;
 
@@ -284,9 +250,13 @@
   bool is_array_;
   const shared_ptr<vector<unique_ptr<AidlTypeSpecifier>>> type_params_;
   string comments_;
-  vector<string> split_name_;
+  const android::aidl::ValidatableType* language_type_ = nullptr;
 };
 
+// Transforms a value string into a language specific form. Raw value as produced by
+// AidlConstantValue.
+using ConstantValueDecorator =
+    std::function<std::string(const AidlTypeSpecifier& type, const std::string& raw_value)>;
 
 // Returns the universal value unaltered.
 std::string AidlConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value);
@@ -347,7 +317,6 @@
 
 class AidlMethod;
 class AidlConstantDeclaration;
-class AidlEnumDeclaration;
 class AidlMember : public AidlNode {
  public:
   AidlMember(const AidlLocation& location);
@@ -360,170 +329,85 @@
   DISALLOW_COPY_AND_ASSIGN(AidlMember);
 };
 
-class AidlUnaryConstExpression;
-class AidlBinaryConstExpression;
-
 class AidlConstantValue : public AidlNode {
  public:
-  enum class Type {
-    // WARNING: Don't change this order! The order is used to determine type
-    // promotion during a binary expression.
-    BOOLEAN,
-    INT8,
-    INT32,
-    INT64,
-    ARRAY,
-    CHARACTER,
-    STRING,
-    FLOATING,
-    UNARY,
-    BINARY,
-    ERROR,
-  };
-
-  /*
-   * Return the value casted to the given type.
-   */
-  template <typename T>
-  T cast() const;
+  enum class Type { ERROR, ARRAY, BOOLEAN, CHARACTER, FLOATING, HEXIDECIMAL, INTEGRAL, STRING };
 
   virtual ~AidlConstantValue() = default;
 
   static AidlConstantValue* Boolean(const AidlLocation& location, bool value);
   static AidlConstantValue* Character(const AidlLocation& location, char value);
-  // example: 123, -5498, maybe any size
-  static AidlConstantValue* Integral(const AidlLocation& location, const string& value);
+  // example: "0x4f"
   static AidlConstantValue* Floating(const AidlLocation& location, const std::string& value);
+  static AidlConstantValue* Hex(const AidlLocation& location, const std::string& value);
+  // example: 123, -5498, maybe any size
+  static AidlConstantValue* Integral(const AidlLocation& location, const std::string& value);
   static AidlConstantValue* Array(const AidlLocation& location,
-                                  std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values);
+                                  std::vector<std::unique_ptr<AidlConstantValue>>* values);
   // example: "\"asdf\""
-  static AidlConstantValue* String(const AidlLocation& location, const string& value);
+  static AidlConstantValue* String(const AidlLocation& location, const std::string& value);
 
-  // Construct an AidlConstantValue by evaluating the other integral constant's
-  // value string. This does not preserve the structure of the copied constant.
-  static AidlConstantValue* ShallowIntegralCopy(const AidlConstantValue& other);
+  Type GetType() const { return type_; }
 
-  Type GetType() const { return final_type_; }
-
-  virtual bool CheckValid() const;
+  bool CheckValid() const;
 
   // Raw value of type (currently valid in C++ and Java). Empty string on error.
-  virtual string ValueString(const AidlTypeSpecifier& type,
-                             const ConstantValueDecorator& decorator) const;
+  string As(const AidlTypeSpecifier& type, const ConstantValueDecorator& decorator) const;
 
  private:
-  AidlConstantValue(const AidlLocation& location, Type parsed_type, int64_t parsed_value,
-                    const string& checked_value);
-  AidlConstantValue(const AidlLocation& location, Type type, const string& checked_value);
+  AidlConstantValue(const AidlLocation& location, Type type, const std::string& checked_value);
   AidlConstantValue(const AidlLocation& location, Type type,
-                    std::unique_ptr<vector<unique_ptr<AidlConstantValue>>> values);
+                    std::vector<std::unique_ptr<AidlConstantValue>>* values);
   static string ToString(Type type);
-  static bool ParseIntegral(const string& value, int64_t* parsed_value, Type* parsed_type);
-  static bool IsHex(const string& value);
-  virtual bool evaluate(const AidlTypeSpecifier& type) const;
 
   const Type type_ = Type::ERROR;
-  const vector<unique_ptr<AidlConstantValue>> values_;  // if type_ == ARRAY
-  const string value_;                                  // otherwise
-
-  // State for tracking evaluation of expressions
-  mutable bool is_valid_;
-  mutable bool is_evaluated_;
-  mutable Type final_type_;
-  mutable int64_t final_value_;
-  mutable string final_string_value_ = "";
+  const std::vector<std::unique_ptr<AidlConstantValue>> values_;  // if type_ == ARRAY
+  const std::string value_;                                       // otherwise
 
   DISALLOW_COPY_AND_ASSIGN(AidlConstantValue);
-
-  friend AidlUnaryConstExpression;
-  friend AidlBinaryConstExpression;
-};
-
-class AidlUnaryConstExpression : public AidlConstantValue {
- public:
-  AidlUnaryConstExpression(const AidlLocation& location, const string& op,
-                           std::unique_ptr<AidlConstantValue> rval);
-
-  static bool IsCompatibleType(Type type, const string& op);
-  bool CheckValid() const override;
-  string ValueString(const AidlTypeSpecifier& type,
-                     const ConstantValueDecorator& decorator) const override;
-
- private:
-  bool evaluate(const AidlTypeSpecifier& type) const override;
-
-  std::unique_ptr<AidlConstantValue> unary_;
-  const string op_;
-};
-
-class AidlBinaryConstExpression : public AidlConstantValue {
- public:
-  AidlBinaryConstExpression(const AidlLocation& location, std::unique_ptr<AidlConstantValue> lval,
-                            const string& op, std::unique_ptr<AidlConstantValue> rval);
-
-  bool CheckValid() const override;
-  string ValueString(const AidlTypeSpecifier& type,
-                     const ConstantValueDecorator& decorator) const override;
-
-  static bool AreCompatibleTypes(Type t1, Type t2);
-  // Returns the promoted kind for both operands
-  static Type UsualArithmeticConversion(Type left, Type right);
-  // Returns the promoted integral type where INT32 is the smallest type
-  static Type IntegralPromotion(Type in);
-
- private:
-  bool evaluate(const AidlTypeSpecifier& type) const override;
-
-  std::unique_ptr<AidlConstantValue> left_val_;
-  std::unique_ptr<AidlConstantValue> right_val_;
-  const string op_;
-};
-
-struct AidlAnnotationParameter {
-  std::string name;
-  std::unique_ptr<AidlConstantValue> value;
 };
 
 class AidlConstantDeclaration : public AidlMember {
  public:
   AidlConstantDeclaration(const AidlLocation& location, AidlTypeSpecifier* specifier,
-                          const string& name, AidlConstantValue* value);
+                          const std::string& name, AidlConstantValue* value);
   virtual ~AidlConstantDeclaration() = default;
 
   const AidlTypeSpecifier& GetType() const { return *type_; }
   AidlTypeSpecifier* GetMutableType() { return type_.get(); }
-  const string& GetName() const { return name_; }
+  const std::string& GetName() const { return name_; }
   const AidlConstantValue& GetValue() const { return *value_; }
   bool CheckValid(const AidlTypenames& typenames) const;
 
-  string ToString() const;
-  string Signature() const;
+  std::string ToString() const;
+  std::string Signature() const;
   string ValueString(const ConstantValueDecorator& decorator) const {
-    return value_->ValueString(GetType(), decorator);
+    return GetValue().As(GetType(), decorator);
   }
 
   AidlConstantDeclaration* AsConstantDeclaration() override { return this; }
 
  private:
   const unique_ptr<AidlTypeSpecifier> type_;
-  const string name_;
-  unique_ptr<AidlConstantValue> value_;
+  const std::string name_;
+  const unique_ptr<AidlConstantValue> value_;
 
   DISALLOW_COPY_AND_ASSIGN(AidlConstantDeclaration);
 };
 
 class AidlMethod : public AidlMember {
  public:
-  AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type, const string& name,
-             vector<unique_ptr<AidlArgument>>* args, const string& comments);
-  AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type, const string& name,
-             vector<unique_ptr<AidlArgument>>* args, const string& comments, int id,
-             bool is_user_defined = true);
+  AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
+             const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
+             const std::string& comments);
+  AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
+             const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
+             const std::string& comments, int id, bool is_user_defined = true);
   virtual ~AidlMethod() = default;
 
   AidlMethod* AsMethod() override { return this; }
 
-  const string& GetComments() const { return comments_; }
+  const std::string& GetComments() const { return comments_; }
   const AidlTypeSpecifier& GetType() const { return *type_; }
   AidlTypeSpecifier* GetMutableType() { return type_.get(); }
 
@@ -602,7 +486,7 @@
 class AidlInterface;
 class AidlParcelable;
 class AidlStructuredParcelable;
-// AidlDefinedType represents either an interface, parcelable, or enum that is
+// AidlDefinedType represents either an interface or a parcelable that is
 // defined in the source file.
 class AidlDefinedType : public AidlAnnotatable {
  public:
@@ -624,10 +508,9 @@
 
   virtual const AidlStructuredParcelable* AsStructuredParcelable() const { return nullptr; }
   virtual const AidlParcelable* AsParcelable() const { return nullptr; }
-  virtual const AidlEnumDeclaration* AsEnumDeclaration() const { return nullptr; }
   virtual const AidlInterface* AsInterface() const { return nullptr; }
-  virtual bool CheckValid(const AidlTypenames&) const { return CheckValidAnnotations(); }
-  virtual bool LanguageSpecificCheckValid(Options::Language lang) const = 0;
+  virtual bool CheckValid(const AidlTypenames&) const { return true; }
+
   AidlStructuredParcelable* AsStructuredParcelable() {
     return const_cast<AidlStructuredParcelable*>(
         const_cast<const AidlDefinedType*>(this)->AsStructuredParcelable());
@@ -635,10 +518,6 @@
   AidlParcelable* AsParcelable() {
     return const_cast<AidlParcelable*>(const_cast<const AidlDefinedType*>(this)->AsParcelable());
   }
-  AidlEnumDeclaration* AsEnumDeclaration() {
-    return const_cast<AidlEnumDeclaration*>(
-        const_cast<const AidlDefinedType*>(this)->AsEnumDeclaration());
-  }
   AidlInterface* AsInterface() {
     return const_cast<AidlInterface*>(const_cast<const AidlDefinedType*>(this)->AsInterface());
   }
@@ -652,11 +531,21 @@
         const_cast<const AidlDefinedType*>(this)->AsUnstructuredParcelable());
   }
 
+  void SetLanguageType(const android::aidl::ValidatableType* language_type) {
+    language_type_ = language_type;
+  }
+
+  template <typename T>
+  const T* GetLanguageType() const {
+    return reinterpret_cast<const T*>(language_type_);
+  }
+
   virtual void Write(CodeWriter* writer) const = 0;
 
  private:
   std::string name_;
   std::string comments_;
+  const android::aidl::ValidatableType* language_type_ = nullptr;
   const std::vector<std::string> package_;
 
   DISALLOW_COPY_AND_ASSIGN(AidlDefinedType);
@@ -674,7 +563,7 @@
   std::string GetCppHeader() const { return cpp_header_; }
 
   bool CheckValid(const AidlTypenames& typenames) const override;
-  bool LanguageSpecificCheckValid(Options::Language lang) const override;
+
   const AidlParcelable* AsParcelable() const override { return this; }
   std::string GetPreprocessDeclarationName() const override { return "parcelable"; }
 
@@ -703,7 +592,6 @@
   void Write(CodeWriter* writer) const override;
 
   bool CheckValid(const AidlTypenames& typenames) const override;
-  bool LanguageSpecificCheckValid(Options::Language lang) const override;
 
  private:
   const std::vector<std::unique_ptr<AidlVariableDeclaration>> variables_;
@@ -711,58 +599,6 @@
   DISALLOW_COPY_AND_ASSIGN(AidlStructuredParcelable);
 };
 
-class AidlEnumerator : public AidlNode {
- public:
-  AidlEnumerator(const AidlLocation& location, const std::string& name, AidlConstantValue* value,
-                 const std::string& comments);
-  virtual ~AidlEnumerator() = default;
-
-  const std::string& GetName() const { return name_; }
-  AidlConstantValue* GetValue() const { return value_.get(); }
-  const std::string& GetComments() const { return comments_; }
-  bool CheckValid(const AidlTypeSpecifier& enum_backing_type) const;
-
-  string ValueString(const AidlTypeSpecifier& backing_type,
-                     const ConstantValueDecorator& decorator) const;
-
-  void SetValue(std::unique_ptr<AidlConstantValue> value) { value_ = std::move(value); }
-
- private:
-  const std::string name_;
-  unique_ptr<AidlConstantValue> value_;
-  const std::string comments_;
-
-  DISALLOW_COPY_AND_ASSIGN(AidlEnumerator);
-};
-
-class AidlEnumDeclaration : public AidlDefinedType {
- public:
-  AidlEnumDeclaration(const AidlLocation& location, const string& name,
-                      std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
-                      const std::vector<std::string>& package, const std::string& comments);
-  virtual ~AidlEnumDeclaration() = default;
-
-  void SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type);
-  const AidlTypeSpecifier& GetBackingType() const { return *backing_type_; }
-  const std::vector<std::unique_ptr<AidlEnumerator>>& GetEnumerators() const {
-    return enumerators_;
-  }
-  void Autofill();
-  bool CheckValid(const AidlTypenames& typenames) const override;
-  bool LanguageSpecificCheckValid(Options::Language) const override { return true; }
-  std::string GetPreprocessDeclarationName() const override { return "enum"; }
-  void Write(CodeWriter*) const override;
-
-  const AidlEnumDeclaration* AsEnumDeclaration() const override { return this; }
-
- private:
-  const std::string name_;
-  const std::vector<std::unique_ptr<AidlEnumerator>> enumerators_;
-  std::unique_ptr<const AidlTypeSpecifier> backing_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(AidlEnumDeclaration);
-};
-
 class AidlInterface final : public AidlDefinedType {
  public:
   AidlInterface(const AidlLocation& location, const std::string& name, const std::string& comments,
@@ -783,7 +619,6 @@
   void Write(CodeWriter* writer) const override;
 
   bool CheckValid(const AidlTypenames& typenames) const override;
-  bool LanguageSpecificCheckValid(Options::Language lang) const override;
 
  private:
   std::vector<std::unique_ptr<AidlMethod>> methods_;
diff --git a/aidl_language_l.ll b/aidl_language_l.ll
index 8667ab4..862332c 100644
--- a/aidl_language_l.ll
+++ b/aidl_language_l.ll
@@ -1,19 +1,3 @@
-/*
- * Copyright (C) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
 %{
 #include <string.h>
 #include <stdlib.h>
@@ -36,9 +20,9 @@
 
 identifier  [_a-zA-Z][_a-zA-Z0-9]*
 whitespace  ([ \t\r]+)
-intvalue    [0-9]+[lL]?
+intvalue    [-+]?(0|[1-9][0-9]*)
 hexvalue    0[x|X][0-9a-fA-F]+
-floatvalue  [0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?
+floatvalue  [-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?f?
 
 %%
 %{
@@ -62,44 +46,25 @@
 \"[^\"]*\"            { yylval->token = new AidlToken(yytext, extra_text);
                         return yy::parser::token::C_STR; }
 
-\/\/.*                { extra_text += yytext; extra_text += "\n"; }
+\/\/.*\n              { extra_text += yytext; yylloc->lines(1); yylloc->step(); }
 
 \n+                   { yylloc->lines(yyleng); yylloc->step(); }
 {whitespace}          {}
 <<EOF>>               { yyterminate(); }
 
     /* symbols */
-"("                   { return('('); }
-")"                   { return(')'); }
-"<"                   { return('<'); }
-">"                   { return('>'); }
-"{"                   { return('{'); }
-"}"                   { return('}'); }
-"["                   { return('['); }
-"]"                   { return(']'); }
-":"                   { return(':'); }
-";"                   { return(';'); }
-","                   { return(','); }
-"."                   { return('.'); }
-"="                   { return('='); }
-"+"                   { return('+'); }
-"-"                   { return('-'); }
-"*"                   { return('*'); }
-"/"                   { return('/'); }
-"%"                   { return('%'); }
-"&"                   { return('&'); }
-"|"                   { return('|'); }
-"^"                   { return('^'); }
-"<<"                  { return(yy::parser::token::LSHIFT); }
-">>"                  { return(yy::parser::token::RSHIFT); }
-"&&"                  { return(yy::parser::token::LOGICAL_AND); }
-"||"                  { return(yy::parser::token::LOGICAL_OR);  }
-"!"                   { return('!'); }
-"~"                   { return('~'); }
-"<="                  { return(yy::parser::token::LEQ); }
-">="                  { return(yy::parser::token::GEQ); }
-"=="                  { return(yy::parser::token::EQUALITY); }
-"!="                  { return(yy::parser::token::NEQ); }
+;                     { return ';'; }
+\{                    { return '{'; }
+\}                    { return '}'; }
+=                     { return '='; }
+,                     { return ','; }
+\.                    { return '.'; }
+\(                    { return '('; }
+\)                    { return ')'; }
+\[                    { return '['; }
+\]                    { return ']'; }
+\<                    { return '<'; }
+\>                    { return '>'; }
 
     /* annotations */
 @{identifier}         { yylval->token = new AidlToken(yytext + 1, extra_text);
@@ -126,9 +91,6 @@
 oneway                { yylval->token = new AidlToken("oneway", extra_text);
                         return yy::parser::token::ONEWAY;
                       }
-enum                  { yylval->token = new AidlToken("enum", extra_text);
-                        return yy::parser::token::ENUM;
-                      }
 
     /* scalars */
 {identifier}          { yylval->token = new AidlToken(yytext, extra_text);
diff --git a/aidl_language_y.yy b/aidl_language_y.yy
index c9df5e8..3b2c586 100644
--- a/aidl_language_y.yy
+++ b/aidl_language_y.yy
@@ -1,26 +1,8 @@
-/*
- * Copyright (C) 2016, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
 %{
 #include "aidl_language.h"
 #include "aidl_language_y.h"
 #include "logging.h"
-#include <android-base/parseint.h>
 #include <set>
-#include <map>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -65,16 +47,11 @@
     char character;
     std::string *str;
     AidlAnnotation* annotation;
-    AidlAnnotationParameter* param;
-    std::map<std::string, std::shared_ptr<AidlConstantValue>>* param_list;
     std::vector<AidlAnnotation>* annotation_list;
     AidlTypeSpecifier* type;
     AidlArgument* arg;
     AidlArgument::Direction direction;
-    AidlConstantValue* const_expr;
-    AidlEnumerator* enumerator;
-    std::vector<std::unique_ptr<AidlEnumerator>>* enumerators;
-    AidlEnumDeclaration* enum_decl;
+    AidlConstantValue* constant_value;
     std::vector<std::unique_ptr<AidlConstantValue>>* constant_value_list;
     std::vector<std::unique_ptr<AidlArgument>>* arg_list;
     AidlVariableDeclaration* variable;
@@ -89,24 +66,19 @@
     std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args;
 }
 
-%destructor { } <character>
-%destructor { } <direction>
-%destructor { delete ($$); } <*>
-
 %token<token> ANNOTATION "annotation"
 %token<token> C_STR "string literal"
 %token<token> IDENTIFIER "identifier"
 %token<token> INTERFACE "interface"
 %token<token> PARCELABLE "parcelable"
 %token<token> ONEWAY "oneway"
-%token<token> ENUM "enum"
 
 %token<character> CHARVALUE "char literal"
 %token<token> FLOATVALUE "float literal"
 %token<token> HEXVALUE "hex literal"
 %token<token> INTVALUE "int literal"
 
-%token '(' ')' ',' '=' '[' ']' '.' '{' '}' ';'
+%token '(' ')' ',' '=' '[' ']' '<' '>' '.' '{' '}' ';'
 %token CONST "const"
 %token UNKNOWN "unrecognized character"
 %token CPP_HEADER "cpp_header"
@@ -118,28 +90,6 @@
 %token TRUE_LITERAL "true"
 %token FALSE_LITERAL "false"
 
-/* Operator precedence and associativity, as per
- * http://en.cppreference.com/w/cpp/language/operator_precedence */
-/* Precedence level 13 - 14, LTR, logical operators*/
-%left LOGICAL_OR
-%left LOGICAL_AND
-/* Precedence level 10 - 12, LTR, bitwise operators*/
-%left '|'
-%left '^'
-%left '&'
-/* Precedence level 9, LTR */
-%left EQUALITY NEQ
-/* Precedence level 8, LTR */
-%left '<' '>' LEQ GEQ
-/* Precedence level 7, LTR */
-%left LSHIFT RSHIFT
-/* Precedence level 6, LTR */
-%left '+' '-'
-/* Precedence level 5, LTR */
-%left '*' '/' '%'
-/* Precedence level 3, RTL; but we have to use %left here */
-%right UNARY_PLUS UNARY_MINUS  '!' '~'
-
 %type<declaration> decl
 %type<variable_list> variable_decls
 %type<variable> variable_decl
@@ -149,22 +99,16 @@
 %type<parcelable> parcelable_decl
 %type<method> method_decl
 %type<constant> constant_decl
-%type<enumerator> enumerator
-%type<enumerators> enumerators enum_decl_body
-%type<enum_decl> enum_decl
-%type<param> parameter
-%type<param_list> parameter_list
-%type<param_list> parameter_non_empty_list
 %type<annotation> annotation
 %type<annotation_list>annotation_list
 %type<type> type
 %type<type> unannotated_type
-%type<arg_list> arg_list arg_non_empty_list
+%type<arg_list> arg_list
 %type<arg> arg
 %type<direction> direction
 %type<type_args> type_args
 %type<qname> qualified_name
-%type<const_expr> const_expr
+%type<constant_value> constant_value
 %type<constant_value_list> constant_value_list
 %type<constant_value_list> constant_value_non_empty_list
 
@@ -213,14 +157,10 @@
 
 decls
  : decl {
-    if ($1 != nullptr) {
-      ps->AddDefinedType(unique_ptr<AidlDefinedType>($1));
-    }
+    ps->AddDefinedType(unique_ptr<AidlDefinedType>($1));
   }
  | decls decl {
-    if ($2 != nullptr) {
-      ps->AddDefinedType(unique_ptr<AidlDefinedType>($2));
-    }
+    ps->AddDefinedType(unique_ptr<AidlDefinedType>($2));
   };
 
 decl
@@ -228,12 +168,12 @@
    {
     $$ = $2;
 
-    if ($1->size() > 0 && $$ != nullptr) {
+    if ($1->size() > 0) {
       // copy comments from annotation to decl
-      $$->SetComments($1->begin()->GetComments());
-      $$->Annotate(std::move(*$1));
+      $2->SetComments($1->begin()->GetComments());
     }
 
+    $$->Annotate(std::move(*$1));
     delete $1;
    }
  ;
@@ -243,31 +183,22 @@
   { $$ = $1; }
  | interface_decl
   { $$ = $1; }
- | enum_decl
-  { $$ = $1; }
  ;
 
 parcelable_decl
  : PARCELABLE qualified_name ';' {
     $$ = new AidlParcelable(loc(@2), $2, ps->Package(), $1->GetComments());
-    delete $1;
   }
  | PARCELABLE qualified_name CPP_HEADER C_STR ';' {
     $$ = new AidlParcelable(loc(@2), $2, ps->Package(), $1->GetComments(), $4->GetText());
-    delete $1;
-    delete $4;
   }
  | PARCELABLE identifier '{' variable_decls '}' {
     AidlQualifiedName* name = new AidlQualifiedName(loc(@2), $2->GetText(), $2->GetComments());
     $$ = new AidlStructuredParcelable(loc(@2), name, ps->Package(), $1->GetComments(), $4);
-    delete $1;
-    delete $2;
-    delete $4;
  }
  | PARCELABLE error ';' {
     ps->AddError();
-    $$ = nullptr;
-    delete $1;
+    $$ = NULL;
   };
 
 variable_decls
@@ -284,12 +215,9 @@
 variable_decl
  : type identifier ';' {
    $$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText());
-   delete $2;
  }
- | type identifier '=' const_expr ';' {
-   // TODO(b/123321528): Support enum type default assignments (TestEnum foo = TestEnum.FOO).
+ | type identifier '=' constant_value ';' {
    $$ = new AidlVariableDeclaration(loc(@2), $1, $2->GetText(),  $4);
-   delete $2;
  }
  | error ';' {
    ps->AddError();
@@ -312,6 +240,7 @@
     ps->AddError();
     $$ = nullptr;
     delete $1;
+    delete $2;
     delete $4;
   };
 
@@ -319,26 +248,20 @@
  :
   { $$ = new std::vector<std::unique_ptr<AidlMember>>(); }
  | interface_members method_decl
-  { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
+  { $1->push_back(std::unique_ptr<AidlMember>($2)); }
  | interface_members constant_decl
-  { $1->push_back(std::unique_ptr<AidlMember>($2)); $$ = $1; }
+  { $1->push_back(std::unique_ptr<AidlMember>($2)); }
  | interface_members error ';' {
     ps->AddError();
     $$ = $1;
   };
 
-const_expr
+constant_value
  : TRUE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), true); }
  | FALSE_LITERAL { $$ = AidlConstantValue::Boolean(loc(@1), false); }
  | CHARVALUE { $$ = AidlConstantValue::Character(loc(@1), $1); }
  | INTVALUE {
     $$ = AidlConstantValue::Integral(loc(@1), $1->GetText());
-    if ($$ == nullptr) {
-      std::cerr << "ERROR: Could not parse integer: "
-                << $1->GetText() << " at " << @1 << ".\n";
-      ps->AddError();
-      $$ = AidlConstantValue::Integral(loc(@1), "0");
-    }
     delete $1;
   }
  | FLOATVALUE {
@@ -346,13 +269,7 @@
     delete $1;
   }
  | HEXVALUE {
-    $$ = AidlConstantValue::Integral(loc(@1), $1->GetText());
-    if ($$ == nullptr) {
-      std::cerr << "ERROR: Could not parse hexvalue: "
-                << $1->GetText() << " at " << @1 << ".\n";
-      ps->AddError();
-      $$ = AidlConstantValue::Integral(loc(@1), "0");
-    }
+    $$ = AidlConstantValue::Hex(loc(@1), $1->GetText());
     delete $1;
   }
  | C_STR {
@@ -360,85 +277,9 @@
     delete $1;
   }
  | '{' constant_value_list '}' {
-    $$ = AidlConstantValue::Array(loc(@1), std::unique_ptr<vector<unique_ptr<AidlConstantValue>>>($2));
+    $$ = AidlConstantValue::Array(loc(@1), $2);
+    delete $2;
   }
- | const_expr LOGICAL_OR const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "||", std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr LOGICAL_AND const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&&", std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '|' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "|" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '^' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "^" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '&' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "&" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr EQUALITY const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "==", std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr NEQ const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "!=", std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '<' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '>' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr LEQ const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<=", std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr GEQ const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">=", std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr LSHIFT const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "<<", std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr RSHIFT const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), ">>", std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '+' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "+" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '-' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "-" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '*' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "*" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '/' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "/" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | const_expr '%' const_expr {
-    $$ = new AidlBinaryConstExpression(loc(@1), std::unique_ptr<AidlConstantValue>($1), "%" , std::unique_ptr<AidlConstantValue>($3));
-  }
- | '+' const_expr %prec UNARY_PLUS  {
-    $$ = new AidlUnaryConstExpression(loc(@1), "+", std::unique_ptr<AidlConstantValue>($2));
-  }
- | '-' const_expr %prec UNARY_MINUS {
-    $$ = new AidlUnaryConstExpression(loc(@1), "-", std::unique_ptr<AidlConstantValue>($2));
-  }
- | '!' const_expr {
-    $$ = new AidlUnaryConstExpression(loc(@1), "!", std::unique_ptr<AidlConstantValue>($2));
-  }
- | '~' const_expr {
-    $$ = new AidlUnaryConstExpression(loc(@1), "~", std::unique_ptr<AidlConstantValue>($2));
-  }
- | '(' const_expr ')'
-  {
-    $$ = $2;
-  }
- | '(' error ')'
-   {
-     std::cerr << "ERROR: invalid const expression within parenthesis at " << @1 << ".\n";
-     ps->AddError();
-     // to avoid segfaults
-     $$ = AidlConstantValue::Integral(loc(@1), "0");
-   }
  ;
 
 constant_value_list
@@ -451,112 +292,54 @@
  ;
 
 constant_value_non_empty_list
- : const_expr {
+ : constant_value {
     $$ = new std::vector<std::unique_ptr<AidlConstantValue>>;
     $$->push_back(std::unique_ptr<AidlConstantValue>($1));
  }
- | constant_value_non_empty_list ',' const_expr {
+ | constant_value_non_empty_list ',' constant_value {
     $$ = $1;
     $$->push_back(std::unique_ptr<AidlConstantValue>($3));
  }
  ;
 
 constant_decl
- : CONST type identifier '=' const_expr ';' {
+ : CONST type identifier '=' constant_value ';' {
     $$ = new AidlConstantDeclaration(loc(@3), $2, $3->GetText(), $5);
     delete $3;
    }
  ;
 
-enumerator
- : identifier '=' const_expr {
-    $$ = new AidlEnumerator(loc(@1), $1->GetText(), $3, $1->GetComments());
-    delete $1;
-   }
- | identifier {
-    $$ = new AidlEnumerator(loc(@1), $1->GetText(), nullptr, $1->GetComments());
-    delete $1;
-   }
- ;
-
-enumerators
- : enumerator {
-    $$ = new std::vector<std::unique_ptr<AidlEnumerator>>();
-    $$->push_back(std::unique_ptr<AidlEnumerator>($1));
-   }
- | enumerators ',' enumerator {
-    $1->push_back(std::unique_ptr<AidlEnumerator>($3));
-    $$ = $1;
-   }
- ;
-
-enum_decl_body
- : '{' enumerators '}' { $$ = $2; }
- | '{' enumerators ',' '}' { $$ = $2; }
- ;
-
-enum_decl
- : ENUM identifier enum_decl_body {
-    $$ = new AidlEnumDeclaration(loc(@2), $2->GetText(), $3, ps->Package(), $1->GetComments());
-    delete $1;
-    delete $2;
-    delete $3;
-   }
- ;
-
 method_decl
  : type identifier '(' arg_list ')' ';' {
     $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments());
     delete $2;
   }
- | annotation_list ONEWAY type identifier '(' arg_list ')' ';' {
-    const std::string& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
-    $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, comments);
-    $3->Annotate(std::move(*$1));
+ | ONEWAY type identifier '(' arg_list ')' ';' {
+    $$ = new AidlMethod(loc(@3), true, $2, $3->GetText(), $5, $1->GetComments());
     delete $1;
-    delete $2;
-    delete $4;
+    delete $3;
   }
  | type identifier '(' arg_list ')' '=' INTVALUE ';' {
-    int32_t serial;
-    if (!android::base::ParseInt($7->GetText(), &serial)) {
-        AIDL_ERROR(loc(@7)) << "Could not parse int value: " << $7->GetText();
-        ps->AddError();
-    }
-    $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments(), serial);
+    $$ = new AidlMethod(loc(@2), false, $1, $2->GetText(), $4, $1->GetComments(), std::stoi($7->GetText()));
     delete $2;
-    delete $7;
   }
- | annotation_list ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
-    const std::string& comments = ($1->size() > 0) ? $1->begin()->GetComments() : $2->GetComments();
-    int32_t serial;
-    if (!android::base::ParseInt($9->GetText(), &serial)) {
-        AIDL_ERROR(loc(@9)) << "Could not parse int value: " << $9->GetText();
-        ps->AddError();
-    }
-    $$ = new AidlMethod(loc(@4), true, $3, $4->GetText(), $6, comments, serial);
-    $3->Annotate(std::move(*$1));
+ | ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
+    $$ = new AidlMethod(loc(@3), true, $2, $3->GetText(), $5, $1->GetComments(), std::stoi($8->GetText()));
     delete $1;
-    delete $2;
-    delete $4;
-    delete $9;
-  };
-
-arg_non_empty_list
- : arg {
-    $$ = new std::vector<std::unique_ptr<AidlArgument>>();
-    $$->push_back(std::unique_ptr<AidlArgument>($1));
-  }
- | arg_non_empty_list ',' arg {
-    $$ = $1;
-    $$->push_back(std::unique_ptr<AidlArgument>($3));
+    delete $3;
   };
 
 arg_list
- : /*empty*/
-   { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); }
- | arg_non_empty_list { $$ = $1; }
- ;
+ :
+  { $$ = new std::vector<std::unique_ptr<AidlArgument>>(); }
+ | arg {
+    $$ = new std::vector<std::unique_ptr<AidlArgument>>();
+    $$->push_back(std::unique_ptr<AidlArgument>($1));
+  }
+ | arg_list ',' arg {
+    $$ = $1;
+    $$->push_back(std::unique_ptr<AidlArgument>($3));
+  };
 
 arg
  : direction type identifier {
@@ -567,7 +350,9 @@
     $$ = new AidlArgument(loc(@2), $1, $2->GetText());
     delete $2;
   }
- ;
+ | error {
+    ps->AddError();
+  };
 
 unannotated_type
  : qualified_name {
@@ -604,7 +389,6 @@
   }
  | type_args ',' unannotated_type {
     $1->emplace_back($3);
-    $$ = $1;
   };
 
 annotation_list
@@ -616,60 +400,17 @@
       $1->emplace_back(std::move(*$2));
       delete $2;
     }
-    $$ = $1;
-  };
-
-parameter
-  : identifier '=' const_expr {
-    $$ = new AidlAnnotationParameter{$1->GetText(), std::unique_ptr<AidlConstantValue>($3)};
-    delete $1;
-  };
-
-parameter_list
-  : /*empty*/{
-    $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>();
-  }
-  | parameter_non_empty_list  {
-    $$ = $1;
-  };
-
-parameter_non_empty_list
-  : parameter {
-    $$ = new std::map<std::string, std::shared_ptr<AidlConstantValue>>();
-    $$->emplace(std::move($1->name), $1->value.release());
-    delete $1;
-  }
-  | parameter_non_empty_list ',' parameter {
-    $$ = $1;
-    if ($$->find($3->name) != $$->end()) {
-      AIDL_ERROR(loc(@3)) << "Trying to redefine parameter " << $3->name << ".";
-      ps->AddError();
-    }
-    $$->emplace(std::move($3->name), std::move($3->value));
-    delete $3;
   };
 
 annotation
  : ANNOTATION
   {
-    $$ = AidlAnnotation::Parse(loc(@1), $1->GetText(), nullptr);
-    if ($$) {
-      $$->SetComments($1->GetComments());
-    } else {
+    $$ = AidlAnnotation::Parse(loc(@1), $1->GetText());
+    if ($$ == nullptr) {
       ps->AddError();
     }
-    delete $1;
+    $$->SetComments($1->GetComments());
   };
- | ANNOTATION '(' parameter_list ')' {
-    $$ = AidlAnnotation::Parse(loc(@1), $1->GetText(), $3);
-    if ($$) {
-      $$->SetComments($1->GetComments());
-    } else {
-      ps->AddError();
-    }
-    delete $1;
-    delete $3;
- }
 
 direction
  : IN
diff --git a/aidl_to_cpp.cpp b/aidl_to_cpp.cpp
index f5fa3f8..f335475 100644
--- a/aidl_to_cpp.cpp
+++ b/aidl_to_cpp.cpp
@@ -18,182 +18,17 @@
 #include "aidl_language.h"
 #include "logging.h"
 
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
 #include <functional>
 #include <unordered_map>
 
-using android::base::Join;
-using android::base::Split;
-using android::base::StringPrintf;
 using std::ostringstream;
 
 namespace android {
 namespace aidl {
 namespace cpp {
 
-namespace {
-std::string RawParcelMethod(const AidlTypeSpecifier& raw_type, const AidlTypenames& typenames,
-                            bool readMethod) {
-  static map<string, string> kBuiltin = {
-      {"byte", "Byte"},
-      {"boolean", "Bool"},
-      {"char", "Char"},
-      {"double", "Double"},
-      {"FileDescriptor", "UniqueFileDescriptor"},
-      {"float", "Float"},
-      {"IBinder", "StrongBinder"},
-      {"int", "Int32"},
-      {"long", "Int64"},
-      {"ParcelFileDescriptor", "Parcelable"},
-      {"String", "String16"},
-  };
-
-  static map<string, string> kBuiltinVector = {
-      {"FileDescriptor", "UniqueFileDescriptorVector"},
-      {"double", "DoubleVector"},
-      {"char", "CharVector"},
-      {"boolean", "BoolVector"},
-      {"byte", "ByteVector"},
-      {"float", "FloatVector"},
-      {"IBinder", "StrongBinderVector"},
-      {"String", "String16Vector"},
-      {"int", "Int32Vector"},
-      {"long", "Int64Vector"},
-      {"ParcelFileDescriptor", "ParcelableVector"},
-  };
-
-  const bool nullable = raw_type.IsNullable();
-  const bool isVector =
-      raw_type.IsArray() || (raw_type.IsGeneric() && raw_type.GetName() == "List");
-  const bool utf8 = raw_type.IsUtf8InCpp();
-  const auto& type = raw_type.IsGeneric() ? *raw_type.GetTypeParameters().at(0) : raw_type;
-  const string& aidl_name = type.GetName();
-
-  if (auto enum_decl = typenames.GetEnumDeclaration(raw_type); enum_decl != nullptr) {
-    if (isVector) {
-      return "EnumVector";
-    } else {
-      return RawParcelMethod(enum_decl->GetBackingType(), typenames, readMethod);
-    }
-  }
-
-  if (isVector) {
-    if (kBuiltinVector.find(aidl_name) != kBuiltinVector.end()) {
-      CHECK(AidlTypenames::IsBuiltinTypename(aidl_name));
-      if (utf8) {
-        CHECK(aidl_name == "String");
-        return readMethod ? "Utf8VectorFromUtf16Vector" : "Utf8VectorAsUtf16Vector";
-      }
-      return kBuiltinVector[aidl_name];
-    }
-  } else {
-    if (kBuiltin.find(aidl_name) != kBuiltin.end()) {
-      CHECK(AidlTypenames::IsBuiltinTypename(aidl_name));
-      if (aidl_name == "IBinder" && nullable && readMethod) {
-        return "NullableStrongBinder";
-      }
-      if (aidl_name == "ParcelFileDescriptor" && nullable && !readMethod) {
-        return "NullableParcelable";
-      }
-      if (utf8) {
-        CHECK(aidl_name == "String");
-        return readMethod ? "Utf8FromUtf16" : "Utf8AsUtf16";
-      }
-      return kBuiltin[aidl_name];
-    }
-  }
-  CHECK(!AidlTypenames::IsBuiltinTypename(aidl_name));
-  auto definedType = typenames.TryGetDefinedType(type.GetName());
-  if (definedType != nullptr && definedType->AsInterface() != nullptr) {
-    if (isVector) {
-      return "StrongBinderVector";
-    }
-    if (nullable && readMethod) {
-      return "NullableStrongBinder";
-    }
-    return "StrongBinder";
-  }
-
-  // The type must be either primitive or interface or parcelable,
-  // so it cannot be nullptr.
-  CHECK(definedType != nullptr) << type.GetName() << " is not found.";
-
-  // Parcelable
-  if (isVector) {
-    return "ParcelableVector";
-  }
-  if (nullable && !readMethod) {
-    return "NullableParcelable";
-  }
-  return "Parcelable";
-}
-
-std::string GetRawCppName(const AidlTypeSpecifier& type) {
-  return "::" + Join(type.GetSplitName(), "::");
-}
-
-std::string WrapIfNullable(const std::string type_str, const AidlTypeSpecifier& raw_type,
-                           const AidlTypenames& typenames) {
-  const auto& type = raw_type.IsGeneric() ? (*raw_type.GetTypeParameters().at(0)) : raw_type;
-
-  if (raw_type.IsNullable() && !AidlTypenames::IsPrimitiveTypename(type.GetName()) &&
-      type.GetName() != "IBinder" && typenames.GetEnumDeclaration(type) == nullptr) {
-    return "::std::unique_ptr<" + type_str + ">";
-  }
-  return type_str;
-}
-
-std::string GetCppName(const AidlTypeSpecifier& raw_type, const AidlTypenames& typenames) {
-  // map from AIDL built-in type name to the corresponding Cpp type name
-  static map<string, string> m = {
-      {"boolean", "bool"},
-      {"byte", "int8_t"},
-      {"char", "char16_t"},
-      {"double", "double"},
-      {"FileDescriptor", "::android::base::unique_fd"},
-      {"float", "float"},
-      {"IBinder", "::android::sp<::android::IBinder>"},
-      {"int", "int32_t"},
-      {"long", "int64_t"},
-      {"ParcelFileDescriptor", "::android::os::ParcelFileDescriptor"},
-      {"String", "::android::String16"},
-      {"void", "void"},
-  };
-
-  CHECK(!raw_type.IsGeneric() ||
-        (raw_type.GetName() == "List" && raw_type.GetTypeParameters().size() == 1));
-  const auto& type = raw_type.IsGeneric() ? (*raw_type.GetTypeParameters().at(0)) : raw_type;
-  const string& aidl_name = type.GetName();
-  if (m.find(aidl_name) != m.end()) {
-    CHECK(AidlTypenames::IsBuiltinTypename(aidl_name));
-    if (aidl_name == "byte" && type.IsArray()) {
-      return "uint8_t";
-    } else if (raw_type.IsUtf8InCpp()) {
-      CHECK(aidl_name == "String");
-      return WrapIfNullable("::std::string", raw_type, typenames);
-    }
-    return WrapIfNullable(m[aidl_name], raw_type, typenames);
-  }
-  auto definedType = typenames.TryGetDefinedType(type.GetName());
-  if (definedType != nullptr && definedType->AsInterface() != nullptr) {
-    return "::android::sp<" + GetRawCppName(type) + ">";
-  }
-
-  return WrapIfNullable(GetRawCppName(type), raw_type, typenames);
-}
-}  // namespace
 std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value) {
-  if (type.IsArray()) {
-    return raw_value;
-  }
-
-  if (type.GetName() == "long") {
-    return raw_value + "L";
-  }
-
-  if (type.GetName() == "String" && !type.IsUtf8InCpp()) {
+  if (type.GetName() == "String" && !type.IsArray() && !type.IsUtf8InCpp()) {
     return "::android::String16(" + raw_value + ")";
   }
 
@@ -207,113 +42,6 @@
   output << method.GetId() << " /* " << method.GetName() << " */";
   return output.str();
 }
-
-std::string CppNameOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
-  if (type.IsArray() || type.IsGeneric()) {
-    std::string cpp_name = GetCppName(type, typenames);
-    if (type.IsNullable()) {
-      return "::std::unique_ptr<::std::vector<" + cpp_name + ">>";
-    }
-    return "::std::vector<" + cpp_name + ">";
-  }
-  return GetCppName(type, typenames);
-}
-
-std::string ParcelReadMethodOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
-  return "read" + RawParcelMethod(type, typenames, true /* readMethod */);
-}
-
-std::string ParcelReadCastOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
-                             const std::string& variable_name) {
-  if (auto enum_decl = typenames.GetEnumDeclaration(type);
-      enum_decl != nullptr && !type.IsArray()) {
-    return StringPrintf("reinterpret_cast<%s *>(%s)",
-                        CppNameOf(enum_decl->GetBackingType(), typenames).c_str(),
-                        variable_name.c_str());
-  }
-
-  return variable_name;
-}
-
-std::string ParcelWriteMethodOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
-  return "write" + RawParcelMethod(type, typenames, false /* readMethod */);
-}
-
-std::string ParcelWriteCastOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
-                              const std::string& variable_name) {
-  if (auto enum_decl = typenames.GetEnumDeclaration(type);
-      enum_decl != nullptr && !type.IsArray()) {
-    return StringPrintf("static_cast<%s>(%s)",
-                        CppNameOf(enum_decl->GetBackingType(), typenames).c_str(),
-                        variable_name.c_str());
-  }
-
-  if (typenames.GetInterface(type) != nullptr) {
-    return GetRawCppName(type) + "::asBinder(" + variable_name + ")";
-  }
-
-  return variable_name;
-}
-
-void AddHeaders(const AidlTypeSpecifier& raw_type, const AidlTypenames& typenames,
-                std::set<std::string>& headers) {
-  bool isVector = raw_type.IsArray() || raw_type.IsGeneric();
-  bool isNullable = raw_type.IsNullable();
-  bool utf8 = raw_type.IsUtf8InCpp();
-
-  CHECK(!raw_type.IsGeneric() ||
-        (raw_type.GetName() == "List" && raw_type.GetTypeParameters().size() == 1));
-  const auto& type = raw_type.IsGeneric() ? *raw_type.GetTypeParameters().at(0) : raw_type;
-  auto definedType = typenames.TryGetDefinedType(type.GetName());
-
-  if (isVector) {
-    headers.insert("vector");
-  }
-  if (isNullable) {
-    if (type.GetName() != "IBinder") {
-      headers.insert("memory");
-    }
-  }
-  if (type.GetName() == "String") {
-    headers.insert(utf8 ? "string" : "utils/String16.h");
-  }
-  if (type.GetName() == "IBinder") {
-    headers.insert("binder/IBinder.h");
-  }
-  if (type.GetName() == "FileDescriptor") {
-    headers.insert("android-base/unique_fd.h");
-  }
-  if (type.GetName() == "ParcelFileDescriptor") {
-    headers.insert("binder/ParcelFileDescriptor.h");
-  }
-
-  static const std::set<string> need_cstdint{"byte", "int", "long"};
-  if (need_cstdint.find(type.GetName()) != need_cstdint.end()) {
-    headers.insert("cstdint");
-  }
-
-  if (definedType == nullptr) {
-    return;
-  }
-  if (definedType->AsInterface() != nullptr || definedType->AsStructuredParcelable() != nullptr ||
-      definedType->AsEnumDeclaration() != nullptr) {
-    AddHeaders(*definedType, headers);
-  } else if (definedType->AsParcelable() != nullptr) {
-    const std::string cpp_header = definedType->AsParcelable()->GetCppHeader();
-    AIDL_FATAL_IF(cpp_header.empty(), definedType->AsParcelable())
-        << "Parcelable " << definedType->AsParcelable()->GetCanonicalName()
-        << " has no C++ header defined.";
-    headers.insert(cpp_header);
-  }
-}
-
-void AddHeaders(const AidlDefinedType& definedType, std::set<std::string>& headers) {
-  vector<string> name = definedType.GetSplitPackage();
-  name.push_back(definedType.GetName());
-  const std::string cpp_header = Join(name, '/') + ".h";
-  headers.insert(cpp_header);
-}
-
 }  // namespace cpp
 }  // namespace aidl
 }  // namespace android
diff --git a/aidl_to_cpp.h b/aidl_to_cpp.h
index 3bf608c..5c936c9 100644
--- a/aidl_to_cpp.h
+++ b/aidl_to_cpp.h
@@ -36,31 +36,6 @@
 };
 
 std::string GetTransactionIdFor(const AidlMethod& method);
-
-std::string CppNameOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
-
-// Returns the name of the Parcel method suitable for reading data of the
-// given type.
-std::string ParcelReadMethodOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
-
-// Returns the potentially-cast representation of the provided variable name,
-// suitable for being passed to a method from ParcelReadMethodOf.
-std::string ParcelReadCastOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
-                             const std::string& variable_name);
-
-// Returns the name of the Parcel method suitable for writing data of the
-// given type.
-std::string ParcelWriteMethodOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
-
-// Returns the potentially-cast representation of the provided variable name,
-// suitable for being passed to a method from ParcelWriteMethodOf.
-std::string ParcelWriteCastOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
-                              const std::string& variable_name);
-
-void AddHeaders(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
-                std::set<std::string>& headers);
-
-void AddHeaders(const AidlDefinedType& parcelable, std::set<std::string>& headers);
 }  // namespace cpp
 }  // namespace aidl
 }  // namespace android
diff --git a/aidl_to_java.cpp b/aidl_to_java.cpp
index ec7909d..d8a6368 100644
--- a/aidl_to_java.cpp
+++ b/aidl_to_java.cpp
@@ -21,6 +21,7 @@
 
 #include <android-base/strings.h>
 
+#include <cassert>
 #include <functional>
 #include <iostream>
 #include <map>
@@ -39,35 +40,15 @@
 using std::string;
 using std::vector;
 
-std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value) {
-  if (type.GetName() == "long" && !type.IsArray()) {
-    return raw_value + "L";
-  }
-
+std::string ConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
+                                   const std::string& raw_value) {
+  // no difference
   return raw_value;
 };
 
-const string& JavaNameOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames,
-                         bool instantiable = false) {
+const string& JavaNameOf(const AidlTypeSpecifier& aidl) {
   CHECK(aidl.IsResolved()) << aidl.ToString();
 
-  if (instantiable) {
-    // An instantiable type is used in only out type(not even inout type),
-    // And instantiable type has to be either the type in List, Map, ParcelFileDescriptor or
-    // user-defined type.
-
-    static map<string, string> instantiable_m = {
-        {"List", "java.util.ArrayList"},
-        {"Map", "java.util.HashMap"},
-        {"ParcelFileDescriptor", "android.os.ParcelFileDescriptor"},
-    };
-    const string& aidl_name = aidl.GetName();
-
-    if (instantiable_m.find(aidl_name) != instantiable_m.end()) {
-      return instantiable_m[aidl_name];
-    }
-  }
-
   // map from AIDL built-in type name to the corresponding Java type name
   static map<string, string> m = {
       {"void", "void"},
@@ -86,17 +67,6 @@
       {"CharSequence", "java.lang.CharSequence"},
       {"ParcelFileDescriptor", "android.os.ParcelFileDescriptor"},
   };
-
-  // Enums in Java are represented by their backing type when
-  // referenced in parcelables, methods, etc.
-  if (const AidlEnumDeclaration* enum_decl = typenames.GetEnumDeclaration(aidl);
-      enum_decl != nullptr) {
-    const string& backing_type_name = enum_decl->GetBackingType().GetName();
-    CHECK(m.find(backing_type_name) != m.end());
-    CHECK(AidlTypenames::IsBuiltinTypename(backing_type_name));
-    return m[backing_type_name];
-  }
-
   const string& aidl_name = aidl.GetName();
   if (m.find(aidl_name) != m.end()) {
     CHECK(AidlTypenames::IsBuiltinTypename(aidl_name));
@@ -107,59 +77,28 @@
   }
 }
 
-namespace {
-string JavaSignatureOfInternal(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames,
-                               bool instantiable, bool omit_array) {
-  string ret = JavaNameOf(aidl, typenames, instantiable);
+string JavaSignatureOf(const AidlTypeSpecifier& aidl) {
+  string ret = JavaNameOf(aidl);
   if (aidl.IsGeneric()) {
     vector<string> arg_names;
     for (const auto& ta : aidl.GetTypeParameters()) {
-      arg_names.emplace_back(JavaSignatureOfInternal(*ta, typenames, false, false));
+      arg_names.emplace_back(JavaSignatureOf(*ta));
     }
     ret += "<" + Join(arg_names, ",") + ">";
   }
-  if (aidl.IsArray() && !omit_array) {
+  if (aidl.IsArray()) {
     ret += "[]";
   }
   return ret;
 }
 
-// Returns the name of the backing type for the specified type. Note: this
-// returns type names as used in AIDL, not a Java signature.
-// For enums, this is the enum's backing type.
-// For all other types, this is the type itself.
-string AidlBackingTypeName(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
-  string type_name;
-  if (const AidlEnumDeclaration* enum_decl = typenames.GetEnumDeclaration(type);
-      enum_decl != nullptr) {
-    type_name = enum_decl->GetBackingType().GetName();
-  } else {
-    type_name = type.GetName();
-  }
-  if (type.IsArray()) {
-    type_name += "[]";
-  }
-  return type_name;
-}
-
-}  // namespace
-
-string JavaSignatureOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames) {
-  return JavaSignatureOfInternal(aidl, typenames, false, false);
-}
-
-string InstantiableJavaSignatureOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames) {
-  return JavaSignatureOfInternal(aidl, typenames, true, true);
-}
-
-string DefaultJavaValueOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames) {
+string DefaultJavaValueOf(const AidlTypeSpecifier& aidl) {
   static map<string, string> m = {
       {"boolean", "false"}, {"byte", "0"},     {"char", R"('\u0000')"}, {"int", "0"},
       {"long", "0L"},       {"float", "0.0f"}, {"double", "0.0d"},
   };
-
-  const string name = AidlBackingTypeName(aidl, typenames);
-  CHECK(name != "void");
+  const string& name = aidl.GetName();
+  assert(name != "void");
 
   if (!aidl.IsArray() && m.find(name) != m.end()) {
     CHECK(AidlTypenames::IsBuiltinTypename(name));
@@ -370,7 +309,7 @@
          c.writer << "}\n";
        }},
   };
-  const string type_name = AidlBackingTypeName(c.type, c.typenames);
+  const string type_name = c.type.GetName() + (c.type.IsArray() ? "[]" : "");
   const auto found = method_map.find(type_name);
   if (found != method_map.end()) {
     found->second(c);
@@ -503,8 +442,7 @@
              CHECK(t != nullptr) << "Unknown type: " << contained_type << endl;
              if (t->AsParcelable() != nullptr) {
                c.writer << c.var << " = " << c.parcel << ".createTypedArrayList("
-                        << JavaNameOf(*(c.type.GetTypeParameters().at(0)), c.typenames)
-                        << ".CREATOR);\n";
+                        << JavaNameOf(*(c.type.GetTypeParameters().at(0))) << ".CREATOR);\n";
              }
            }
          } else {
@@ -570,7 +508,8 @@
          c.writer << "}\n";
        }},
   };
-  const auto found = method_map.find(AidlBackingTypeName(c.type, c.typenames));
+  const string type_name = c.type.GetName() + (c.type.IsArray() ? "[]" : "");
+  const auto found = method_map.find(type_name);
   if (found != method_map.end()) {
     found->second(c);
   } else {
@@ -583,8 +522,8 @@
       }
     } else if (t->AsParcelable() != nullptr || t->AsStructuredParcelable() != nullptr) {
       if (c.type.IsArray()) {
-        c.writer << c.var << " = " << c.parcel << ".createTypedArray("
-                 << JavaNameOf(c.type, c.typenames) << ".CREATOR);\n";
+        c.writer << c.var << " = " << c.parcel << ".createTypedArray(" << JavaNameOf(c.type)
+                 << ".CREATOR);\n";
       } else {
         // This is same as readTypedObject.
         // Keeping below code just not to break unit tests.
@@ -657,8 +596,7 @@
              CHECK(t != nullptr) << "Unknown type: " << contained_type << endl;
              if (t->AsParcelable() != nullptr) {
                c.writer << c.parcel << ".readTypedList(" << c.var << ", "
-                        << JavaNameOf(*(c.type.GetTypeParameters().at(0)), c.typenames)
-                        << ".CREATOR);\n";
+                        << JavaNameOf(*(c.type.GetTypeParameters().at(0))) << ".CREATOR);\n";
              }
            }
          } else {
@@ -693,7 +631,8 @@
                   << ", android.os.ParcelFileDescriptor.CREATOR);\n";
        }},
   };
-  const auto& found = method_map.find(AidlBackingTypeName(c.type, c.typenames));
+  const string type_name = c.type.GetName() + (c.type.IsArray() ? "[]" : "");
+  const auto& found = method_map.find(type_name);
   if (found != method_map.end()) {
     found->second(c);
   } else {
diff --git a/aidl_to_java.h b/aidl_to_java.h
index d33b25b..060b113 100644
--- a/aidl_to_java.h
+++ b/aidl_to_java.h
@@ -41,16 +41,16 @@
 
 std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value);
 
-// Returns the Java type signature of the AIDL type spec
-// This includes generic type parameters with array modifiers.
-string JavaSignatureOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames);
+// Returns the corresponding Java type name for an AIDL type spec
+// This excludes generic type parameters and array modifiers.
+const string& JavaNameOf(const AidlTypeSpecifier& aidl);
 
-// Returns the instantiable Jva type signature of the AIDL type spec
-// This includes generic type parameters, but excludes array modifiers.
-string InstantiableJavaSignatureOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames);
+// Returns the Java type signature of the AIDL type spec
+// This includes generic type parameters and array modifiers.
+string JavaSignatureOf(const AidlTypeSpecifier& aidl);
 
 // Returns the default Java value of the AIDL type spec
-string DefaultJavaValueOf(const AidlTypeSpecifier& aidl, const AidlTypenames& typenames);
+string DefaultJavaValueOf(const AidlTypeSpecifier& aidl);
 
 // This carries information that is required to generate code for
 // marshalling and unmarshalling a method argument or a parcelable field
diff --git a/aidl_to_ndk.cpp b/aidl_to_ndk.cpp
index 5379564..26d2465 100644
--- a/aidl_to_ndk.cpp
+++ b/aidl_to_ndk.cpp
@@ -68,14 +68,6 @@
   std::shared_ptr<Aspect> nullable_array;
 };
 
-std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value) {
-  if (type.GetName() == "long" && !type.IsArray()) {
-    return raw_value + "L";
-  }
-
-  return raw_value;
-};
-
 static std::function<void(const CodeGeneratorContext& c)> StandardRead(const std::string& name) {
   return [name](const CodeGeneratorContext& c) {
     c.writer << name << "(" << c.parcel << ", " << c.var << ")";
@@ -163,77 +155,7 @@
   };
 }
 
-TypeInfo EnumDeclarationTypeInfo(const AidlEnumDeclaration& enum_decl) {
-  const std::string clazz = NdkFullClassName(enum_decl, cpp::ClassNames::BASE);
-
-  static map<std::string, std::string> kAParcelTypeNameMap = {
-      {"byte", "Byte"},
-      {"int", "Int32"},
-      {"long", "Int64"},
-  };
-  auto aparcel_name_it = kAParcelTypeNameMap.find(enum_decl.GetBackingType().GetName());
-  CHECK(aparcel_name_it != kAParcelTypeNameMap.end());
-  const std::string aparcel_name = aparcel_name_it->second;
-
-  const std::string backing_type_name =
-      NdkNameOf(AidlTypenames(), enum_decl.GetBackingType(), StorageMode::STACK);
-
-  return TypeInfo{
-      .raw = TypeInfo::Aspect{
-          .cpp_name = clazz,
-          .value_is_cheap = true,
-          .read_func =
-              [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
-                c.writer << "AParcel_read" << aparcel_name << "(" << c.parcel
-                         << ", reinterpret_cast<" << backing_type_name << "*>(" << c.var << "))";
-              },
-          .write_func =
-              [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
-                c.writer << "AParcel_write" << aparcel_name << "(" << c.parcel << ", static_cast<"
-                         << backing_type_name << ">(" << c.var << "))";
-              },
-      },
-      .array = std::shared_ptr<TypeInfo::Aspect>(new TypeInfo::Aspect{
-          .cpp_name = "std::vector<" + clazz + ">",
-          .value_is_cheap = false,
-          .read_func =
-              [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
-                c.writer << "AParcel_read" << aparcel_name << "Array(" << c.parcel
-                         << ", static_cast<void*>(" << c.var
-                         << "), ndk::AParcel_stdVectorAllocator<" << backing_type_name << ">)";
-              },
-          .write_func =
-              [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
-                c.writer << "AParcel_write" << aparcel_name << "Array(" << c.parcel
-                         << ", reinterpret_cast<const " << backing_type_name << "*>(" << c.var
-                         << ".data()), " << c.var << ".size())";
-              },
-      }),
-      .nullable = nullptr,
-      .nullable_array = std::shared_ptr<TypeInfo::Aspect>(new TypeInfo::Aspect{
-          .cpp_name = "std::optional<std::vector<" + clazz + ">>",
-          .value_is_cheap = false,
-          .read_func =
-              [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
-                c.writer << "AParcel_read" << aparcel_name << "Array(" << c.parcel
-                         << ", static_cast<void*>(" << c.var
-                         << "), ndk::AParcel_nullableStdVectorAllocator<" << backing_type_name
-                         << ">)";
-              },
-          .write_func =
-              [aparcel_name, backing_type_name](const CodeGeneratorContext& c) {
-                // If the var exists, use writeArray with data() and size().
-                // Otherwise, use nullptr and -1.
-                c.writer << "AParcel_write" << aparcel_name << "Array(" << c.parcel << ", ("
-                         << c.var << " ? reinterpret_cast<const " << backing_type_name << "*>("
-                         << c.var << "->data()) : nullptr)"
-                         << ", (" << c.var << " ? " << c.var << "->size() : -1))";
-              },
-      }),
-  };
-}
-
-// map from AIDL built-in type name to the corresponding Ndk type info
+// map from AIDL built-in type name to the corresponding Ndk type name
 static map<std::string, TypeInfo> kNdkTypeInfoMap = {
     {"void", TypeInfo{{"void", true, nullptr, nullptr}, nullptr, nullptr, nullptr}},
     {"boolean", PrimitiveType("bool", "Bool")},
@@ -330,13 +252,10 @@
     const AidlDefinedType* type = types.TryGetDefinedType(aidl_name);
     AIDL_FATAL_IF(type == nullptr, aidl_name) << "Unrecognized type.";
 
-    if (const AidlInterface* intf = type->AsInterface(); intf != nullptr) {
-      info = InterfaceTypeInfo(*intf);
-    } else if (const AidlParcelable* parcelable = type->AsParcelable(); parcelable != nullptr) {
-      info = ParcelableTypeInfo(*parcelable);
-    } else if (const AidlEnumDeclaration* enum_decl = type->AsEnumDeclaration();
-               enum_decl != nullptr) {
-      info = EnumDeclarationTypeInfo(*enum_decl);
+    if (type->AsInterface() != nullptr) {
+      info = InterfaceTypeInfo(*type->AsInterface());
+    } else if (type->AsParcelable() != nullptr) {
+      info = ParcelableTypeInfo(*type->AsParcelable());
     } else {
       AIDL_FATAL(aidl_name) << "Unrecognized type";
     }
diff --git a/aidl_to_ndk.h b/aidl_to_ndk.h
index 1f7f490..50fb880 100644
--- a/aidl_to_ndk.h
+++ b/aidl_to_ndk.h
@@ -31,8 +31,6 @@
 std::string NdkHeaderFile(const AidlDefinedType& defined_type, cpp::ClassNames name,
                           bool use_os_sep = true);
 
-std::string ConstantValueDecorator(const AidlTypeSpecifier& type, const std::string& raw_value);
-
 // Returns ::aidl::some_package::some_sub_package::foo::IFoo/BpFoo/BnFoo
 std::string NdkFullClassName(const AidlDefinedType& type, cpp::ClassNames name);
 
diff --git a/aidl_typenames.cpp b/aidl_typenames.cpp
index 6f9b590..3b79aba 100644
--- a/aidl_typenames.cpp
+++ b/aidl_typenames.cpp
@@ -81,13 +81,6 @@
   return true;
 }
 
-bool AidlTypenames::IsIgnorableImport(const string& import) const {
-  static set<string> ignore_import = {"android.os.IInterface",   "android.os.IBinder",
-                                      "android.os.Parcelable",   "android.os.Parcel",
-                                      "android.content.Context", "java.lang.String"};
-  return ResolveTypename(import).second || ignore_import.find(import) != ignore_import.end();
-}
-
 bool AidlTypenames::AddDefinedType(unique_ptr<AidlDefinedType> type) {
   const string name = type->GetCanonicalName();
   if (defined_types_.find(name) != defined_types_.end()) {
@@ -169,7 +162,7 @@
 // Only T[], List, Map, ParcelFileDescriptor and Parcelable can be an out parameter.
 bool AidlTypenames::CanBeOutParameter(const AidlTypeSpecifier& type) const {
   const string& name = type.GetName();
-  if (IsBuiltinTypename(name) || GetEnumDeclaration(type)) {
+  if (IsBuiltinTypename(name)) {
     return type.IsArray() || type.GetName() == "List" || type.GetName() == "Map" ||
            type.GetName() == "ParcelFileDescriptor";
   }
@@ -178,24 +171,6 @@
   return t->AsParcelable() != nullptr;
 }
 
-const AidlEnumDeclaration* AidlTypenames::GetEnumDeclaration(const AidlTypeSpecifier& type) const {
-  if (auto defined_type = TryGetDefinedType(type.GetName()); defined_type != nullptr) {
-    if (auto enum_decl = defined_type->AsEnumDeclaration(); enum_decl != nullptr) {
-      return enum_decl;
-    }
-  }
-  return nullptr;
-}
-
-const AidlInterface* AidlTypenames::GetInterface(const AidlTypeSpecifier& type) const {
-  if (auto defined_type = TryGetDefinedType(type.GetName()); defined_type != nullptr) {
-    if (auto intf = defined_type->AsInterface(); intf != nullptr) {
-      return intf;
-    }
-  }
-  return nullptr;
-}
-
 void AidlTypenames::IterateTypes(const std::function<void(const AidlDefinedType&)>& body) const {
   for (const auto& kv : defined_types_) {
     body(*kv.second);
diff --git a/aidl_typenames.h b/aidl_typenames.h
index c2ea12e..74db49c 100644
--- a/aidl_typenames.h
+++ b/aidl_typenames.h
@@ -31,8 +31,6 @@
 using std::vector;
 
 class AidlDefinedType;
-class AidlEnumDeclaration;
-class AidlInterface;
 class AidlTypeSpecifier;
 
 namespace android {
@@ -60,13 +58,7 @@
   const AidlDefinedType* TryGetDefinedType(const string& type_name) const;
   pair<string, bool> ResolveTypename(const string& type_name) const;
   bool CanBeOutParameter(const AidlTypeSpecifier& type) const;
-  bool IsIgnorableImport(const string& import) const;
-  // Returns the AidlEnumDeclaration of the given type, or nullptr if the type
-  // is not an AidlEnumDeclaration;
-  const AidlEnumDeclaration* GetEnumDeclaration(const AidlTypeSpecifier& type) const;
-  // Returns the AidlInterface of the given type, or nullptr if the type
-  // is not an AidlInterface;
-  const AidlInterface* GetInterface(const AidlTypeSpecifier& type) const;
+
   // Iterates over all defined and then preprocessed types
   void IterateTypes(const std::function<void(const AidlDefinedType&)>& body) const;
 
diff --git a/aidl_unittest.cpp b/aidl_unittest.cpp
index 6e56514..7cf8172 100644
--- a/aidl_unittest.cpp
+++ b/aidl_unittest.cpp
@@ -26,19 +26,18 @@
 #include "aidl_apicheck.h"
 #include "aidl_language.h"
 #include "aidl_to_cpp.h"
-#include "aidl_to_java.h"
-#include "options.h"
 #include "tests/fake_io_delegate.h"
+#include "type_cpp.h"
+#include "type_java.h"
+#include "type_namespace.h"
 
-using android::aidl::internals::parse_preprocessed_file;
 using android::aidl::test::FakeIoDelegate;
 using android::base::StringPrintf;
 using std::set;
 using std::string;
 using std::unique_ptr;
 using std::vector;
-using testing::internal::CaptureStderr;
-using testing::internal::GetCapturedStderr;
+using android::aidl::internals::parse_preprocessed_file;
 
 namespace android {
 namespace aidl {
@@ -70,7 +69,7 @@
 p/Foo.aidl :
 )";
 
-const char kExpectedJavaParcelableOutputContests[] =
+const char kExepectedJavaParcelableOutputContests[] =
     R"(/*
  * This file is auto-generated.  DO NOT MODIFY.
  */
@@ -82,11 +81,9 @@
   @android.annotation.SystemApi
   public int x = 5;
 
-  @dalvik.annotation.compat.UnsupportedAppUsage(expectedSignature = "dummy", implicitMember = "dummy", maxTargetSdk = 28, publicAlternatives = "dummy", trackingBug = 42L)
+  @android.annotation.UnsupportedAppUsage
   @android.annotation.SystemApi
   public int y;
-
-  public android.os.ParcelFileDescriptor fd;
   public static final android.os.Parcelable.Creator<Rect> CREATOR = new android.os.Parcelable.Creator<Rect>() {
     @Override
     public Rect createFromParcel(android.os.Parcel _aidl_source) {
@@ -105,13 +102,6 @@
     _aidl_parcel.writeInt(0);
     _aidl_parcel.writeInt(x);
     _aidl_parcel.writeInt(y);
-    if ((fd!=null)) {
-      _aidl_parcel.writeInt(1);
-      fd.writeToParcel(_aidl_parcel, 0);
-    }
-    else {
-      _aidl_parcel.writeInt(0);
-    }
     int _aidl_end_pos = _aidl_parcel.dataPosition();
     _aidl_parcel.setDataPosition(_aidl_start_pos);
     _aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos);
@@ -127,13 +117,6 @@
       if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
       y = _aidl_parcel.readInt();
       if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
-      if ((0!=_aidl_parcel.readInt())) {
-        fd = android.os.ParcelFileDescriptor.CREATOR.createFromParcel(_aidl_parcel);
-      }
-      else {
-        fd = null;
-      }
-      if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;
     } finally {
       _aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size);
     }
@@ -150,29 +133,19 @@
 class AidlTest : public ::testing::Test {
  protected:
   void SetUp() override {
-    CaptureStderr();
+    java_types_.Init();
+    cpp_types_.Init();
   }
 
-  void TearDown() override {
-    auto actual_stderr = GetCapturedStderr();
-    std::cerr << actual_stderr << std::endl;
-
-    if (expected_stderr_.size() > 0) {
-      EXPECT_EQ(android::base::Join(expected_stderr_, ""), actual_stderr);
-    }
-  }
-
-  void AddExpectedStderr(string expected) { expected_stderr_.push_back(expected); }
-
-  AidlDefinedType* Parse(const string& path, const string& contents, AidlTypenames& typenames_,
-                         Options::Language lang, AidlError* error = nullptr,
+  AidlDefinedType* Parse(const string& path, const string& contents, TypeNamespace* types,
+                         AidlError* error = nullptr,
                          const vector<string> additional_arguments = {}) {
     io_delegate_.SetFileContents(path, contents);
     vector<string> args;
-    if (lang == Options::Language::CPP) {
-      args.emplace_back("aidl-cpp");
-    } else {
+    if (types == &java_types_) {
       args.emplace_back("aidl");
+    } else {
+      args.emplace_back("aidl-cpp");
     }
     for (const string& s : additional_arguments) {
       args.emplace_back(s);
@@ -189,7 +162,7 @@
     vector<string> imported_files;
     ImportResolver import_resolver{io_delegate_, path, import_paths_, {}};
     AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
-        path, options, io_delegate_, &typenames_, &defined_types, &imported_files);
+        path, options, io_delegate_, types, &defined_types, &imported_files);
 
     if (error != nullptr) {
       *error = actual_error;
@@ -207,22 +180,13 @@
   FakeIoDelegate io_delegate_;
   vector<string> preprocessed_files_;
   set<string> import_paths_;
-  vector<string> expected_stderr_;
-  AidlTypenames typenames_;
+  java::JavaTypeNamespace java_types_;
+  cpp::TypeNamespace cpp_types_;
 };
 
 TEST_F(AidlTest, AcceptMissingPackage) {
-  EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, Options::Language::JAVA));
-  typenames_.Reset();
-  EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", typenames_, Options::Language::CPP));
-}
-
-TEST_F(AidlTest, EndsInSingleLineComment) {
-  EXPECT_NE(nullptr,
-            Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, Options::Language::JAVA));
-  typenames_.Reset();
-  EXPECT_NE(nullptr,
-            Parse("IFoo.aidl", "interface IFoo { } // foo", typenames_, Options::Language::CPP));
+  EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &java_types_));
+  EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &cpp_types_));
 }
 
 TEST_F(AidlTest, RejectsArraysOfBinders) {
@@ -233,22 +197,8 @@
   string contents = "package foo;\n"
                     "import bar.IBar;\n"
                     "interface IFoo { void f(in IBar[] input); }";
-  EXPECT_EQ(nullptr, Parse(path, contents, typenames_, Options::Language::JAVA));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse(path, contents, typenames_, Options::Language::CPP));
-}
-
-TEST_F(AidlTest, SupportOnlyOutParameters) {
-  string interface_list = "package a; interface IBar { void f(out List bar); }";
-  string interface_ibinder = "package a; interface IBaz { void f(out IBinder bar); }";
-  // List without type isn't supported in cpp.
-  EXPECT_EQ(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_NE(nullptr, Parse("a/IBar.aidl", interface_list, typenames_, Options::Language::JAVA));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse("a/IBaz.aidl", interface_ibinder, typenames_, Options::Language::JAVA));
+  EXPECT_EQ(nullptr, Parse(path, contents, &java_types_));
+  EXPECT_EQ(nullptr, Parse(path, contents, &cpp_types_));
 }
 
 TEST_F(AidlTest, RejectsOnewayOutParameters) {
@@ -256,55 +206,43 @@
       "package a; oneway interface IFoo { void f(out int bar); }";
   string oneway_method =
       "package a; interface IBar { oneway void f(out int bar); }";
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, typenames_, Options::Language::JAVA));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, typenames_, Options::Language::JAVA));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &cpp_types_));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_interface, &java_types_));
+  EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &cpp_types_));
+  EXPECT_EQ(nullptr, Parse("a/IBar.aidl", oneway_method, &java_types_));
 }
 
 TEST_F(AidlTest, RejectsOnewayNonVoidReturn) {
   string oneway_method = "package a; interface IFoo { oneway int f(); }";
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::JAVA));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
 }
 
 TEST_F(AidlTest, RejectsNullablePrimitive) {
   string oneway_method = "package a; interface IFoo { @nullable int f(); }";
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::JAVA));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
 }
 
 TEST_F(AidlTest, RejectsDuplicatedArgumentNames) {
   string method = "package a; interface IFoo { void f(int a, int a); }";
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, Options::Language::JAVA));
-}
-
-TEST_F(AidlTest, RejectsDuplicatedAnnotationParams) {
-  string method = "package a; interface IFoo { @UnsupportedAppUsage(foo=1, foo=2)void f(); }";
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, typenames_, Options::Language::JAVA));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, &cpp_types_));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", method, &java_types_));
 }
 
 TEST_F(AidlTest, ParsesNullableAnnotation) {
   for (auto is_nullable: {true, false}) {
-    auto parse_result = Parse("a/IFoo.aidl",
-                              StringPrintf("package a; interface IFoo {%s String f(); }",
-                                           (is_nullable) ? "@nullable" : ""),
-                              typenames_, Options::Language::CPP);
+    auto parse_result = Parse(
+        "a/IFoo.aidl",
+        StringPrintf( "package a; interface IFoo {%s String f(); }",
+                     (is_nullable) ? "@nullable" : ""),
+        &cpp_types_);
     ASSERT_NE(nullptr, parse_result);
     const AidlInterface* interface = parse_result->AsInterface();
     ASSERT_NE(nullptr, interface);
     ASSERT_FALSE(interface->GetMethods().empty());
     EXPECT_EQ(interface->GetMethods()[0]->GetType().IsNullable(), is_nullable);
-    typenames_.Reset();
+    cpp_types_.typenames_.Reset();
   }
 }
 
@@ -312,121 +250,44 @@
   for (auto is_utf8: {true, false}) {
     auto parse_result = Parse(
         "a/IFoo.aidl",
-        StringPrintf("package a; interface IFoo {%s String f(); }", (is_utf8) ? "@utf8InCpp" : ""),
-        typenames_, Options::Language::CPP);
+        StringPrintf( "package a; interface IFoo {%s String f(); }",
+                     (is_utf8) ? "@utf8InCpp" : ""),
+        &cpp_types_);
     ASSERT_NE(nullptr, parse_result);
     const AidlInterface* interface = parse_result->AsInterface();
     ASSERT_NE(nullptr, interface);
     ASSERT_FALSE(interface->GetMethods().empty());
     EXPECT_EQ(interface->GetMethods()[0]->GetType().IsUtf8InCpp(), is_utf8);
-    typenames_.Reset();
+    cpp_types_.typenames_.Reset();
   }
 }
 
-TEST_F(AidlTest, VintfRequiresStructuredAndStability) {
-  AidlError error;
-  auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
-                            Options::Language::CPP, &error);
-  ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
-  ASSERT_EQ(nullptr, parse_result);
-}
-
-TEST_F(AidlTest, VintfRequiresStructured) {
-  AidlError error;
-  auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
-                            Options::Language::CPP, &error, {"--stability", "vintf"});
-  ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
-  ASSERT_EQ(nullptr, parse_result);
-}
-
-TEST_F(AidlTest, VintfRequiresSpecifiedStability) {
-  AidlError error;
-  auto parse_result = Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_,
-                            Options::Language::CPP, &error, {"--structured"});
-  ASSERT_EQ(AidlError::NOT_STRUCTURED, error);
-  ASSERT_EQ(nullptr, parse_result);
-}
-
-TEST_F(AidlTest, ParsesStabilityAnnotations) {
-  AidlError error;
-  auto parse_result =
-      Parse("IFoo.aidl", "@VintfStability interface IFoo {}", typenames_, Options::Language::CPP,
-            &error, {"--structured", "--stability", "vintf"});
-  ASSERT_EQ(AidlError::OK, error);
-  ASSERT_NE(nullptr, parse_result);
-  const AidlInterface* interface = parse_result->AsInterface();
-  ASSERT_NE(nullptr, interface);
-  ASSERT_TRUE(interface->IsVintfStability());
-  typenames_.Reset();
-}
-
-TEST_F(AidlTest, ParsesJavaOnlyStableParcelable) {
-  Options java_options = Options::From("aidl -o out --structured a/Foo.aidl");
-  Options cpp_options =
-      Options::From("aidl --lang=cpp --structured -o out -h out/include a/Foo.aidl");
-  io_delegate_.SetFileContents(
-      "a/Foo.aidl", StringPrintf("package a; @JavaOnlyStableParcelable parcelable Foo;"));
-
-  EXPECT_EQ(0, ::android::aidl::compile_aidl(java_options, io_delegate_));
-  AddExpectedStderr(
-      "ERROR: a/Foo.aidl:1.48-52: @JavaOnlyStableParcelable supports only Java target.\n");
-  EXPECT_NE(0, ::android::aidl::compile_aidl(cpp_options, io_delegate_));
-}
-
 TEST_F(AidlTest, AcceptsOneway) {
   string oneway_method = "package a; interface IFoo { oneway void f(int a); }";
   string oneway_interface =
       "package a; oneway interface IBar { void f(int a); }";
-  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::JAVA));
-  typenames_.Reset();
-  EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, typenames_, Options::Language::JAVA));
-}
-
-TEST_F(AidlTest, AcceptsAnnotatedOnewayMethod) {
-  string oneway_method = "package a; interface IFoo { @UnsupportedAppUsage oneway void f(int a); }";
-  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::CPP));
-  typenames_.Reset();
-  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, typenames_, Options::Language::JAVA));
-}
-
-TEST_F(AidlTest, WritesComments) {
-  string foo_interface =
-      "package a; /* foo */ interface IFoo {"
-      "  /* i */ int i();"
-      "  /* j */ @nullable String j();"
-      "  /* k */ @UnsupportedAppUsage oneway void k(int a); }";
-
-  auto parse_result = Parse("a/IFoo.aidl", foo_interface, typenames_, Options::Language::JAVA);
-  EXPECT_NE(nullptr, parse_result);
-  EXPECT_EQ("/* foo */", parse_result->GetComments());
-
-  const AidlInterface* interface = parse_result->AsInterface();
-  EXPECT_EQ("/* i */", interface->GetMethods()[0]->GetComments());
-  EXPECT_EQ("/* j */", interface->GetMethods()[1]->GetComments());
-  EXPECT_EQ("/* k */", interface->GetMethods()[2]->GetComments());
+  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &cpp_types_));
+  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", oneway_method, &java_types_));
+  EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &cpp_types_));
+  EXPECT_NE(nullptr, Parse("a/IBar.aidl", oneway_interface, &java_types_));
 }
 
 TEST_F(AidlTest, ParsesPreprocessedFile) {
   string simple_content = "parcelable a.Foo;\ninterface b.IBar;";
   io_delegate_.SetFileContents("path", simple_content);
-  EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").second);
-  EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
-  EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").second);
-  EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").second);
+  EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
+  EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_, java_types_.typenames_));
+  EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
+  EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
 }
 
 TEST_F(AidlTest, ParsesPreprocessedFileWithWhitespace) {
   string simple_content = "parcelable    a.Foo;\n  interface b.IBar  ;\t";
   io_delegate_.SetFileContents("path", simple_content);
-
-  EXPECT_FALSE(typenames_.ResolveTypename("a.Foo").second);
-  EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &typenames_));
-  EXPECT_TRUE(typenames_.ResolveTypename("a.Foo").second);
-  EXPECT_TRUE(typenames_.ResolveTypename("b.IBar").second);
+  EXPECT_FALSE(java_types_.HasTypeByCanonicalName("a.Foo"));
+  EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_, java_types_.typenames_));
+  EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
+  EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
 }
 
 TEST_F(AidlTest, PreferImportToPreprocessed) {
@@ -435,17 +296,18 @@
                                                 "interface IBar {}");
   preprocessed_files_.push_back("preprocessed");
   import_paths_.emplace("");
-  auto parse_result = Parse("p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
-                            typenames_, Options::Language::JAVA);
+  auto parse_result = Parse(
+      "p/IFoo.aidl", "package p; import one.IBar; interface IFoo {}",
+      &java_types_);
   EXPECT_NE(nullptr, parse_result);
-
   // We expect to know about both kinds of IBar
-  EXPECT_TRUE(typenames_.ResolveTypename("one.IBar").second);
-  EXPECT_TRUE(typenames_.ResolveTypename("another.IBar").second);
+  EXPECT_TRUE(java_types_.HasTypeByCanonicalName("one.IBar"));
+  EXPECT_TRUE(java_types_.HasTypeByCanonicalName("another.IBar"));
   // But if we request just "IBar" we should get our imported one.
   AidlTypeSpecifier ambiguous_type(AIDL_LOCATION_HERE, "IBar", false, nullptr, "");
-  ambiguous_type.Resolve(typenames_);
-  EXPECT_EQ("one.IBar", ambiguous_type.GetName());
+  const java::Type* type = java_types_.Find(ambiguous_type);
+  ASSERT_TRUE(type);
+  EXPECT_EQ("one.IBar", type->CanonicalName());
 }
 
 TEST_F(AidlTest, WritePreprocessedFile) {
@@ -469,20 +331,16 @@
 }
 
 TEST_F(AidlTest, JavaParcelableOutput) {
-  io_delegate_.SetFileContents(
-      "Rect.aidl",
-      "@SystemApi\n"
-      "parcelable Rect {\n"
-      "  // Comment\n"
-      "  @SystemApi\n"
-      "  int x=5;\n"
-      "  @SystemApi\n"
-      "  @UnsupportedAppUsage(maxTargetSdk = 28, trackingBug = 42, implicitMember = \"dummy\", "
-      "expectedSignature = \"dummy\", publicAlternatives = \"d\" \n + \"u\" + \n \"m\" \n + \"m\" "
-      "+ \"y\")\n"
-      "  int y;\n"
-      "  ParcelFileDescriptor fd;\n"
-      "}");
+  io_delegate_.SetFileContents("Rect.aidl",
+                               "@SystemApi\n"
+                               "parcelable Rect {\n"
+                               "  // Comment\n"
+                               "  @SystemApi\n"
+                               "  int x=5;\n"
+                               "  @SystemApi\n"
+                               "  @UnsupportedAppUsage\n"
+                               "  int y;\n"
+                               "}");
 
   vector<string> args{"aidl", "Rect.aidl"};
   Options options = Options::From(args);
@@ -490,16 +348,17 @@
 
   string output;
   EXPECT_TRUE(io_delegate_.GetWrittenContents("Rect.java", &output));
-  EXPECT_EQ(kExpectedJavaParcelableOutputContests, output);
+  EXPECT_EQ(kExepectedJavaParcelableOutputContests, output);
 }
 
 TEST_F(AidlTest, RequireOuterClass) {
   io_delegate_.SetFileContents("p/Outer.aidl",
                                "package p; parcelable Outer.Inner;");
   import_paths_.emplace("");
-  auto parse_result =
-      Parse("p/IFoo.aidl", "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
-            typenames_, Options::Language::JAVA);
+  auto parse_result = Parse(
+      "p/IFoo.aidl",
+      "package p; import p.Outer; interface IFoo { void f(in Inner c); }",
+      &java_types_);
   EXPECT_EQ(nullptr, parse_result);
 }
 
@@ -507,8 +366,10 @@
   io_delegate_.SetFileContents("preprocessed",
                                "parcelable p.Outer.Inner;");
   preprocessed_files_.push_back("preprocessed");
-  auto parse_result = Parse("p/IFoo.aidl", "package p; interface IFoo { void f(in Inner c); }",
-                            typenames_, Options::Language::JAVA);
+  auto parse_result = Parse(
+      "p/IFoo.aidl",
+      "package p; interface IFoo { void f(in Inner c); }",
+      &java_types_);
   // TODO(wiley): This should actually return nullptr because we require
   //              the outer class name.  However, for legacy reasons,
   //              this behavior must be maintained.  b/17415692
@@ -528,7 +389,7 @@
 
   io_delegate_.SetFileContents("p/IBar.aidl", "package p; parcelable Foo; interface IBar{}");
 
-  // With '-b' option, a parcelable and an interface should fail.
+  // Regardless of '-b', a parcelable and an interface should fail.
   Options options3 = Options::From("aidl p/IBar.aidl");
   EXPECT_EQ(0, ::android::aidl::compile_aidl(options3, io_delegate_));
   Options options4 = Options::From("aidl -b p/IBar.aidl");
@@ -542,35 +403,37 @@
   auto parse_result =
       Parse("p/IFoo.aidl",
             "package p; import o.WhoKnowsWhat; interface IFoo { void f(in WhoKnowsWhat thisIs); }",
-            typenames_, Options::Language::JAVA, &reported_error, {"--structured"});
+            &java_types_, &reported_error, {"--structured"});
   EXPECT_EQ(nullptr, parse_result);
   EXPECT_EQ(AidlError::NOT_STRUCTURED, reported_error);
 }
 
 TEST_F(AidlTest, FailOnDuplicateConstantNames) {
   AidlError reported_error;
-  EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
-                           R"(package p;
+  EXPECT_EQ(nullptr,
+            Parse("p/IFoo.aidl",
+                   R"(package p;
                       interface IFoo {
                         const String DUPLICATED = "d";
                         const int DUPLICATED = 1;
                       }
                    )",
-                           typenames_, Options::Language::CPP, &reported_error));
+                   &cpp_types_,
+                   &reported_error));
   EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
 }
 
 TEST_F(AidlTest, FailOnManyDefinedTypes) {
   AidlError reported_error;
-  AddExpectedStderr("ERROR: p/IFoo.aidl: You must declare only one type per a file.\n");
   EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
                            R"(package p;
                       interface IFoo {}
+                      parcelable Bar;
                       parcelable IBar {}
                       parcelable StructuredParcelable {}
                       interface IBaz {}
-                  )",
-                           typenames_, Options::Language::CPP, &reported_error));
+                   )",
+                           &cpp_types_, &reported_error));
   // Parse success is important for clear error handling even if the cases aren't
   // actually supported in code generation.
   EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
@@ -578,58 +441,61 @@
 
 TEST_F(AidlTest, FailOnNoDefinedTypes) {
   AidlError reported_error;
-  EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", typenames_, Options::Language::CPP,
-                           &reported_error));
+  EXPECT_EQ(nullptr, Parse("p/IFoo.aidl", R"(package p;)", &cpp_types_, &reported_error));
   EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
 }
 
 TEST_F(AidlTest, FailOnMalformedConstHexValue) {
   AidlError reported_error;
-  EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
-                           R"(package p;
+  EXPECT_EQ(nullptr,
+            Parse("p/IFoo.aidl",
+                   R"(package p;
                       interface IFoo {
                         const int BAD_HEX_VALUE = 0xffffffffffffffffff;
                       }
                    )",
-                           typenames_, Options::Language::CPP, &reported_error));
-  EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
+                   &cpp_types_,
+                   &reported_error));
+  EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
 }
 
 TEST_F(AidlTest, ParsePositiveConstHexValue) {
   AidlError reported_error;
-  auto cpp_parse_result = Parse("p/IFoo.aidl",
-                                R"(package p;
+  auto cpp_parse_result =
+    Parse("p/IFoo.aidl",
+           R"(package p;
               interface IFoo {
                 const int POSITIVE_HEX_VALUE = 0xf5;
               }
            )",
-                                typenames_, Options::Language::CPP, &reported_error);
+           &cpp_types_,
+           &reported_error);
   EXPECT_NE(nullptr, cpp_parse_result);
   const AidlInterface* interface = cpp_parse_result->AsInterface();
   ASSERT_NE(nullptr, interface);
   const auto& cpp_constants = interface->GetConstantDeclarations();
   EXPECT_EQ((size_t)1, cpp_constants.size());
   EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_constants[0]->GetName());
-  EXPECT_TRUE(cpp_constants[0]->CheckValid(typenames_));
   EXPECT_EQ("245", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
 }
 
 TEST_F(AidlTest, ParseNegativeConstHexValue) {
   AidlError reported_error;
-  auto cpp_parse_result = Parse("p/IFoo.aidl",
-                                R"(package p;
+  auto cpp_parse_result =
+    Parse("p/IFoo.aidl",
+           R"(package p;
               interface IFoo {
                 const int NEGATIVE_HEX_VALUE = 0xffffffff;
               }
            )",
-                                typenames_, Options::Language::CPP, &reported_error);
-  ASSERT_NE(nullptr, cpp_parse_result);
+           &cpp_types_,
+           &reported_error);
+  EXPECT_NE(nullptr, cpp_parse_result);
   const AidlInterface* interface = cpp_parse_result->AsInterface();
   ASSERT_NE(nullptr, interface);
   const auto& cpp_constants = interface->GetConstantDeclarations();
   EXPECT_EQ((size_t)1, cpp_constants.size());
   EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_constants[0]->GetName());
-  EXPECT_EQ(true, cpp_constants[0]->CheckValid(typenames_));
   EXPECT_EQ("-1", cpp_constants[0]->ValueString(cpp::ConstantValueDecorator));
 }
 
@@ -642,14 +508,12 @@
   const string input = "package p; import p.Outer; interface IFoo"
                        " { Outer.Inner get(); }";
 
-  auto cpp_parse_result = Parse(input_path, input, typenames_, Options::Language::CPP);
+  auto cpp_parse_result = Parse(input_path, input, &cpp_types_);
   EXPECT_NE(nullptr, cpp_parse_result);
-
-  auto pair = typenames_.ResolveTypename("p.Outer.Inner");
-  EXPECT_TRUE(pair.second);
+  auto cpp_type = cpp_types_.FindTypeByCanonicalName("p.Outer.Inner");
+  ASSERT_NE(nullptr, cpp_type);
   // C++ uses "::" instead of "." to refer to a inner class.
-  AidlTypeSpecifier nested_type(AIDL_LOCATION_HERE, "p.Outer.Inner", false, nullptr, "");
-  EXPECT_EQ("::p::Outer::Inner", cpp::CppNameOf(nested_type, typenames_));
+  EXPECT_EQ("::p::Outer::Inner", cpp_type->CppType());
 }
 
 TEST_F(AidlTest, UnderstandsNativeParcelables) {
@@ -659,31 +523,24 @@
   import_paths_.emplace("");
   const string input_path = "p/IFoo.aidl";
   const string input = "package p; import p.Bar; interface IFoo { }";
-  {
-    // C++ understands C++ specific stuff
-    auto cpp_parse_result = Parse(input_path, input, typenames_, Options::Language::CPP);
-    EXPECT_NE(nullptr, cpp_parse_result);
-    auto pair = typenames_.ResolveTypename("p.Bar");
-    EXPECT_TRUE(pair.second);
-    AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", false, nullptr, "");
-    native_type.Resolve(typenames_);
-    EXPECT_EQ("::p::Bar", cpp::CppNameOf(native_type, typenames_));
-    set<string> headers;
-    cpp::AddHeaders(native_type, typenames_, headers);
-    EXPECT_EQ(1u, headers.size());
-    EXPECT_EQ(1u, headers.count("baz/header"));
-  }
-  typenames_.Reset();
-  {
-    // Java ignores C++ specific stuff
-    auto java_parse_result = Parse(input_path, input, typenames_, Options::Language::JAVA);
-    EXPECT_NE(nullptr, java_parse_result);
-    auto pair = typenames_.ResolveTypename("p.Bar");
-    EXPECT_TRUE(pair.second);
-    AidlTypeSpecifier native_type(AIDL_LOCATION_HERE, "p.Bar", false, nullptr, "");
-    native_type.Resolve(typenames_);
-    EXPECT_EQ("p.Bar", java::InstantiableJavaSignatureOf(native_type, typenames_));
-  }
+
+  // C++ understands C++ specific stuff
+  auto cpp_parse_result = Parse(input_path, input, &cpp_types_);
+  EXPECT_NE(nullptr, cpp_parse_result);
+  auto cpp_type = cpp_types_.FindTypeByCanonicalName("p.Bar");
+  ASSERT_NE(nullptr, cpp_type);
+  EXPECT_EQ("::p::Bar", cpp_type->CppType());
+  set<string> headers;
+  cpp_type->GetHeaders(&headers);
+  EXPECT_EQ(1u, headers.size());
+  EXPECT_EQ(1u, headers.count("baz/header"));
+
+  // Java ignores C++ specific stuff
+  auto java_parse_result = Parse(input_path, input, &java_types_);
+  EXPECT_NE(nullptr, java_parse_result);
+  auto java_type = java_types_.FindTypeByCanonicalName("p.Bar");
+  ASSERT_NE(nullptr, java_type);
+  EXPECT_EQ("p.Bar", java_type->InstantiableName());
 }
 
 TEST_F(AidlTest, WritesCorrectDependencyFile) {
@@ -774,11 +631,10 @@
                            "  List<int, List<String, bool>> foo(); }";
   string nested_in_parcelable = "package a; parcelable IData {\n"
                                 "  List<int, List<String, bool>> foo;}";
-  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, typenames_, Options::Language::JAVA));
-  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, typenames_, Options::Language::CPP));
-  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, typenames_,
-Options::Language::JAVA)); EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, typenames_,
-Options::Language::CPP));
+  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, &java_types_));
+  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_iface, &cpp_types_));
+  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, &java_types_));
+  EXPECT_NE(nullptr, Parse("a/IFoo.aidl", nested_in_parcelable, &cpp_types_));
 }
 */
 
@@ -903,33 +759,44 @@
   EXPECT_NE(0, ::android::aidl::compile_aidl(options2, io_delegate_));
 }
 
-TEST_F(AidlTest, FailOnMultipleTypesInSingleFile) {
-  std::vector<std::string> rawOptions{"aidl --lang=java -o out foo/bar/Foo.aidl",
-                                      "aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl"};
-  for (auto& rawOption : rawOptions) {
-    Options options = Options::From(rawOption);
-    io_delegate_.SetFileContents(options.InputFiles().front(),
-                                 "package foo.bar;\n"
-                                 "interface IFoo1 { int foo(); }\n"
-                                 "interface IFoo2 { int foo(); }\n"
-                                 "parcelable Data1 { int a; int b;}\n"
-                                 "parcelable Data2 { int a; int b;}\n");
+TEST_F(AidlTest, MultipleTypesInSingleFile) {
+  Options options = Options::From("aidl --lang=java -o out foo/bar/Foo.aidl");
+  io_delegate_.SetFileContents(options.InputFiles().front(),
+      "package foo.bar;\n"
+      "interface IFoo1 { int foo(); }\n"
+      "interface IFoo2 { int foo(); }\n"
+      "parcelable Data { int a; int b;}\n");
 
-    EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
+  EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
 
-    io_delegate_.SetFileContents(options.InputFiles().front(),
-                                 "package foo.bar;\n"
-                                 "interface IFoo1 { int foo(); }\n"
-                                 "interface IFoo2 { int foo(); }\n");
+  string content;
+  for (const auto file :
+    {"out/foo/bar/IFoo1.java", "out/foo/bar/IFoo2.java", "out/foo/bar/Data.java"}) {
+    content.clear();
+    EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
+    EXPECT_FALSE(content.empty());
+  }
+}
 
-    EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
+TEST_F(AidlTest, MultipleTypesInSingleFileCpp) {
+  Options options = Options::From("aidl --lang=cpp -o out -h out/include foo/bar/Foo.aidl");
+  io_delegate_.SetFileContents(options.InputFiles().front(),
+      "package foo.bar;\n"
+      "interface IFoo1 { int foo(); }\n"
+      "interface IFoo2 { int foo(); }\n"
+      "parcelable Data { int a; int b;}\n");
 
-    io_delegate_.SetFileContents(options.InputFiles().front(),
-                                 "package foo.bar;\n"
-                                 "parcelable Data1 { int a; int b;}\n"
-                                 "parcelable Data2 { int a; int b;}\n");
+  EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
 
-    EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
+  string content;
+  for (const auto file : {
+    "out/foo/bar/IFoo1.cpp", "out/foo/bar/IFoo2.cpp", "out/foo/bar/Data.cpp",
+    "out/include/foo/bar/IFoo1.h", "out/include/foo/bar/IFoo2.h", "out/include/foo/bar/Data.h",
+    "out/include/foo/bar/BpFoo1.h", "out/include/foo/bar/BpFoo2.h", "out/include/foo/bar/BpData.h",
+    "out/include/foo/bar/BnFoo1.h", "out/include/foo/bar/BnFoo2.h", "out/include/foo/bar/BnData.h"}) {
+    content.clear();
+    EXPECT_TRUE(io_delegate_.GetWrittenContents(file, &content));
+    EXPECT_FALSE(content.empty());
   }
 }
 
@@ -1014,7 +881,7 @@
   EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
 }
 
-TEST_F(AidlTest, DifferentOrderAnnotationsInCheckAPI) {
+TEST_F(AidlTest, DiffrentOrderAnnotationsInCheckAPI) {
   Options options = Options::From("aidl --checkapi old new");
   io_delegate_.SetFileContents("old/p/IFoo.aidl",
                                "package p; interface IFoo{ @utf8InCpp @nullable String foo();}");
@@ -1032,102 +899,73 @@
   EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
 }
 
-class AidlTestCompatibleChanges : public AidlTest {
- protected:
-  Options options_ = Options::From("aidl --checkapi old new");
-};
-
-TEST_F(AidlTestCompatibleChanges, NewType) {
+TEST_F(AidlTest, SuccessOnCompatibleChanges) {
+  Options options = Options::From("aidl --checkapi old new");
   io_delegate_.SetFileContents("old/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void foo(int a);"
                                "}");
+  io_delegate_.SetFileContents("old/p/Data.aidl",
+                               "package p;"
+                               "parcelable Data {"
+                               "  int foo;"
+                               "}");
+
+  // new type
   io_delegate_.SetFileContents("new/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void foo(int a);"
                                "}");
+  io_delegate_.SetFileContents("new/p/Data.aidl",
+                               "package p;"
+                               "parcelable Data {"
+                               "  int foo;"
+                               "}");
   io_delegate_.SetFileContents("new/p/IBar.aidl",
                                "package p;"
                                "interface IBar {"
                                "  void bar();"
                                "}");
-  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
+  EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+  io_delegate_.SetFileContents("new/p/IBar.aidl", "");
 
-TEST_F(AidlTestCompatibleChanges, NewMethod) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
-                               "package p;"
-                               "interface IFoo {"
-                               "  void foo(int a);"
-                               "}");
+  // new method
   io_delegate_.SetFileContents("new/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void foo(int a);"
                                "  void bar();"
                                "}");
-  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, NewField) {
-  io_delegate_.SetFileContents("old/p/Data.aidl",
+  io_delegate_.SetFileContents("new/p/Data.aidl",
                                "package p;"
                                "parcelable Data {"
                                "  int foo;"
                                "}");
+  EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+  // new field
+  io_delegate_.SetFileContents("new/p/IFoo.aidl",
+                               "package p;"
+                               "interface IFoo {"
+                               "  void foo(int a);"
+                               "}");
   io_delegate_.SetFileContents("new/p/Data.aidl",
                                "package p;"
                                "parcelable Data {"
                                "  int foo;"
                                "  int bar;"
                                "}");
-  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
+  EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
 
-TEST_F(AidlTestCompatibleChanges, NewEnumerator) {
-  io_delegate_.SetFileContents("old/p/Enum.aidl",
-                               "package p;"
-                               "enum Enum {"
-                               "  FOO = 1,"
-                               "}");
-  io_delegate_.SetFileContents("new/p/Enum.aidl",
-                               "package p;"
-                               "enum Enum {"
-                               "  FOO = 1,"
-                               "  BAR = 2,"
-                               "}");
-  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, ReorderedEnumerator) {
-  io_delegate_.SetFileContents("old/p/Enum.aidl",
-                               "package p;"
-                               "enum Enum {"
-                               "  FOO = 1,"
-                               "  BAR = 2,"
-                               "}");
-  io_delegate_.SetFileContents("new/p/Enum.aidl",
-                               "package p;"
-                               "enum Enum {"
-                               "  BAR = 2,"
-                               "  FOO = 1,"
-                               "}");
-  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, NewPackage) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
-                               "package p;"
-                               "interface IFoo {"
-                               "  void foo(int a);"
-                               "}");
-  io_delegate_.SetFileContents("old/p/Data.aidl",
-                               "package p;"
-                               "parcelable Data {"
-                               "  int foo;"
-                               "}");
+  // new package
   io_delegate_.SetFileContents("new/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
@@ -1148,273 +986,277 @@
                                "parcelable Data {"
                                "  int foo;"
                                "}");
-  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
+  EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+  io_delegate_.SetFileContents("new/q/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/q/Data.aidl", "");
 
-TEST_F(AidlTestCompatibleChanges, ArgNameChange) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
-                               "package p;"
-                               "interface IFoo {"
-                               "  void foo(int a);"
-                               "}");
+  // arg name change
   io_delegate_.SetFileContents("new/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void foo(int b);"
                                "}");
-  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, AddedConstValue) {
-  io_delegate_.SetFileContents("old/p/I.aidl",
-                               "package p; interface I {"
-                               "const int A = 1; }");
-  io_delegate_.SetFileContents("new/p/I.aidl",
-                               "package p ; interface I {"
-                               "const int A = 1; const int B = 2;}");
-  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestCompatibleChanges, ChangedConstValueOrder) {
-  io_delegate_.SetFileContents("old/p/I.aidl",
-                               "package p; interface I {"
-                               "const int A = 1; const int B = 2;}");
-  io_delegate_.SetFileContents("new/p/I.aidl",
-                               "package p ; interface I {"
-                               "const int B = 2; const int A = 1;}");
-  EXPECT_TRUE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-class AidlTestIncompatibleChanges : public AidlTest {
- protected:
-  Options options_ = Options::From("aidl --checkapi old new");
-};
-
-TEST_F(AidlTestIncompatibleChanges, RemovedType) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
-                               "package p;"
-                               "interface IFoo {"
-                               "  void foo(in String[] str);"
-                               "  void bar(@utf8InCpp String str);"
-                               "}");
-  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RemovedMethod) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
-                               "package p;"
-                               "interface IFoo {"
-                               "  void foo(in String[] str);"
-                               "  void bar(@utf8InCpp String str);"
-                               "}");
-  io_delegate_.SetFileContents("new/p/IFoo.aidl",
-                               "package p;"
-                               "interface IFoo {"
-                               "  void foo(in String[] str);"
-                               "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RemovedField) {
-  io_delegate_.SetFileContents("old/p/Data.aidl",
-                               "package p;"
-                               "parcelable Data {"
-                               "  int foo;"
-                               "  int bar;"
-                               "}");
   io_delegate_.SetFileContents("new/p/Data.aidl",
                                "package p;"
                                "parcelable Data {"
                                "  int foo;"
                                "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
+  EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+  io_delegate_.SetFileContents("old/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("old/p/Data.aidl", "");
+
+  // added const value
+  io_delegate_.SetFileContents("old/p/I.aidl",
+                               "package p; interface I {"
+                               "const int A = 1; }");
+  io_delegate_.SetFileContents("new/p/I.aidl",
+                               "package p ; interface I {"
+                               "const int A = 1; const int B = 2;}");
+  EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("old/p/I.aidl", "");
+  io_delegate_.SetFileContents("new/p/I.aidl", "");
+
+  // changed const value order
+  io_delegate_.SetFileContents("old/p/I.aidl",
+                               "package p; interface I {"
+                               "const int A = 1; const int B = 2;}");
+  io_delegate_.SetFileContents("new/p/I.aidl",
+                               "package p ; interface I {"
+                               "const int B = 2; const int A = 1;}");
+  EXPECT_TRUE(::android::aidl::check_api(options, io_delegate_));
 }
 
-TEST_F(AidlTestIncompatibleChanges, RemovedEnumerator) {
-  io_delegate_.SetFileContents("old/p/Enum.aidl",
-                               "package p;"
-                               "enum Enum {"
-                               "  FOO = 1,"
-                               "  BAR = 2,"
-                               "}");
-  io_delegate_.SetFileContents("new/p/Enum.aidl",
-                               "package p;"
-                               "enum Enum {"
-                               "  BAR = 2,"
-                               "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RenamedMethod) {
+TEST_F(AidlTest, FailOnIncompatibleChanges) {
+  Options options = Options::From("aidl --checkapi old new");
   io_delegate_.SetFileContents("old/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void foo(in String[] str);"
                                "  void bar(@utf8InCpp String str);"
                                "}");
+  io_delegate_.SetFileContents("old/p/Data.aidl",
+                               "package p;"
+                               "parcelable Data {"
+                               "  int foo;"
+                               "  int bar;"
+                               "}");
+
+  // removed type
+  io_delegate_.SetFileContents("new/p/IFoo.aidl",
+                               "package p;"
+                               "interface IFoo {"
+                               "  void foo(in String[] str);"
+                               "  void bar(@utf8InCpp String str);"
+                               "}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+
+  // removed method
+  io_delegate_.SetFileContents("new/p/IFoo.aidl",
+                               "package p;"
+                               "interface IFoo {"
+                               "  void foo(in String[] str);"
+                               "}");
+  io_delegate_.SetFileContents("new/p/Data.aidl",
+                               "package p;"
+                               "parcelable Data {"
+                               "  int foo;"
+                               "  int bar;"
+                               "}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+  // removed field
+  io_delegate_.SetFileContents("new/p/IFoo.aidl",
+                               "package p;"
+                               "interface IFoo {"
+                               "  void foo(in String[] str);"
+                               "  void bar(@utf8InCpp String str);"
+                               "}");
+  io_delegate_.SetFileContents("new/p/Data.aidl",
+                               "package p;"
+                               "parcelable Data {"
+                               "  int foo;"
+                               "}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+  // renamed method
   io_delegate_.SetFileContents("new/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void foo(in String[] str);"
                                "  void bar2(@utf8InCpp String str);"
                                "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RenamedField) {
-  io_delegate_.SetFileContents("old/p/Data.aidl",
+  io_delegate_.SetFileContents("new/p/Data.aidl",
                                "package p;"
                                "parcelable Data {"
                                "  int foo;"
                                "  int bar;"
                                "}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+  // renamed field
+  io_delegate_.SetFileContents("new/p/IFoo.aidl",
+                               "package p;"
+                               "interface IFoo {"
+                               "  void foo(in String[] str);"
+                               "  void bar(@utf8InCpp String str);"
+                               "}");
   io_delegate_.SetFileContents("new/p/Data.aidl",
                                "package p;"
                                "parcelable Data {"
                                "  int foo;"
                                "  int bar2;"
                                "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
 
-TEST_F(AidlTestIncompatibleChanges, RenamedType) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
-                               "package p;"
-                               "interface IFoo {"
-                               "  void foo(in String[] str);"
-                               "  void bar(@utf8InCpp String str);"
-                               "}");
+  // renamed type
   io_delegate_.SetFileContents("new/p/IFoo2.aidl",
                                "package p;"
                                "interface IFoo2 {"
                                "  void foo(in String[] str);"
                                "  void bar(@utf8InCpp String str);"
                                "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+  io_delegate_.SetFileContents("new/p/Data.aidl",
+                               "package p;"
+                               "parcelable Data {"
+                               "  int foo;"
+                               "  int bar;"
+                               "}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo2.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
 
-TEST_F(AidlTestIncompatibleChanges, ChangedEnumerator) {
-  io_delegate_.SetFileContents("old/p/Enum.aidl",
-                               "package p;"
-                               "enum Enum {"
-                               "  FOO = 1,"
-                               "  BAR = 2,"
-                               "}");
-  io_delegate_.SetFileContents("new/p/Enum.aidl",
-                               "package p;"
-                               "enum Enum {"
-                               "  FOO = 3,"
-                               "  BAR = 2,"
-                               "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, ReorderedMethod) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
-                               "package p;"
-                               "interface IFoo {"
-                               "  void foo(in String[] str);"
-                               "  void bar(@utf8InCpp String str);"
-                               "}");
+  // reorderd method
   io_delegate_.SetFileContents("new/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void bar(@utf8InCpp String str);"
                                "  void foo(in String[] str);"
                                "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, ReorderedField) {
-  io_delegate_.SetFileContents("old/p/Data.aidl",
+  io_delegate_.SetFileContents("new/p/Data.aidl",
                                "package p;"
                                "parcelable Data {"
                                "  int foo;"
                                "  int bar;"
                                "}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+  // reorderd field
+  io_delegate_.SetFileContents("new/p/IFoo.aidl",
+                               "package p;"
+                               "interface IFoo {"
+                               "  void foo(in String[] str);"
+                               "  void bar(@utf8InCpp String str);"
+                               "}");
   io_delegate_.SetFileContents("new/p/Data.aidl",
                                "package p;"
                                "parcelable Data {"
                                "  int bar;"
                                "  int foo;"
                                "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
 
-TEST_F(AidlTestIncompatibleChanges, ChangedDirectionSpecifier) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
-                               "package p;"
-                               "interface IFoo {"
-                               "  void foo(in String[] str);"
-                               "  void bar(@utf8InCpp String str);"
-                               "}");
+  // changed direction specifier
   io_delegate_.SetFileContents("new/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void foo(out String[] str);"
                                "  void bar(@utf8InCpp String str);"
                                "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, AddedAnnotation) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
+  io_delegate_.SetFileContents("new/p/Data.aidl",
                                "package p;"
-                               "interface IFoo {"
-                               "  void foo(in String[] str);"
-                               "  void bar(@utf8InCpp String str);"
+                               "parcelable Data {"
+                               "  int foo;"
+                               "  int bar;"
                                "}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+  // added annotation
   io_delegate_.SetFileContents("new/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void foo(in @utf8InCpp String[] str);"
                                "  void bar(@utf8InCpp String str);"
                                "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
-
-TEST_F(AidlTestIncompatibleChanges, RemovedAnnotation) {
-  io_delegate_.SetFileContents("old/p/IFoo.aidl",
+  io_delegate_.SetFileContents("new/p/Data.aidl",
                                "package p;"
-                               "interface IFoo {"
-                               "  void foo(in String[] str);"
-                               "  void bar(@utf8InCpp String str);"
+                               "parcelable Data {"
+                               "  int foo;"
+                               "  int bar;"
                                "}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
+
+  // removed annotation
   io_delegate_.SetFileContents("new/p/IFoo.aidl",
                                "package p;"
                                "interface IFoo {"
                                "  void foo(in String[] str);"
                                "  void bar(String str);"
                                "}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+  io_delegate_.SetFileContents("new/p/Data.aidl",
+                               "package p;"
+                               "parcelable Data {"
+                               "  int foo;"
+                               "  int bar;"
+                               "}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/Data.aidl", "");
 
-TEST_F(AidlTestIncompatibleChanges, RemovedPackage) {
+  // removed package
+  io_delegate_.SetFileContents("old/p/Data.aidl", "");
   io_delegate_.SetFileContents("old/p/IFoo.aidl", "package p; interface IFoo{}");
   io_delegate_.SetFileContents("old/q/IFoo.aidl", "package q; interface IFoo{}");
-  io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
 
-TEST_F(AidlTestIncompatibleChanges, ChangedDefaultValue) {
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "package p; interface IFoo{}");
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("old/p/IFoo.aidl", "");
+  io_delegate_.SetFileContents("old/q/IFoo.aidl", "");
+  io_delegate_.SetFileContents("new/p/IFoo.aidl", "");
+
+  // changed default value
   io_delegate_.SetFileContents("old/p/D.aidl", "package p; parcelable D { int a = 1; }");
   io_delegate_.SetFileContents("new/p/D.aidl", "package p; parcelable D { int a = 2; }");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("old/p/D.aidl", "");
+  io_delegate_.SetFileContents("new/p/D.aidl", "");
 
-TEST_F(AidlTestIncompatibleChanges, RemovedConstValue) {
+  // removed const value
   io_delegate_.SetFileContents("old/p/I.aidl",
                                "package p; interface I {"
                                "const int A = 1; const int B = 2;}");
   io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 1; }");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
-}
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("old/p/I.aidl", "");
+  io_delegate_.SetFileContents("new/p/I.aidl", "");
 
-TEST_F(AidlTestIncompatibleChanges, ChangedConstValue) {
+  // changed const value
   io_delegate_.SetFileContents("old/p/I.aidl", "package p; interface I { const int A = 1; }");
   io_delegate_.SetFileContents("new/p/I.aidl", "package p; interface I { const int A = 2; }");
-  EXPECT_FALSE(::android::aidl::check_api(options_, io_delegate_));
+  EXPECT_FALSE(::android::aidl::check_api(options, io_delegate_));
+  io_delegate_.SetFileContents("old/p/I.aidl", "");
+  io_delegate_.SetFileContents("new/p/I.aidl", "");
 }
 
 TEST_F(AidlTest, RejectAmbiguousImports) {
@@ -1516,21 +1358,6 @@
   EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
 }
 
-TEST_F(AidlTest, AllowDuplicatedImportPaths) {
-  Options options = Options::From("aidl --lang=java -I dir -I dir IFoo.aidl");
-  io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
-  io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
-  EXPECT_EQ(0, ::android::aidl::compile_aidl(options, io_delegate_));
-}
-
-TEST_F(AidlTest, FailOnAmbiguousImports) {
-  Options options = Options::From("aidl --lang=java -I dir -I dir2 IFoo.aidl");
-  io_delegate_.SetFileContents("dir/IBar.aidl", "interface IBar{}");
-  io_delegate_.SetFileContents("dir2/IBar.aidl", "interface IBar{}");
-  io_delegate_.SetFileContents("IFoo.aidl", "import IBar; interface IFoo{}");
-  EXPECT_NE(0, ::android::aidl::compile_aidl(options, io_delegate_));
-}
-
 class AidlOutputPathTest : public AidlTest {
  protected:
   void SetUp() override {
@@ -1565,67 +1392,5 @@
   Test(Options::From("aidl sub/dir/foo/bar/IFoo.aidl"), "sub/dir/foo/bar/IFoo.java");
 }
 
-TEST_F(AidlTest, FailOnOutOfBoundsInt32MaxConstInt) {
-  AidlError reported_error;
-  EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
-                           R"(package p;
-                              interface IFoo {
-                                const int int32_max_oob = 2147483650;
-                              }
-                             )",
-                           typenames_, Options::Language::CPP, &reported_error));
-  EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
-}
-
-TEST_F(AidlTest, FailOnOutOfBoundsInt32MinConstInt) {
-  AidlError reported_error;
-  EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
-                           R"(package p;
-                              interface IFoo {
-                                const int int32_min_oob = -2147483650;
-                              }
-                             )",
-                           typenames_, Options::Language::CPP, &reported_error));
-  EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
-}
-
-TEST_F(AidlTest, FailOnOutOfBoundsInt64MaxConstInt) {
-  AidlError reported_error;
-  EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
-                           R"(package p;
-                              interface IFoo {
-                                const long int64_max_oob = 21474836509999999999999999;
-                              }
-                             )",
-                           typenames_, Options::Language::CPP, &reported_error));
-  EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
-}
-
-TEST_F(AidlTest, FailOnOutOfBoundsInt64MinConstInt) {
-  AidlError reported_error;
-  EXPECT_EQ(nullptr, Parse("p/IFoo.aidl",
-                           R"(package p;
-                              interface IFoo {
-                                const long int64_min_oob = -21474836509999999999999999;
-                              }
-                             )",
-                           typenames_, Options::Language::CPP, &reported_error));
-  EXPECT_EQ(AidlError::PARSE_ERROR, reported_error);
-}
-
-TEST_F(AidlTest, FailOnOutOfBoundsAutofilledEnum) {
-  AidlError reported_error;
-  EXPECT_EQ(nullptr, Parse("p/TestEnum.aidl",
-                           R"(package p;
-                              @Backing(type="byte")
-                              enum TestEnum {
-                                FOO = 127,
-                                BAR,
-                              }
-                             )",
-                           typenames_, Options::Language::CPP, &reported_error));
-  EXPECT_EQ(AidlError::BAD_TYPE, reported_error);
-}
-
 }  // namespace aidl
 }  // namespace android
diff --git a/ast_cpp.cpp b/ast_cpp.cpp
index 98566fb..e5ed6d8 100644
--- a/ast_cpp.cpp
+++ b/ast_cpp.cpp
@@ -92,18 +92,16 @@
     : key(k),
       value(v) {}
 
-Enum::Enum(const string& name, const string& base_type, bool is_class)
-    : enum_name_(name), underlying_type_(base_type), is_class_(is_class) {}
+Enum::Enum(const string& name, const string& base_type)
+    : enum_name_(name), underlying_type_(base_type) {}
+
+Enum::Enum(const string& name) : Enum(name, "") {}
 
 void Enum::Write(CodeWriter* to) const {
-  to->Write("enum ");
-  if (is_class_) {
-    to->Write("class ");
-  }
   if (underlying_type_.empty()) {
-    to->Write("%s {\n", enum_name_.c_str());
+    to->Write("enum %s {\n", enum_name_.c_str());
   } else {
-    to->Write("%s : %s {\n", enum_name_.c_str(), underlying_type_.c_str());
+    to->Write("enum %s : %s {\n", enum_name_.c_str(), underlying_type_.c_str());
   }
   to->Indent();
   for (const auto& field : fields_) {
@@ -263,10 +261,6 @@
         arguments_(std::move(arg_list)),
         initializer_list_(initializer_list) {}
 
-StatementBlock* ConstructorImpl::GetStatementBlock() {
-  return &body_;
-}
-
 void ConstructorImpl::Write(CodeWriter* to) const {
   to->Write("%s::%s", class_name_.c_str(), class_name_.c_str());
   arguments_.Write(to);
diff --git a/ast_cpp.h b/ast_cpp.h
index 635519d..9f9414a 100644
--- a/ast_cpp.h
+++ b/ast_cpp.h
@@ -87,7 +87,8 @@
 
 class Enum : public Declaration {
  public:
-  Enum(const std::string& name, const std::string& base_type, bool is_class);
+  Enum(const std::string& name, const std::string& base_type);
+  explicit Enum(const std::string& name);
   virtual ~Enum() = default;
 
   bool HasValues() const { return !fields_.empty(); }
@@ -104,7 +105,6 @@
 
   std::string enum_name_;
   std::string underlying_type_;
-  bool is_class_;
   std::vector<EnumField> fields_;
 
   DISALLOW_COPY_AND_ASSIGN(Enum);
@@ -228,9 +228,6 @@
                   const std::vector<std::string>& initializer_list);
   virtual ~ConstructorImpl() = default;
 
-  // ConstructorImpl retains ownership of the statement block.
-  StatementBlock* GetStatementBlock();
-
   void Write(CodeWriter* to) const override;
 
  private:
diff --git a/ast_cpp_unittest.cpp b/ast_cpp_unittest.cpp
index c8f1937..6c34424 100644
--- a/ast_cpp_unittest.cpp
+++ b/ast_cpp_unittest.cpp
@@ -59,6 +59,13 @@
 #endif  // HEADER_INCLUDE_GUARD_H_
 )";
 
+const char kExpectedEnumOutput[] =
+R"(enum Foo {
+  BAR = 42,
+  BAZ,
+};
+)";
+
 const char kExpectedSwitchOutput[] =
 R"(switch (var) {
 case 2:
@@ -139,34 +146,11 @@
   CompareGeneratedCode(cpp_header, kExpectedHeaderOutput);
 }
 
-TEST_F(AstCppTests, GeneratesUnscopedEnum) {
-  Enum e("Foo", "", false);
+TEST_F(AstCppTests, GeneratesEnum) {
+  Enum e("Foo");
   e.AddValue("BAR", "42");
   e.AddValue("BAZ", "");
-
-  string expected =
-      R"(enum Foo {
-  BAR = 42,
-  BAZ,
-};
-)";
-
-  CompareGeneratedCode(e, expected);
-}
-
-TEST_F(AstCppTests, GeneratesScopedEnum) {
-  Enum e("Foo", "int32_t", true);
-  e.AddValue("BAR", "42");
-  e.AddValue("BAZ", "");
-
-  string expected =
-      R"(enum class Foo : int32_t {
-  BAR = 42,
-  BAZ,
-};
-)";
-
-  CompareGeneratedCode(e, expected);
+  CompareGeneratedCode(e, kExpectedEnumOutput);
 }
 
 TEST_F(AstCppTests, GeneratesArgList) {
diff --git a/ast_java.cpp b/ast_java.cpp
index f997494..d38319c 100644
--- a/ast_java.cpp
+++ b/ast_java.cpp
@@ -65,7 +65,7 @@
   }
 }
 
-void WriteArgumentList(CodeWriter* to, const vector<std::shared_ptr<Expression>>& arguments) {
+void WriteArgumentList(CodeWriter* to, const vector<Expression*>& arguments) {
   size_t N = arguments.size();
   for (size_t i = 0; i < N; i++) {
     arguments[i]->Write(to);
@@ -75,7 +75,7 @@
   }
 }
 
-Field::Field(int m, std::shared_ptr<Variable> v) : ClassElement(), modifiers(m), variable(v) {}
+Field::Field(int m, Variable* v) : ClassElement(), modifiers(m), variable(v) {}
 
 void Field::Write(CodeWriter* to) const {
   if (this->comment.length() != 0) {
@@ -105,22 +105,27 @@
   to->Write("\"%s\"", this->value.c_str());
 }
 
-Variable::Variable(const string& t, const string& n) : type(t), name(n) {}
+Variable::Variable(const string& t, const string& n) : type(t), name(n), dimension(0) {}
+
+Variable::Variable(const string& t, const string& n, int d) : type(t), name(n), dimension(d) {}
 
 void Variable::WriteDeclaration(CodeWriter* to) const {
-  to->Write("%s %s", this->type.c_str(), this->name.c_str());
+  string dim;
+  for (int i = 0; i < this->dimension; i++) {
+    dim += "[]";
+  }
+  to->Write("%s%s %s", this->type.c_str(), dim.c_str(), this->name.c_str());
 }
 
 void Variable::Write(CodeWriter* to) const { to->Write("%s", name.c_str()); }
 
-FieldVariable::FieldVariable(std::shared_ptr<Expression> o, const string& n)
-    : receiver(o), name(n) {}
+FieldVariable::FieldVariable(Expression* o, const string& n) : receiver(o), name(n) {}
 
 FieldVariable::FieldVariable(const string& c, const string& n) : receiver(c), name(n) {}
 
 void FieldVariable::Write(CodeWriter* to) const {
   visit(
-      overloaded{[&](std::shared_ptr<Expression> e) { e->Write(to); },
+      overloaded{[&](Expression* e) { e->Write(to); },
                  [&](const std::string& s) { to->Write("%s", s.c_str()); }, [](std::monostate) {}},
       this->receiver);
   to->Write(".%s", name.c_str());
@@ -143,26 +148,24 @@
   to->Write("}\n");
 }
 
-void StatementBlock::Add(std::shared_ptr<Statement> statement) {
+void StatementBlock::Add(Statement* statement) {
   this->statements.push_back(statement);
 }
 
-void StatementBlock::Add(std::shared_ptr<Expression> expression) {
-  this->statements.push_back(std::make_shared<ExpressionStatement>(expression));
+void StatementBlock::Add(Expression* expression) {
+  this->statements.push_back(new ExpressionStatement(expression));
 }
 
-ExpressionStatement::ExpressionStatement(std::shared_ptr<Expression> e) : expression(e) {}
+ExpressionStatement::ExpressionStatement(Expression* e) : expression(e) {}
 
 void ExpressionStatement::Write(CodeWriter* to) const {
   this->expression->Write(to);
   to->Write(";\n");
 }
 
-Assignment::Assignment(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r)
-    : lvalue(l), rvalue(r) {}
+Assignment::Assignment(Variable* l, Expression* r) : lvalue(l), rvalue(r) {}
 
-Assignment::Assignment(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r, string c)
-    : lvalue(l), rvalue(r), cast(c) {}
+Assignment::Assignment(Variable* l, Expression* r, string c) : lvalue(l), rvalue(r), cast(c) {}
 
 void Assignment::Write(CodeWriter* to) const {
   this->lvalue->Write(to);
@@ -175,24 +178,42 @@
 
 MethodCall::MethodCall(const string& n) : name(n) {}
 
-MethodCall::MethodCall(const string& n, const std::vector<std::shared_ptr<Expression>>& args)
-    : name(n), arguments(args) {}
+MethodCall::MethodCall(const string& n, int argc = 0, ...) : name(n) {
+  va_list args;
+  va_start(args, argc);
+  init(argc, args);
+  va_end(args);
+}
 
-MethodCall::MethodCall(std::shared_ptr<Expression> o, const string& n) : receiver(o), name(n) {}
+MethodCall::MethodCall(Expression* o, const string& n) : receiver(o), name(n) {}
 
 MethodCall::MethodCall(const std::string& t, const string& n) : receiver(t), name(n) {}
 
-MethodCall::MethodCall(std::shared_ptr<Expression> o, const string& n,
-                       const std::vector<std::shared_ptr<Expression>>& args)
-    : receiver(o), name(n), arguments(args) {}
+MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...) : receiver(o), name(n) {
+  va_list args;
+  va_start(args, argc);
+  init(argc, args);
+  va_end(args);
+}
 
-MethodCall::MethodCall(const std::string& t, const string& n,
-                       const std::vector<std::shared_ptr<Expression>>& args)
-    : receiver(t), name(n), arguments(args) {}
+MethodCall::MethodCall(const std::string& t, const string& n, int argc = 0, ...)
+    : receiver(t), name(n) {
+  va_list args;
+  va_start(args, argc);
+  init(argc, args);
+  va_end(args);
+}
+
+void MethodCall::init(int n, va_list args) {
+  for (int i = 0; i < n; i++) {
+    Expression* expression = (Expression*)va_arg(args, void*);
+    this->arguments.push_back(expression);
+  }
+}
 
 void MethodCall::Write(CodeWriter* to) const {
   visit(
-      overloaded{[&](std::shared_ptr<Expression> e) {
+      overloaded{[&](Expression* e) {
                    e->Write(to);
                    to->Write(".");
                  },
@@ -203,8 +224,7 @@
   to->Write(")");
 }
 
-Comparison::Comparison(std::shared_ptr<Expression> l, const string& o,
-                       std::shared_ptr<Expression> r)
+Comparison::Comparison(Expression* l, const string& o, Expression* r)
     : lvalue(l), op(o), rvalue(r) {}
 
 void Comparison::Write(CodeWriter* to) const {
@@ -217,9 +237,19 @@
 
 NewExpression::NewExpression(const std::string& n) : instantiableName(n) {}
 
-NewExpression::NewExpression(const std::string& n,
-                             const std::vector<std::shared_ptr<Expression>>& args)
-    : instantiableName(n), arguments(args) {}
+NewExpression::NewExpression(const std::string& n, int argc = 0, ...) : instantiableName(n) {
+  va_list args;
+  va_start(args, argc);
+  init(argc, args);
+  va_end(args);
+}
+
+void NewExpression::init(int n, va_list args) {
+  for (int i = 0; i < n; i++) {
+    Expression* expression = (Expression*)va_arg(args, void*);
+    this->arguments.push_back(expression);
+  }
+}
 
 void NewExpression::Write(CodeWriter* to) const {
   to->Write("new %s(", this->instantiableName.c_str());
@@ -227,8 +257,7 @@
   to->Write(")");
 }
 
-NewArrayExpression::NewArrayExpression(const std::string& t, std::shared_ptr<Expression> s)
-    : type(t), size(s) {}
+NewArrayExpression::NewArrayExpression(const std::string& t, Expression* s) : type(t), size(s) {}
 
 void NewArrayExpression::Write(CodeWriter* to) const {
   to->Write("new %s[", this->type.c_str());
@@ -236,7 +265,7 @@
   to->Write("]");
 }
 
-Cast::Cast(const std::string& t, std::shared_ptr<Expression> e) : type(t), expression(e) {}
+Cast::Cast(const std::string& t, Expression* e) : type(t), expression(e) {}
 
 void Cast::Write(CodeWriter* to) const {
   to->Write("((%s)", this->type.c_str());
@@ -244,10 +273,9 @@
   to->Write(")");
 }
 
-VariableDeclaration::VariableDeclaration(std::shared_ptr<Variable> l, std::shared_ptr<Expression> r)
-    : lvalue(l), rvalue(r) {}
+VariableDeclaration::VariableDeclaration(Variable* l, Expression* r) : lvalue(l), rvalue(r) {}
 
-VariableDeclaration::VariableDeclaration(std::shared_ptr<Variable> l) : lvalue(l) {}
+VariableDeclaration::VariableDeclaration(Variable* l) : lvalue(l) {}
 
 void VariableDeclaration::Write(CodeWriter* to) const {
   this->lvalue->WriteDeclaration(to);
@@ -271,7 +299,7 @@
   }
 }
 
-ReturnStatement::ReturnStatement(std::shared_ptr<Expression> e) : expression(e) {}
+ReturnStatement::ReturnStatement(Expression* e) : expression(e) {}
 
 void ReturnStatement::Write(CodeWriter* to) const {
   to->Write("return ");
@@ -308,7 +336,7 @@
   statements->Write(to);
 }
 
-SwitchStatement::SwitchStatement(std::shared_ptr<Expression> e) : expression(e) {}
+SwitchStatement::SwitchStatement(Expression* e) : expression(e) {}
 
 void SwitchStatement::Write(CodeWriter* to) const {
   to->Write("switch (");
@@ -338,7 +366,11 @@
                  SCOPE_MASK | STATIC | ABSTRACT | FINAL | OVERRIDE);
 
   if (this->returnType) {
-    to->Write("%s ", this->returnType->c_str());
+    string dim;
+    for (i = 0; i < this->returnTypeDimension; i++) {
+      dim += "[]";
+    }
+    to->Write("%s%s ", this->returnType->c_str(), dim.c_str());
   }
 
   to->Write("%s(", this->name.c_str());
@@ -455,11 +487,6 @@
   }
 }
 
-std::shared_ptr<Expression> NULL_VALUE = std::make_shared<LiteralExpression>("null");
-std::shared_ptr<Expression> THIS_VALUE = std::make_shared<LiteralExpression>("this");
-std::shared_ptr<Expression> SUPER_VALUE = std::make_shared<LiteralExpression>("super");
-std::shared_ptr<Expression> TRUE_VALUE = std::make_shared<LiteralExpression>("true");
-std::shared_ptr<Expression> FALSE_VALUE = std::make_shared<LiteralExpression>("false");
 }  // namespace java
 }  // namespace aidl
 }  // namespace android
diff --git a/ast_java.h b/ast_java.h
index d037d97..ec0ccfd 100644
--- a/ast_java.h
+++ b/ast_java.h
@@ -89,9 +89,11 @@
 struct Variable : public Expression {
   const std::string type;
   std::string name;
+  int dimension = 0;
 
   Variable() = default;
   Variable(const std::string& type, const std::string& name);
+  Variable(const std::string& type, const std::string& name, int dimension);
   virtual ~Variable() = default;
 
   void WriteDeclaration(CodeWriter* to) const;
@@ -99,10 +101,10 @@
 };
 
 struct FieldVariable : public Expression {
-  std::variant<std::shared_ptr<Expression>, std::string> receiver;
+  std::variant<Expression*, std::string> receiver;
   std::string name;
 
-  FieldVariable(std::shared_ptr<Expression> object, const std::string& name);
+  FieldVariable(Expression* object, const std::string& name);
   FieldVariable(const std::string& clazz, const std::string& name);
   virtual ~FieldVariable() = default;
 
@@ -113,11 +115,11 @@
   std::string comment;
   std::vector<std::string> annotations;
   int modifiers = 0;
-  std::shared_ptr<Variable> variable = nullptr;
+  Variable* variable = nullptr;
   std::string value;
 
   Field() = default;
-  Field(int modifiers, std::shared_ptr<Variable> variable);
+  Field(int modifiers, Variable* variable);
   virtual ~Field() = default;
 
   void Write(CodeWriter* to) const override;
@@ -138,108 +140,110 @@
 };
 
 struct StatementBlock : public Statement {
-  std::vector<std::shared_ptr<Statement>> statements;
+  std::vector<Statement*> statements;
 
   StatementBlock() = default;
   virtual ~StatementBlock() = default;
   void Write(CodeWriter* to) const override;
 
-  void Add(std::shared_ptr<Statement> statement);
-  void Add(std::shared_ptr<Expression> expression);
+  void Add(Statement* statement);
+  void Add(Expression* expression);
 };
 
 struct ExpressionStatement : public Statement {
-  std::shared_ptr<Expression> expression;
+  Expression* expression;
 
-  explicit ExpressionStatement(std::shared_ptr<Expression> expression);
+  explicit ExpressionStatement(Expression* expression);
   virtual ~ExpressionStatement() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct Assignment : public Expression {
-  std::shared_ptr<Variable> lvalue;
-  std::shared_ptr<Expression> rvalue;
+  Variable* lvalue;
+  Expression* rvalue;
   std::optional<std::string> cast = std::nullopt;
 
-  Assignment(std::shared_ptr<Variable> lvalue, std::shared_ptr<Expression> rvalue);
-  Assignment(std::shared_ptr<Variable> lvalue, std::shared_ptr<Expression> rvalue,
-             std::string cast);
+  Assignment(Variable* lvalue, Expression* rvalue);
+  Assignment(Variable* lvalue, Expression* rvalue, std::string cast);
   virtual ~Assignment() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct MethodCall : public Expression {
-  std::variant<std::monostate, std::shared_ptr<Expression>, std::string> receiver;
+  std::variant<std::monostate, Expression*, std::string> receiver;
   std::string name;
-  std::vector<std::shared_ptr<Expression>> arguments;
+  std::vector<Expression*> arguments;
   std::vector<std::string> exceptions;
 
   explicit MethodCall(const std::string& name);
-  MethodCall(const std::string& name, const std::vector<std::shared_ptr<Expression>>& args);
-  MethodCall(std::shared_ptr<Expression> obj, const std::string& name);
+  MethodCall(const std::string& name, int argc, ...);
+  MethodCall(Expression* obj, const std::string& name);
   MethodCall(const std::string& clazz, const std::string& name);
-  MethodCall(std::shared_ptr<Expression> obj, const std::string& name,
-             const std::vector<std::shared_ptr<Expression>>& args);
-  MethodCall(const std::string&, const std::string& name,
-             const std::vector<std::shared_ptr<Expression>>& args);
+  MethodCall(Expression* obj, const std::string& name, int argc, ...);
+  MethodCall(const std::string&, const std::string& name, int argc, ...);
   virtual ~MethodCall() = default;
   void Write(CodeWriter* to) const override;
+
+ private:
+  void init(int n, va_list args);
 };
 
 struct Comparison : public Expression {
-  std::shared_ptr<Expression> lvalue;
+  Expression* lvalue;
   std::string op;
-  std::shared_ptr<Expression> rvalue;
+  Expression* rvalue;
 
-  Comparison(std::shared_ptr<Expression> lvalue, const std::string& op,
-             std::shared_ptr<Expression> rvalue);
+  Comparison(Expression* lvalue, const std::string& op, Expression* rvalue);
   virtual ~Comparison() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct NewExpression : public Expression {
   const std::string instantiableName;
-  std::vector<std::shared_ptr<Expression>> arguments;
+  std::vector<Expression*> arguments;
 
   explicit NewExpression(const std::string& name);
-  NewExpression(const std::string& name, const std::vector<std::shared_ptr<Expression>>& args);
+  NewExpression(const std::string& name, int argc, ...);
   virtual ~NewExpression() = default;
   void Write(CodeWriter* to) const override;
+
+ private:
+  void init(int n, va_list args);
 };
 
 struct NewArrayExpression : public Expression {
   const std::string type;
-  std::shared_ptr<Expression> size;
+  Expression* size;
 
-  NewArrayExpression(const std::string& type, std::shared_ptr<Expression> size);
+  NewArrayExpression(const std::string& type, Expression* size);
   virtual ~NewArrayExpression() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct Cast : public Expression {
   const std::string type;
-  std::shared_ptr<Expression> expression = nullptr;
+  Expression* expression = nullptr;
 
   Cast() = default;
-  Cast(const std::string& type, std::shared_ptr<Expression> expression);
+  Cast(const std::string& type, Expression* expression);
   virtual ~Cast() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct VariableDeclaration : public Statement {
-  std::shared_ptr<Variable> lvalue = nullptr;
-  std::shared_ptr<Expression> rvalue = nullptr;
+  Variable* lvalue = nullptr;
+  Expression* rvalue = nullptr;
 
-  explicit VariableDeclaration(std::shared_ptr<Variable> lvalue);
-  VariableDeclaration(std::shared_ptr<Variable> lvalue, std::shared_ptr<Expression> rvalue);
+  explicit VariableDeclaration(Variable* lvalue);
+  VariableDeclaration(Variable* lvalue, Expression* rvalue);
   virtual ~VariableDeclaration() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct IfStatement : public Statement {
-  std::shared_ptr<Expression> expression = nullptr;
-  std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
-  std::shared_ptr<IfStatement> elseif = nullptr;
+  Expression* expression = nullptr;
+  StatementBlock* statements = new StatementBlock;
+  IfStatement* elseif = nullptr;
 
   IfStatement() = default;
   virtual ~IfStatement() = default;
@@ -247,15 +251,15 @@
 };
 
 struct ReturnStatement : public Statement {
-  std::shared_ptr<Expression> expression;
+  Expression* expression;
 
-  explicit ReturnStatement(std::shared_ptr<Expression> expression);
+  explicit ReturnStatement(Expression* expression);
   virtual ~ReturnStatement() = default;
   void Write(CodeWriter* to) const override;
 };
 
 struct TryStatement : public Statement {
-  std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
+  StatementBlock* statements = new StatementBlock;
 
   TryStatement() = default;
   virtual ~TryStatement() = default;
@@ -263,7 +267,7 @@
 };
 
 struct FinallyStatement : public Statement {
-  std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
+  StatementBlock* statements = new StatementBlock;
 
   FinallyStatement() = default;
   virtual ~FinallyStatement() = default;
@@ -272,7 +276,7 @@
 
 struct Case : public AstNode {
   std::vector<std::string> cases;
-  std::shared_ptr<StatementBlock> statements = std::make_shared<StatementBlock>();
+  StatementBlock* statements = new StatementBlock;
 
   Case() = default;
   explicit Case(const std::string& c);
@@ -281,10 +285,10 @@
 };
 
 struct SwitchStatement : public Statement {
-  std::shared_ptr<Expression> expression;
-  std::vector<std::shared_ptr<Case>> cases;
+  Expression* expression;
+  std::vector<Case*> cases;
 
-  explicit SwitchStatement(std::shared_ptr<Expression> expression);
+  explicit SwitchStatement(Expression* expression);
   virtual ~SwitchStatement() = default;
   void Write(CodeWriter* to) const override;
 };
@@ -294,10 +298,11 @@
   std::vector<std::string> annotations;
   int modifiers = 0;
   std::optional<std::string> returnType = std::nullopt;  // nullopt means constructor
+  size_t returnTypeDimension = 0;
   std::string name;
-  std::vector<std::shared_ptr<Variable>> parameters;
+  std::vector<Variable*> parameters;
   std::vector<std::string> exceptions;
-  std::shared_ptr<StatementBlock> statements = nullptr;
+  StatementBlock* statements = nullptr;
 
   Method() = default;
   virtual ~Method() = default;
@@ -324,7 +329,7 @@
   std::string type;
   std::optional<std::string> extends = std::nullopt;
   std::vector<std::string> interfaces;
-  std::vector<std::shared_ptr<ClassElement>> elements;
+  std::vector<ClassElement*> elements;
 
   Class() = default;
   virtual ~Class() = default;
@@ -346,11 +351,6 @@
   std::unique_ptr<Class> clazz_;
 };
 
-extern std::shared_ptr<Expression> NULL_VALUE;
-extern std::shared_ptr<Expression> THIS_VALUE;
-extern std::shared_ptr<Expression> SUPER_VALUE;
-extern std::shared_ptr<Expression> TRUE_VALUE;
-extern std::shared_ptr<Expression> FALSE_VALUE;
 }  // namespace java
 }  // namespace aidl
 }  // namespace android
diff --git a/ast_java_unittest.cpp b/ast_java_unittest.cpp
index 0101d42..d287504 100644
--- a/ast_java_unittest.cpp
+++ b/ast_java_unittest.cpp
@@ -20,6 +20,7 @@
 
 #include "ast_java.h"
 #include "code_writer.h"
+#include "type_java.h"
 
 using std::string;
 
@@ -38,12 +39,16 @@
 }  // namespace
 
 TEST(AstJavaTests, GeneratesClass) {
+  JavaTypeNamespace types;
+  types.Init();
+  Type class_type(&types, "TestClass", ValidatableType::KIND_GENERATED, false);
+  Type extend_type(&types, "SuperClass", ValidatableType::KIND_BUILT_IN, false);
   Class a_class;
   a_class.comment = "// class comment";
   a_class.modifiers = FINAL;
   a_class.what = Class::CLASS;
-  a_class.type = "TestClass";
-  a_class.extends = "SuperClass";
+  a_class.type = class_type.JavaType();
+  a_class.extends = extend_type.JavaType();
 
   string actual_output;
   a_class.Write(CodeWriter::ForString(&actual_output).get());
diff --git a/build/Android.bp b/build/Android.bp
index 9cf4125..9b27b32 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -35,8 +35,6 @@
 
 cc_defaults {
     name: "aidl-cpp-module-defaults",
-    // TODO(b/31559095): remove when host bionic is available
-    defaults: ["libbinder_ndk_host_user"],
     cflags: [
         "-Wall",
         "-Werror",
@@ -50,8 +48,12 @@
 
 // Tests
 
-filegroup {
-    name: "aidl-test-filegroup",
+// Copy of test-piece-1 as test only. Creating a separate library because 'vendor_available' is
+// contagious.
+aidl_interface {
+    name: "test-vendor",
+    local_include_dir: "tests_1",
+    vendor_available: true,
     srcs: [
         "tests_1/some_package/IFoo.aidl",
         "tests_1/some_package/Thing.aidl",
@@ -59,25 +61,13 @@
     ],
 }
 
-// Copy of test-piece-1 as test only. Creating a separate library because 'vendor_available' is
-// contagious.
-aidl_interface {
-    name: "test-variants",
-    local_include_dir: "tests_1",
-    vendor_available: true,
-    host_supported: true,
-    srcs: [
-        ":aidl-test-filegroup",
-    ],
-}
-
 aidl_interface {
     name: "test-piece-1",
     local_include_dir: "tests_1",
     srcs: [
         "tests_1/some_package/IFoo.aidl",
         "tests_1/some_package/Thing.aidl",
-        "tests_1/some_package/sub_package/*.aidl", // testing glob w/o filegroup
+        "tests_1/some_package/sub_package/*.aidl",
     ],
     api_dir: "api/test-piece-1",
     versions: ["1"],
diff --git a/build/Android.mk b/build/Android.mk
deleted file mode 100644
index e50f702..0000000
--- a/build/Android.mk
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-.PHONY: aidl-freeze-api
-aidl-freeze-api: $(addsuffix -freeze-api, $(SOONG_ALL_AIDL_INTERFACES))
diff --git a/build/aidl_interface.go b/build/aidl_interface.go
index 56534e7..ba022bf 100644
--- a/build/aidl_interface.go
+++ b/build/aidl_interface.go
@@ -20,7 +20,6 @@
 	"android/soong/genrule"
 	"android/soong/java"
 	"android/soong/phony"
-
 	"fmt"
 	"io"
 	"path/filepath"
@@ -40,6 +39,7 @@
 	langJava            = "java"
 	langNdk             = "ndk"
 	langNdkPlatform     = "ndk_platform"
+	futureVersion       = "10000"
 
 	pctx = android.NewPackageContext("android/aidl")
 
@@ -69,11 +69,10 @@
 	}, "imports", "outDir", "optionalFlags")
 
 	aidlDumpApiRule = pctx.StaticRule("aidlDumpApiRule", blueprint.RuleParams{
-		Command: `rm -rf "${outDir}" && mkdir -p "${outDir}" && ` +
-			`${aidlCmd} --dumpapi --structured ${imports} --out ${outDir} ${in} && ` +
-			`(cd ${outDir} && find ./ -name "*.aidl" -exec sha1sum {} ';' && echo ${latestVersion}) | sha1sum > ${hashFile} `,
+		Command: `rm -rf "${out}" && mkdir -p "${out}" && ` +
+			`${aidlCmd} --dumpapi --structured ${imports} --out ${out} ${in}`,
 		CommandDeps: []string{"${aidlCmd}"},
-	}, "imports", "outDir", "hashFile", "latestVersion")
+	}, "imports")
 
 	aidlDumpMappingsRule = pctx.StaticRule("aidlDumpMappingsRule", blueprint.RuleParams{
 		Command: `rm -rf "${outDir}" && mkdir -p "${outDir}" && ` +
@@ -86,12 +85,12 @@
 		blueprint.RuleParams{
 			Command: `mkdir -p ${to} && rm -rf ${to}/* && ` +
 				`${bpmodifyCmd} -w -m ${name} -parameter versions -a ${version} ${bp} && ` +
-				`cp -rf ${apiDir}/. ${to} && ` +
+				`cp -rf ${in}/* ${to} && ` +
 				`find ${to} -type f -exec bash -c ` +
 				`"cat ${apiPreamble} {} > {}.temp; mv {}.temp {}" \; && ` +
 				`touch ${out}`,
 			CommandDeps: []string{"${bpmodifyCmd}"},
-		}, "to", "name", "version", "bp", "apiDir", "apiPreamble")
+		}, "to", "name", "version", "bp", "apiPreamble")
 
 	aidlCheckApiRule = pctx.StaticRule("aidlCheckApiRule", blueprint.RuleParams{
 		Command: `(${aidlCmd} --checkapi ${old} ${new} && touch ${out}) || ` +
@@ -101,10 +100,10 @@
 	}, "old", "new", "messageFile")
 
 	aidlDiffApiRule = pctx.StaticRule("aidlDiffApiRule", blueprint.RuleParams{
-		Command: `(diff -N --line-format="" ${oldHashFile} ${newHashFile} && diff -r -B -I '//.*' ${old} ${new} && touch ${out}) || ` +
+		Command: `(diff -r -B -I '//.*' ${old} ${new} && touch ${out}) || ` +
 			`(cat ${messageFile} && exit 1)`,
 		Description: "Check equality of ${new} and ${old}",
-	}, "old", "new", "messageFile", "oldHashFile", "newHashFile")
+	}, "old", "new", "messageFile")
 )
 
 func init() {
@@ -113,7 +112,6 @@
 	pctx.SourcePathVariable("aidlToJniCmd", "system/tools/aidl/build/aidl_to_jni.py")
 	android.RegisterModuleType("aidl_interface", aidlInterfaceFactory)
 	android.RegisterModuleType("aidl_mapping", aidlMappingFactory)
-	android.RegisterMakeVarsProvider(pctx, allAidlInterfacesMakeVars)
 }
 
 // wrap(p, a, s) = [p + v + s for v in a]
@@ -134,24 +132,6 @@
 	return ret
 }
 
-func checkAndUpdateSources(ctx android.ModuleContext, rawSrcs []string, inDir string) android.Paths {
-	srcs := android.PathsForModuleSrc(ctx, rawSrcs)
-	srcs = android.PathsWithModuleSrcSubDir(ctx, srcs, inDir)
-
-	if len(srcs) == 0 {
-		ctx.PropertyErrorf("srcs", "No sources provided.")
-	}
-
-	for _, source := range srcs {
-		if source.Ext() != ".aidl" {
-			ctx.PropertyErrorf("srcs", "Source must be a .aidl file: "+source.String())
-			continue
-		}
-	}
-
-	return srcs
-}
-
 func isRelativePath(path string) bool {
 	if path == "" {
 		return true
@@ -161,14 +141,13 @@
 }
 
 type aidlGenProperties struct {
-	Srcs      []string `android:"path"`
-	AidlRoot  string   // base directory for the input aidl file
-	Imports   []string
-	Stability *string
-	Lang      string // target language [java|cpp|ndk]
-	BaseName  string
-	GenLog    bool
-	Version   string
+	Srcs     []string
+	AidlRoot string // base directory for the input aidl file
+	Imports  []string
+	Lang     string // target language [java|cpp|ndk]
+	BaseName string
+	GenLog   bool
+	Version  string
 }
 
 type aidlGenRule struct {
@@ -179,22 +158,15 @@
 	implicitInputs android.Paths
 	importFlags    string
 
-	genOutDir     android.ModuleGenPath
-	genHeaderDir  android.ModuleGenPath
-	genHeaderDeps android.Paths
-	genOutputs    android.WritablePaths
+	genOutDir    android.ModuleGenPath
+	genHeaderDir android.ModuleGenPath
+	genOutputs   android.WritablePaths
 }
 
 var _ android.SourceFileProducer = (*aidlGenRule)(nil)
 var _ genrule.SourceFileGenerator = (*aidlGenRule)(nil)
 
 func (g *aidlGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	srcs := checkAndUpdateSources(ctx, g.properties.Srcs, g.properties.AidlRoot)
-
-	if ctx.Failed() {
-		return
-	}
-
 	genDirTimestamp := android.PathForModuleGen(ctx, "timestamp")
 	g.implicitInputs = append(g.implicitInputs, genDirTimestamp)
 
@@ -212,12 +184,12 @@
 	})
 	g.importFlags = strings.Join(wrap("-I", importPaths, ""), " ")
 
+	srcs := android.PathsWithModuleSrcSubDir(ctx, android.PathsForModuleSrc(ctx, g.properties.Srcs), g.properties.AidlRoot)
+
 	g.genOutDir = android.PathForModuleGen(ctx)
 	g.genHeaderDir = android.PathForModuleGen(ctx, "include")
 	for _, src := range srcs {
-		outFile, headers := g.generateBuildActionsForSingleAidl(ctx, src)
-		g.genOutputs = append(g.genOutputs, outFile)
-		g.genHeaderDeps = append(g.genHeaderDeps, headers...)
+		g.genOutputs = append(g.genOutputs, g.generateBuildActionsForSingleAidl(ctx, src))
 	}
 
 	// This is to clean genOutDir before generating any file
@@ -231,7 +203,7 @@
 	})
 }
 
-func (g *aidlGenRule) generateBuildActionsForSingleAidl(ctx android.ModuleContext, src android.Path) (android.WritablePath, android.Paths) {
+func (g *aidlGenRule) generateBuildActionsForSingleAidl(ctx android.ModuleContext, src android.Path) android.WritablePath {
 	var outFile android.WritablePath
 	if g.properties.Lang == langJava {
 		outFile = android.PathForModuleGen(ctx, pathtools.ReplaceExtension(src.Rel(), "java"))
@@ -244,7 +216,6 @@
 		optionalFlags = append(optionalFlags, "--version "+g.properties.Version)
 	}
 
-	var headers android.WritablePaths
 	if g.properties.Lang == langJava {
 		ctx.ModuleBuild(pctx, android.ModuleBuildParams{
 			Rule:      aidlJavaRule,
@@ -274,6 +245,7 @@
 			prefix = "aidl"
 		}
 
+		var headers android.WritablePaths
 		headers = append(headers, g.genHeaderDir.Join(ctx, prefix, packagePath,
 			typeName+".h"))
 		headers = append(headers, g.genHeaderDir.Join(ctx, prefix, packagePath,
@@ -285,10 +257,6 @@
 			optionalFlags = append(optionalFlags, "--log")
 		}
 
-		if g.properties.Stability != nil {
-			optionalFlags = append(optionalFlags, "--stability", *g.properties.Stability)
-		}
-
 		aidlLang := g.properties.Lang
 		if aidlLang == langNdkPlatform {
 			aidlLang = "ndk"
@@ -310,7 +278,7 @@
 		})
 	}
 
-	return outFile, headers.Paths()
+	return outFile
 }
 
 func (g *aidlGenRule) GeneratedSourceFiles() android.Paths {
@@ -322,7 +290,7 @@
 }
 
 func (g *aidlGenRule) GeneratedDeps() android.Paths {
-	return g.genHeaderDeps
+	return g.genOutputs.Paths()
 }
 
 func (g *aidlGenRule) GeneratedHeaderDirs() android.Paths {
@@ -343,7 +311,7 @@
 
 type aidlApiProperties struct {
 	BaseName string
-	Srcs     []string `android:"path"`
+	Inputs   []string
 	Imports  []string
 	Api_dir  *string
 	Versions []string
@@ -377,23 +345,17 @@
 	} else {
 		latestVersion := m.properties.Versions[len(m.properties.Versions)-1]
 
-		i, err := strconv.Atoi(latestVersion)
+		i, err := strconv.ParseInt(latestVersion, 10, 64)
 		if err != nil {
 			ctx.PropertyErrorf("versions", "must be integers")
 			return ""
 		}
 
-		return strconv.Itoa(i + 1)
+		return strconv.FormatInt(i+1, 10)
 	}
 }
 
-func (m *aidlApi) createApiDumpFromSource(ctx android.ModuleContext) (apiDir android.WritablePath, apiFiles android.WritablePaths, hashFile android.WritablePath) {
-	srcs := checkAndUpdateSources(ctx, m.properties.Srcs, m.properties.AidlRoot)
-
-	if ctx.Failed() {
-		return
-	}
-
+func (m *aidlApi) createApiDumpFromSource(ctx android.ModuleContext) (apiDir android.WritablePath, apiFiles android.WritablePaths) {
 	var importPaths []string
 	ctx.VisitDirectDeps(func(dep android.Module) {
 		if importedAidl, ok := dep.(*aidlInterface); ok {
@@ -401,28 +363,28 @@
 		}
 	})
 
+	var srcs android.Paths
+	for _, input := range m.properties.Inputs {
+		path := android.PathForModuleSrc(ctx, input)
+		path = android.PathWithModuleSrcSubDir(ctx, path, m.properties.AidlRoot)
+		srcs = append(srcs, path)
+	}
+
 	apiDir = android.PathForModuleOut(ctx, "dump")
 	for _, src := range srcs {
 		apiFiles = append(apiFiles, android.PathForModuleOut(ctx, "dump", src.Rel()))
 	}
-	hashFile = android.PathForModuleOut(ctx, "dump", ".hash")
-	latestVersion := "latest-version"
-	if len(m.properties.Versions) >= 1 {
-		latestVersion = m.properties.Versions[len(m.properties.Versions)-1]
-	}
 	imports := strings.Join(wrap("-I", importPaths, ""), " ")
 	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
-		Rule:    aidlDumpApiRule,
-		Outputs: append(apiFiles, hashFile),
-		Inputs:  srcs,
+		Rule:            aidlDumpApiRule,
+		Inputs:          srcs,
+		Output:          apiDir,
+		ImplicitOutputs: apiFiles,
 		Args: map[string]string{
-			"imports":       imports,
-			"outDir":        apiDir.String(),
-			"hashFile":      hashFile.String(),
-			"latestVersion": latestVersion,
+			"imports": imports,
 		},
 	})
-	return apiDir, apiFiles, hashFile
+	return apiDir, apiFiles
 }
 
 func (m *aidlApi) freezeApiDumpAsVersion(ctx android.ModuleContext, apiDumpDir android.Path, apiFiles android.Paths, version string) android.WritablePath {
@@ -443,7 +405,6 @@
 		Output:      timestampFile,
 		Args: map[string]string{
 			"to":          filepath.Join(modulePath, m.apiDir(), version),
-			"apiDir":      apiDumpDir.String(),
 			"name":        m.properties.BaseName,
 			"version":     version,
 			"bp":          android.PathForModuleSrc(ctx, "Android.bp").String(),
@@ -474,8 +435,7 @@
 	return timestampFile
 }
 
-func (m *aidlApi) checkEquality(ctx android.ModuleContext, oldApiDir android.Path, oldApiFiles android.Paths, oldHashFile android.OptionalPath,
-	newApiDir android.Path, newApiFiles android.Paths, newHashFile android.Path) android.WritablePath {
+func (m *aidlApi) checkEquality(ctx android.ModuleContext, oldApiDir android.Path, oldApiFiles android.Paths, newApiDir android.Path, newApiFiles android.Paths) android.WritablePath {
 	newVersion := newApiDir.Base()
 	timestampFile := android.PathForModuleOut(ctx, "checkapi_"+newVersion+".timestamp")
 	messageFile := android.PathForSource(ctx, "system/tools/aidl/build/message_check_equality.txt")
@@ -483,10 +443,6 @@
 	implicits = append(implicits, oldApiFiles...)
 	implicits = append(implicits, newApiFiles...)
 	implicits = append(implicits, messageFile)
-	if oldHashFile.Valid() {
-		implicits = append(implicits, oldHashFile.Path())
-	}
-	implicits = append(implicits, newHashFile)
 	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
 		Rule:      aidlDiffApiRule,
 		Implicits: implicits,
@@ -495,8 +451,6 @@
 			"old":         oldApiDir.String(),
 			"new":         newApiDir.String(),
 			"messageFile": messageFile.String(),
-			"oldHashFile": oldHashFile.String(),
-			"newHashFile": newHashFile.String(),
 		},
 	})
 	return timestampFile
@@ -504,12 +458,12 @@
 
 func (m *aidlApi) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 	currentVersion := m.validateCurrentVersion(ctx)
-	currentDumpDir, currentApiFiles, currentHashFile := m.createApiDumpFromSource(ctx)
 
 	if ctx.Failed() {
 		return
 	}
 
+	currentDumpDir, currentApiFiles := m.createApiDumpFromSource(ctx)
 	m.freezeApiTimestamp = m.freezeApiDumpAsVersion(ctx, currentDumpDir, currentApiFiles.Paths(), currentVersion)
 
 	apiDirs := make(map[string]android.Path)
@@ -538,9 +492,7 @@
 		var checkApiTimestamp android.WritablePath
 		if ctx.Config().DefaultAppTargetSdkInt() != android.FutureApiLevel {
 			// If API is frozen, don't allow any change to the API
-			latestHashFile := android.OptionalPathForModuleSrc(ctx, proptools.StringPtr(filepath.Join(m.apiDir(), latestVersion, ".hash")))
-			checkApiTimestamp = m.checkEquality(ctx, apiDirs[latestVersion], apiFiles[latestVersion], latestHashFile,
-				apiDirs[currentVersion], apiFiles[currentVersion], currentHashFile)
+			checkApiTimestamp = m.checkEquality(ctx, apiDirs[latestVersion], apiFiles[latestVersion], apiDirs[currentVersion], apiFiles[currentVersion])
 		} else {
 			// If not, allow backwards compatible changes to the API
 			checkApiTimestamp = m.checkCompatibility(ctx, apiDirs[latestVersion], apiFiles[latestVersion], apiDirs[currentVersion], apiFiles[currentVersion])
@@ -577,10 +529,6 @@
 
 	// Whether the library can be installed on the vendor image.
 	Vendor_available *bool
-
-	// Whether the library can be used on host
-	Host_supported *bool
-
 	// Top level directories for includes.
 	// TODO(b/128940869): remove it if aidl_interface can depend on framework.aidl
 	Include_dirs []string
@@ -588,11 +536,12 @@
 	// TODO(b/111117220): automatically compute by letting AIDL parse multiple files simultaneously
 	Local_include_dir string
 
-	// List of .aidl files which compose this interface.
-	Srcs []string `android:"path"`
+	// The owner of the module
+	Owner *string
 
-	// List of aidl_interface modules that this uses. If one of your AIDL interfaces uses an
-	// interface or parcelable from another aidl_interface, you should put its name here.
+	// List of .aidl files which compose this interface. These may be globbed.
+	Srcs []string
+
 	Imports []string
 
 	// Used by gen dependency to fill out aidl include path
@@ -601,14 +550,6 @@
 	// Directory where API dumps are. Default is "api".
 	Api_dir *string
 
-	// Stability promise. Currently only supports "vintf".
-	// If this is unset, this corresponds to an interface with stability within
-	// this compilation context (so an interface loaded here can only be used
-	// with things compiled together, e.g. on the system.img).
-	// If this is set to "vintf", this corresponds to a stability promise: the
-	// interface must be kept stable as long as it is used.
-	Stability *string
-
 	// Previous API versions that are now frozen. The version that is last in
 	// the list is considered as the most recent version.
 	Versions []string
@@ -647,6 +588,9 @@
 	android.ModuleBase
 
 	properties aidlInterfaceProperties
+
+	// Unglobbed sources
+	rawSrcs []string
 }
 
 func (i *aidlInterface) shouldGenerateJavaBackend() bool {
@@ -664,6 +608,44 @@
 	return i.properties.Backend.Ndk.Enabled == nil || *i.properties.Backend.Ndk.Enabled
 }
 
+func (i *aidlInterface) checkAndUpdateSources(mctx android.LoadHookContext) {
+	prefix := mctx.ModuleDir()
+	for _, source := range i.properties.Srcs {
+		if pathtools.IsGlob(source) {
+			globbedSrcFiles, err := mctx.GlobWithDeps(filepath.Join(prefix, source), nil)
+			if err != nil {
+				mctx.ModuleErrorf("glob: %s", err.Error())
+			}
+			for _, globbedSrc := range globbedSrcFiles {
+				relativeGlobbedSrc, err := filepath.Rel(prefix, globbedSrc)
+				if err != nil {
+					panic(err)
+				}
+
+				i.rawSrcs = append(i.rawSrcs, relativeGlobbedSrc)
+			}
+		} else {
+			i.rawSrcs = append(i.rawSrcs, source)
+		}
+	}
+
+	if len(i.rawSrcs) == 0 {
+		mctx.PropertyErrorf("srcs", "No sources provided.")
+	}
+
+	for _, source := range i.rawSrcs {
+		if !strings.HasSuffix(source, ".aidl") {
+			mctx.PropertyErrorf("srcs", "Source must be a .aidl file: "+source)
+			continue
+		}
+
+		relativePath, err := filepath.Rel(i.properties.Local_include_dir, source)
+		if err != nil || !isRelativePath(relativePath) {
+			mctx.PropertyErrorf("srcs", "Source is not in local_include_dir: "+source)
+		}
+	}
+}
+
 func (i *aidlInterface) checkImports(mctx android.LoadHookContext) {
 	for _, anImport := range i.properties.Imports {
 		other := lookupInterface(anImport)
@@ -672,11 +654,6 @@
 			mctx.PropertyErrorf("imports", "Import does not exist: "+anImport)
 		}
 
-		if i.shouldGenerateJavaBackend() && !other.shouldGenerateJavaBackend() {
-			mctx.PropertyErrorf("backend.java.enabled",
-				"Java backend not enabled in the imported AIDL interface %q", anImport)
-		}
-
 		if i.shouldGenerateCppBackend() && !other.shouldGenerateCppBackend() {
 			mctx.PropertyErrorf("backend.cpp.enabled",
 				"C++ backend not enabled in the imported AIDL interface %q", anImport)
@@ -689,93 +666,17 @@
 	}
 }
 
-func (i *aidlInterface) checkStability(mctx android.LoadHookContext) {
-	if i.properties.Stability == nil {
-		return
-	}
-
-	if i.shouldGenerateJavaBackend() {
-		mctx.PropertyErrorf("stability", "Java backend does not yet support stability.")
-	}
-
-	// TODO(b/136027762): should we allow more types of stability (e.g. for APEX) or
-	// should we switch this flag to be something like "vintf { enabled: true }"
-	if *i.properties.Stability != "vintf" {
-		mctx.PropertyErrorf("stability", "must be empty or \"vintf\"")
-	}
-
-	// TODO(b/136027762): need some global way to understand AOSP interfaces. Also,
-	// need the implementation for vendor extensions to be merged. For now, restrict
-	// where this can be defined
-	if !filepath.HasPrefix(mctx.ModuleDir(), "hardware/interfaces/") {
-		mctx.PropertyErrorf("stability", "can only be set in hardware/interfaces")
-	}
-}
-
-func (i *aidlInterface) currentVersion(ctx android.BaseModuleContext) string {
-	if !i.hasVersion() {
-		return ""
-	} else {
-		i, err := strconv.Atoi(i.latestVersion())
-		if err != nil {
-			ctx.PropertyErrorf("versions", "must be integers")
-			return ""
-		}
-
-		return strconv.Itoa(i + 1)
-	}
-}
-
-func (i *aidlInterface) latestVersion() string {
-	return i.properties.Versions[len(i.properties.Versions)-1]
-}
-func (i *aidlInterface) isLatestVersion(version string) bool {
-	if !i.hasVersion() {
-		return true
-	}
-	return version == i.latestVersion()
-}
-func (i *aidlInterface) hasVersion() bool {
-	return len(i.properties.Versions) > 0
-}
-
-func (i *aidlInterface) isCurrentVersion(ctx android.BaseModuleContext, version string) bool {
-	return version == i.currentVersion(ctx)
-}
-
-// This function returns module name with version. Assume that there is foo of which latest version is 2
-// Version -> Module name
-// "1"->foo-V1
-// "2"->foo-V2
-// "3"(unfrozen)->foo-unstable
-// ""-> foo
-func (i *aidlInterface) versionedName(ctx android.BaseModuleContext, version string) string {
+func (i *aidlInterface) versionedName(version string) string {
 	name := i.ModuleBase.Name()
-	if version == "" {
-		return name
+	if version != futureVersion && version != "" {
+		name = name + "-V" + version
 	}
-	if i.isCurrentVersion(ctx, version) {
-		return name + "-unstable"
-	}
-	return name + "-V" + version
-}
-
-// The only difference between versionedName and cppOutputName is about unstable version
-// foo-unstable -> foo-V3
-func (i *aidlInterface) cppOutputName(version string) string {
-	name := i.ModuleBase.Name()
-	if !i.hasVersion() {
-		return name
-	}
-	if version == "" {
-		version = i.latestVersion()
-	}
-	return name + "-V" + version
+	return name
 }
 
 func (i *aidlInterface) srcsForVersion(mctx android.LoadHookContext, version string) (srcs []string, base string) {
-	if i.isCurrentVersion(mctx, version) {
-		return i.properties.Srcs, i.properties.Local_include_dir
+	if version == futureVersion || version == "" {
+		return i.rawSrcs, i.properties.Local_include_dir
 	} else {
 		var apiDir string
 		if i.properties.Api_dir != nil {
@@ -806,8 +707,8 @@
 
 	i.properties.Full_import_paths = importPaths
 
+	i.checkAndUpdateSources(mctx)
 	i.checkImports(mctx)
-	i.checkStability(mctx)
 
 	if mctx.Failed() {
 		return
@@ -815,18 +716,14 @@
 
 	var libs []string
 
-	currentVersion := i.currentVersion(mctx)
-
-	versionsForCpp := make([]string, len(i.properties.Versions))
-	copy(versionsForCpp, i.properties.Versions)
-	if i.hasVersion() {
-		// In C++ library, AIDL doesn't create the module of which name is with latest version,
-		// instead of it, there is a module without version.
-		versionsForCpp[len(i.properties.Versions)-1] = ""
+	currentVersion := ""
+	if len(i.properties.Versions) > 0 {
+		currentVersion = futureVersion
 	}
+
 	if i.shouldGenerateCppBackend() {
 		libs = append(libs, addCppLibrary(mctx, i, currentVersion, langCpp))
-		for _, version := range versionsForCpp {
+		for _, version := range i.properties.Versions {
 			addCppLibrary(mctx, i, version, langCpp)
 		}
 	}
@@ -835,43 +732,35 @@
 		// TODO(b/119771576): inherit properties and export 'is vendor' computation from cc.go
 		if !proptools.Bool(i.properties.Vendor_available) {
 			libs = append(libs, addCppLibrary(mctx, i, currentVersion, langNdk))
-			for _, version := range versionsForCpp {
+			for _, version := range i.properties.Versions {
 				addCppLibrary(mctx, i, version, langNdk)
 			}
 		}
 		// TODO(b/121157555): combine with '-ndk' variant
 		libs = append(libs, addCppLibrary(mctx, i, currentVersion, langNdkPlatform))
-		for _, version := range versionsForCpp {
+		for _, version := range i.properties.Versions {
 			addCppLibrary(mctx, i, version, langNdkPlatform)
 		}
 	}
-	versionsForJava := i.properties.Versions
-	if i.hasVersion() {
-		versionsForJava = append(i.properties.Versions, "")
-	}
-	if i.shouldGenerateJavaBackend() {
-		libs = append(libs, addJavaLibrary(mctx, i, currentVersion))
-		for _, version := range versionsForJava {
-			addJavaLibrary(mctx, i, version)
-		}
+
+	libs = append(libs, addJavaLibrary(mctx, i, currentVersion))
+	for _, version := range i.properties.Versions {
+		addJavaLibrary(mctx, i, version)
 	}
 
 	addApiModule(mctx, i)
 
 	// Reserve this module name for future use
-	mctx.CreateModule(phony.PhonyFactory, &phonyProperties{
+	mctx.CreateModule(android.ModuleFactoryAdaptor(phony.PhonyFactory), &phonyProperties{
 		Name:     proptools.StringPtr(i.ModuleBase.Name()),
 		Required: libs,
 	})
 }
 
 func addCppLibrary(mctx android.LoadHookContext, i *aidlInterface, version string, lang string) string {
-	cppSourceGen := i.versionedName(mctx, version) + "-" + lang + "-source"
-	cppModuleGen := i.versionedName(mctx, version) + "-" + lang
-	cppOutputGen := i.cppOutputName(version) + "-" + lang
-	if i.hasVersion() && version == "" {
-		version = i.latestVersion()
-	}
+	cppSourceGen := i.versionedName(version) + "-" + lang + "-source"
+	cppModuleGen := i.versionedName(version) + "-" + lang
+
 	srcs, base := i.srcsForVersion(mctx, version)
 	if len(srcs) == 0 {
 		// This can happen when the version is about to be frozen; the version
@@ -887,17 +776,16 @@
 		genLog = proptools.Bool(i.properties.Backend.Ndk.Gen_log)
 	}
 
-	mctx.CreateModule(aidlGenFactory, &nameProperties{
+	mctx.CreateModule(android.ModuleFactoryAdaptor(aidlGenFactory), &nameProperties{
 		Name: proptools.StringPtr(cppSourceGen),
 	}, &aidlGenProperties{
-		Srcs:      srcs,
-		AidlRoot:  base,
-		Imports:   concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
-		Stability: i.properties.Stability,
-		Lang:      lang,
-		BaseName:  i.ModuleBase.Name(),
-		GenLog:    genLog,
-		Version:   version,
+		Srcs:     srcs,
+		AidlRoot: base,
+		Imports:  concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
+		Lang:     lang,
+		BaseName: i.ModuleBase.Name(),
+		GenLog:   genLog,
+		Version:  version,
 	})
 
 	importExportDependencies := wrap("", i.properties.Imports, "-"+lang)
@@ -906,15 +794,14 @@
 	var sdkVersion *string
 	var stl *string
 	var cpp_std *string
-	var host_supported *bool
-	var addCflags []string
-
 	if lang == langCpp {
 		importExportDependencies = append(importExportDependencies, "libbinder", "libutils")
 		if genLog {
 			libJSONCppDependency = []string{"libjsoncpp"}
 		}
-		host_supported = i.properties.Host_supported
+		sdkVersion = nil
+		stl = nil
+		cpp_std = nil
 	} else if lang == langNdk {
 		importExportDependencies = append(importExportDependencies, "libbinder_ndk")
 		if genLog {
@@ -927,16 +814,14 @@
 		if genLog {
 			libJSONCppDependency = []string{"libjsoncpp"}
 		}
-		host_supported = i.properties.Host_supported
-		addCflags = append(addCflags, "-DBINDER_STABILITY_SUPPORT")
 	} else {
 		panic("Unrecognized language: " + lang)
 	}
 
-	mctx.CreateModule(cc.LibraryFactory, &ccProperties{
+	mctx.CreateModule(android.ModuleFactoryAdaptor(cc.LibraryFactory), &ccProperties{
 		Name:                      proptools.StringPtr(cppModuleGen),
+		Owner:                     i.properties.Owner,
 		Vendor_available:          i.properties.Vendor_available,
-		Host_supported:            host_supported,
 		Defaults:                  []string{"aidl-cpp-module-defaults"},
 		Generated_sources:         []string{cppSourceGen},
 		Generated_headers:         []string{cppSourceGen},
@@ -949,19 +834,16 @@
 		Sdk_version:               sdkVersion,
 		Stl:                       stl,
 		Cpp_std:                   cpp_std,
-		Cflags:                    append(addCflags, "-Wextra", "-Wall", "-Werror"),
-		Stem:                      proptools.StringPtr(cppOutputGen),
+		Cflags:                    []string{"-Wextra", "-Wall", "-Werror"},
 	}, &i.properties.VndkProperties)
 
 	return cppModuleGen
 }
 
 func addJavaLibrary(mctx android.LoadHookContext, i *aidlInterface, version string) string {
-	javaSourceGen := i.versionedName(mctx, version) + "-java-source"
-	javaModuleGen := i.versionedName(mctx, version) + "-java"
-	if i.hasVersion() && version == "" {
-		version = i.latestVersion()
-	}
+	javaSourceGen := i.versionedName(version) + "-java-source"
+	javaModuleGen := i.versionedName(version) + "-java"
+
 	srcs, base := i.srcsForVersion(mctx, version)
 	if len(srcs) == 0 {
 		// This can happen when the version is about to be frozen; the version
@@ -972,25 +854,26 @@
 
 	sdkVersion := proptools.StringDefault(i.properties.Backend.Java.Sdk_version, "system_current")
 
-	mctx.CreateModule(aidlGenFactory, &nameProperties{
+	mctx.CreateModule(android.ModuleFactoryAdaptor(aidlGenFactory), &nameProperties{
 		Name: proptools.StringPtr(javaSourceGen),
 	}, &aidlGenProperties{
-		Srcs:      srcs,
-		AidlRoot:  base,
-		Imports:   concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
-		Stability: i.properties.Stability,
-		Lang:      langJava,
-		BaseName:  i.ModuleBase.Name(),
-		Version:   version,
+		Srcs:     srcs,
+		AidlRoot: base,
+		Imports:  concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
+		Lang:     langJava,
+		BaseName: i.ModuleBase.Name(),
+		Version:  version,
 	})
 
-	mctx.CreateModule(java.LibraryFactory, &javaProperties{
-		Name:        proptools.StringPtr(javaModuleGen),
-		Installable: proptools.BoolPtr(true),
-		Defaults:    []string{"aidl-java-module-defaults"},
-		Sdk_version: proptools.StringPtr(sdkVersion),
-		Static_libs: wrap("", i.properties.Imports, "-java"),
-		Srcs:        []string{":" + javaSourceGen},
+	mctx.CreateModule(android.ModuleFactoryAdaptor(java.LibraryFactory), &javaProperties{
+		Name:              proptools.StringPtr(javaModuleGen),
+		Owner:             i.properties.Owner,
+		Installable:       proptools.BoolPtr(true),
+		Defaults:          []string{"aidl-java-module-defaults"},
+		No_framework_libs: proptools.BoolPtr(true),
+		Sdk_version:       proptools.StringPtr(sdkVersion),
+		Static_libs:       wrap("", i.properties.Imports, "-java"),
+		Srcs:              []string{":" + javaSourceGen},
 	})
 
 	return javaModuleGen
@@ -998,11 +881,11 @@
 
 func addApiModule(mctx android.LoadHookContext, i *aidlInterface) string {
 	apiModule := i.ModuleBase.Name() + aidlApiSuffix
-	mctx.CreateModule(aidlApiFactory, &nameProperties{
+	mctx.CreateModule(android.ModuleFactoryAdaptor(aidlApiFactory), &nameProperties{
 		Name: proptools.StringPtr(apiModule),
 	}, &aidlApiProperties{
 		BaseName: i.ModuleBase.Name(),
-		Srcs:     i.properties.Srcs,
+		Inputs:   i.rawSrcs,
 		Imports:  concat(i.properties.Imports, []string{i.ModuleBase.Name()}),
 		Api_dir:  i.properties.Api_dir,
 		AidlRoot: i.properties.Local_include_dir,
@@ -1046,7 +929,7 @@
 
 type aidlMappingProperties struct {
 	// Source file of this prebuilt.
-	Srcs   []string `android:"path"`
+	Srcs   []string `android:"arch_variant"`
 	Output string
 }
 
@@ -1057,24 +940,56 @@
 }
 
 func (s *aidlMapping) DepsMutator(ctx android.BottomUpMutatorContext) {
+	android.ExtractSourcesDeps(ctx, s.properties.Srcs)
+}
+
+func addItemsToMap(dest map[string]bool, src []string) {
+	for _, item := range src {
+		dest[item] = true
+	}
 }
 
 func (s *aidlMapping) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	var aidlSrcs android.Paths
-	var importDirs []string
+	var srcs android.Paths
+	var all_import_dirs map[string]bool = make(map[string]bool)
 
-	srcs := android.PathsForModuleSrc(ctx, s.properties.Srcs)
-	for _, file := range srcs {
-		if file.Ext() == ".aidl" {
-			aidlSrcs = append(aidlSrcs, file)
-			baseDir := strings.TrimSuffix(file.String(), file.Rel())
-			if baseDir != "" && !android.InList(baseDir, importDirs) {
-				importDirs = append(importDirs, baseDir)
+	ctx.VisitDirectDeps(func(module android.Module) {
+		for _, property := range module.GetProperties() {
+			if jproperty, ok := property.(*java.CompilerProperties); ok {
+				for _, src := range jproperty.Srcs {
+					if strings.HasSuffix(src, ".aidl") {
+						full_path := android.PathForModuleSrc(ctx, src)
+						srcs = append(srcs, full_path)
+						all_import_dirs[filepath.Dir(full_path.String())] = true
+					} else if pathtools.IsGlob(src) {
+						globbedSrcFiles, err := ctx.GlobWithDeps(src, nil)
+						if err == nil {
+							for _, globbedSrc := range globbedSrcFiles {
+								full_path := android.PathForModuleSrc(ctx, globbedSrc)
+								all_import_dirs[full_path.String()] = true
+							}
+						}
+					}
+				}
+			} else if jproperty, ok := property.(*java.CompilerDeviceProperties); ok {
+				addItemsToMap(all_import_dirs, jproperty.Aidl.Include_dirs)
+				for _, include_dir := range jproperty.Aidl.Export_include_dirs {
+					var full_path = filepath.Join(ctx.ModuleDir(), include_dir)
+					all_import_dirs[full_path] = true
+				}
+				for _, include_dir := range jproperty.Aidl.Local_include_dirs {
+					var full_path = filepath.Join(ctx.ModuleSubDir(), include_dir)
+					all_import_dirs[full_path] = true
+				}
 			}
 		}
-	}
+	})
 
-	imports := android.JoinWithPrefix(importDirs, " -I")
+	var import_dirs []string
+	for dir := range all_import_dirs {
+		import_dirs = append(import_dirs, dir)
+	}
+	imports := strings.Join(wrap("-I", import_dirs, ""), " ")
 	s.outputFilePath = android.PathForModuleOut(ctx, s.properties.Output)
 	outDir := android.PathForModuleGen(ctx)
 	ctx.Build(pctx, android.BuildParams{
@@ -1109,13 +1024,3 @@
 		},
 	}
 }
-
-func allAidlInterfacesMakeVars(ctx android.MakeVarsContext) {
-	names := []string{}
-	ctx.VisitAllModules(func(module android.Module) {
-		if ai, ok := module.(*aidlInterface); ok {
-			names = append(names, ai.Name())
-		}
-	})
-	ctx.Strict("ALL_AIDL_INTERFACES", strings.Join(names, " "))
-}
diff --git a/build/properties.go b/build/properties.go
index a1b3489..f0256b8 100644
--- a/build/properties.go
+++ b/build/properties.go
@@ -30,7 +30,6 @@
 	Owner                     *string
 	Defaults                  []string
 	Vendor_available          *bool
-	Host_supported            *bool
 	Generated_sources         []string
 	Generated_headers         []string
 	Shared                    sharedLib
@@ -43,17 +42,17 @@
 	Stl                       *string
 	Cpp_std                   *string
 	Cflags                    []string
-	Stem                      *string
 }
 
 type javaProperties struct {
-	Name        *string
-	Owner       *string
-	Defaults    []string
-	Installable *bool
-	Sdk_version *string
-	Srcs        []string
-	Static_libs []string
+	Name              *string
+	Owner             *string
+	Defaults          []string
+	Installable       *bool
+	No_framework_libs *bool
+	Sdk_version       *string
+	Srcs              []string
+	Static_libs       []string
 }
 
 type phonyProperties struct {
diff --git a/docs/aidl-cpp.md b/docs/aidl-cpp.md
index aa97aa9..156b697 100644
--- a/docs/aidl-cpp.md
+++ b/docs/aidl-cpp.md
@@ -91,6 +91,7 @@
 | String                | String16            | in    | Supports null references.                             |
 | @utf8InCpp String     | std::string         | in    | @utf8InCpp causes UTF16 to UTF8 conversion in C++.    |
 | android.os.Parcelable | android::Parcelable | inout |                                                       |
+| java.util.Map         | android::binder::Map| inout | `std::map<std::string,android::binder::Value>`        |
 | T extends IBinder     | sp<T>               | in    |                                                       |
 | Arrays (T[])          | vector<T>           | inout | May contain only primitives, Strings and parcelables. |
 | List<String>          | vector<String16>    | inout |                                                       |
diff --git a/generate_aidl_mappings.cpp b/generate_aidl_mappings.cpp
index 1624ee6..97958e3 100644
--- a/generate_aidl_mappings.cpp
+++ b/generate_aidl_mappings.cpp
@@ -15,7 +15,7 @@
  */
 
 #include "generate_aidl_mappings.h"
-#include "aidl_to_java.h"
+#include "type_java.h"
 
 #include <sstream>
 
@@ -27,8 +27,7 @@
   return method.PrintLocation();
 }
 
-SignatureMap generate_mappings(const AidlDefinedType* defined_type,
-                               const AidlTypenames& typenames) {
+SignatureMap generate_mappings(const AidlDefinedType* defined_type) {
   const AidlInterface* interface = defined_type->AsInterface();
   SignatureMap mappings;
   if (interface == nullptr) {
@@ -40,10 +39,10 @@
       signature << interface->GetCanonicalName() << "|";
       signature << method->GetName() << "|";
       for (const auto& arg : method->GetArguments()) {
-        signature << java::JavaSignatureOf(arg->GetType(), typenames) << ",";
+        signature << arg->GetType().ToString() << ",";
       }
       signature << "|";
-      signature << java::JavaSignatureOf(method->GetType(), typenames);
+      signature << method->GetType().GetLanguageType<java::Type>()->JavaType();
       mappings[signature.str()] = dump_location(*method);
     }
   }
diff --git a/generate_aidl_mappings.h b/generate_aidl_mappings.h
index d74a17f..09f611e 100644
--- a/generate_aidl_mappings.h
+++ b/generate_aidl_mappings.h
@@ -26,7 +26,7 @@
 
 using SignatureMap = std::unordered_map<std::string, std::string>;
 
-SignatureMap generate_mappings(const AidlDefinedType* iface, const AidlTypenames& typenames);
+SignatureMap generate_mappings(const AidlDefinedType* iface);
 }  // namespace mappings
 }  // namespace aidl
 }  // namespace android
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index 70b9acb..9d2a1fb 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -63,7 +63,6 @@
 const char kIBinderHeader[] = "binder/IBinder.h";
 const char kIInterfaceHeader[] = "binder/IInterface.h";
 const char kParcelHeader[] = "binder/Parcel.h";
-const char kStabilityHeader[] = "binder/Stability.h";
 const char kStatusHeader[] = "binder/Status.h";
 const char kString16Header[] = "utils/String16.h";
 const char kTraceHeader[] = "utils/Trace.h";
@@ -93,28 +92,25 @@
   return unique_ptr<AstNode>(ret);
 }
 
-ArgList BuildArgList(const AidlTypenames& typenames, const AidlMethod& method, bool for_declaration,
+ArgList BuildArgList(const TypeNamespace& types, const AidlMethod& method, bool for_declaration,
                      bool type_name_only = false) {
   // Build up the argument list for the server method call.
   vector<string> method_arguments;
   for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
     string literal;
     if (for_declaration) {
-      // Method declarations need typenames, pointers to out params, and variable
+      // Method declarations need types, pointers to out params, and variable
       // names that match the .aidl specification.
-      literal = CppNameOf(a->GetType(), typenames);
+      const Type* type = a->GetType().GetLanguageType<Type>();
+
+      literal = type->CppType();
 
       if (a->IsOut()) {
         literal = literal + "*";
       } else {
-        const auto definedType = typenames.TryGetDefinedType(a->GetType().GetName());
-
-        const bool isEnum = definedType && definedType->AsEnumDeclaration() != nullptr;
-        const bool isPrimitive = AidlTypenames::IsPrimitiveTypename(a->GetType().GetName());
-
         // We pass in parameters that are not primitives by const reference.
         // Arrays of primitives are not primitives.
-        if (!(isPrimitive || isEnum) || a->GetType().IsArray()) {
+        if (!type->IsCppPrimitive() || a->GetType().IsArray()) {
           literal = "const " + literal + "&";
         }
       }
@@ -128,10 +124,12 @@
     method_arguments.push_back(literal);
   }
 
-  if (method.GetType().GetName() != "void") {
+  const Type* return_type = method.GetType().GetLanguageType<Type>();
+
+  if (return_type != types.VoidType()) {
     string literal;
     if (for_declaration) {
-      literal = StringPrintf("%s* %s", CppNameOf(method.GetType(), typenames).c_str(),
+      literal = StringPrintf("%s* %s", return_type->CppType().c_str(),
                              type_name_only ? "" : kReturnVarName);
     } else {
       literal = string{"&"} + kReturnVarName;
@@ -142,7 +140,8 @@
   return ArgList(method_arguments);
 }
 
-unique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method, const AidlTypenames& typenames,
+unique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method,
+                                        const TypeNamespace& types,
                                         bool for_interface) {
   uint32_t modifiers = 0;
   if (for_interface) {
@@ -153,11 +152,13 @@
   }
 
   return unique_ptr<Declaration>{
-      new MethodDecl{kBinderStatusLiteral, method.GetName(),
-                     BuildArgList(typenames, method, true /* for method decl */), modifiers}};
+      new MethodDecl{kBinderStatusLiteral,
+                     method.GetName(),
+                     BuildArgList(types, method, true /* for method decl */),
+                     modifiers}};
 }
 
-unique_ptr<Declaration> BuildMetaMethodDecl(const AidlMethod& method, const AidlTypenames&,
+unique_ptr<Declaration> BuildMetaMethodDecl(const AidlMethod& method, const TypeNamespace&,
                                             const Options& options, bool for_interface) {
   CHECK(!method.IsUserDefined());
   if (method.GetName() == kGetInterfaceVersion && options.Version()) {
@@ -195,9 +196,11 @@
   return NestInNamespaces(std::move(decls), package);
 }
 
-bool DeclareLocalVariable(const AidlArgument& a, StatementBlock* b,
-                          const AidlTypenames& typenamespaces) {
-  string type = CppNameOf(a.GetType(), typenamespaces);
+bool DeclareLocalVariable(const AidlArgument& a, StatementBlock* b) {
+  const Type* cpp_type = a.GetType().GetLanguageType<Type>();
+  if (!cpp_type) { return false; }
+
+  string type = cpp_type->CppType();
 
   b->AddLiteral(type + " " + BuildVarName(a));
   return true;
@@ -222,14 +225,14 @@
   return ret;
 }
 
-unique_ptr<Declaration> DefineClientTransaction(const AidlTypenames& typenames,
+unique_ptr<Declaration> DefineClientTransaction(const TypeNamespace& types,
                                                 const AidlInterface& interface,
                                                 const AidlMethod& method, const Options& options) {
   const string i_name = ClassName(interface, ClassNames::INTERFACE);
   const string bp_name = ClassName(interface, ClassNames::CLIENT);
-  unique_ptr<MethodImpl> ret{
-      new MethodImpl{kBinderStatusLiteral, bp_name, method.GetName(),
-                     ArgList{BuildArgList(typenames, method, true /* for method decl */)}}};
+  unique_ptr<MethodImpl> ret{new MethodImpl{
+      kBinderStatusLiteral, bp_name, method.GetName(),
+      ArgList{BuildArgList(types, method, true /* for method decl */)}}};
   StatementBlock* b = ret->GetStatementBlock();
 
   // Declare parcels to hold our query and the response.
@@ -264,17 +267,19 @@
   b->AddStatement(GotoErrorOnBadStatus());
 
   for (const auto& a: method.GetArguments()) {
-    const string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
+    const Type* type = a->GetType().GetLanguageType<Type>();
+    string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
+    var_name = type->WriteCast(var_name);
 
     if (a->IsIn()) {
       // Serialization looks roughly like:
       //     _aidl_ret_status = _aidl_data.WriteInt32(in_param_name);
       //     if (_aidl_ret_status != ::android::OK) { goto error; }
-      const string& method = ParcelWriteMethodOf(a->GetType(), typenames);
-      b->AddStatement(
-          new Assignment(kAndroidStatusVarName,
-                         new MethodCall(StringPrintf("%s.%s", kDataVarName, method.c_str()),
-                                        ParcelWriteCastOf(a->GetType(), typenames, var_name))));
+      const string& method = type->WriteToParcelMethod();
+      b->AddStatement(new Assignment(
+          kAndroidStatusVarName,
+          new MethodCall(StringPrintf("%s.%s", kDataVarName, method.c_str()),
+                         ArgList(var_name))));
       b->AddStatement(GotoErrorOnBadStatus());
     } else if (a->IsOut() && a->GetType().IsArray()) {
       // Special case, the length of the out array is written into the parcel.
@@ -282,7 +287,8 @@
       //     if (_aidl_ret_status != ::android::OK) { goto error; }
       b->AddStatement(new Assignment(
           kAndroidStatusVarName,
-          new MethodCall(StringPrintf("%s.writeVectorSize", kDataVarName), var_name)));
+          new MethodCall(StringPrintf("%s.writeVectorSize", kDataVarName),
+                         ArgList(var_name))));
       b->AddStatement(GotoErrorOnBadStatus());
     }
   }
@@ -308,7 +314,7 @@
   for (const auto& a : method.GetArguments()) {
     arg_names.emplace_back(a->GetName());
   }
-  if (method.GetType().GetName() != "void") {
+  if (method.GetType().GetLanguageType<Type>() != types.VoidType()) {
     arg_names.emplace_back(kReturnVarName);
   }
   b->AddLiteral(StringPrintf("if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && "
@@ -341,12 +347,14 @@
   // status" if we are a oneway method, so no more fear of accessing reply.
 
   // If the method is expected to return something, read it first by convention.
-  if (method.GetType().GetName() != "void") {
-    const string& method_call = ParcelReadMethodOf(method.GetType(), typenames);
+  const Type* return_type = method.GetType().GetLanguageType<Type>();
+  if (return_type != types.VoidType()) {
+    const string& method_call = return_type->ReadFromParcelMethod();
     b->AddStatement(new Assignment(
         kAndroidStatusVarName,
-        new MethodCall(StringPrintf("%s.%s", kReplyVarName, method_call.c_str()),
-                       ParcelReadCastOf(method.GetType(), typenames, kReturnVarName))));
+        new MethodCall(StringPrintf("%s.%s", kReplyVarName,
+                                    method_call.c_str()),
+                       ArgList(kReturnVarName))));
     b->AddStatement(GotoErrorOnBadStatus());
   }
 
@@ -354,12 +362,14 @@
     // Deserialization looks roughly like:
     //     _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name);
     //     if (_aidl_status != ::android::OK) { goto _aidl_error; }
-    string method = ParcelReadMethodOf(a->GetType(), typenames);
+    string method =
+      a->GetType().GetLanguageType<Type>()->ReadFromParcelMethod();
 
-    b->AddStatement(
-        new Assignment(kAndroidStatusVarName,
-                       new MethodCall(StringPrintf("%s.%s", kReplyVarName, method.c_str()),
-                                      ParcelReadCastOf(a->GetType(), typenames, a->GetName()))));
+    b->AddStatement(new Assignment(
+        kAndroidStatusVarName,
+        new MethodCall(StringPrintf("%s.%s", kReplyVarName,
+                                    method.c_str()),
+                       ArgList(a->GetName()))));
     b->AddStatement(GotoErrorOnBadStatus());
   }
 
@@ -384,7 +394,7 @@
   return unique_ptr<Declaration>(ret.release());
 }
 
-unique_ptr<Declaration> DefineClientMetaTransaction(const AidlTypenames& /* typenames */,
+unique_ptr<Declaration> DefineClientMetaTransaction(const TypeNamespace&,
                                                     const AidlInterface& interface,
                                                     const AidlMethod& method,
                                                     const Options& options) {
@@ -421,8 +431,8 @@
 
 }  // namespace
 
-unique_ptr<Document> BuildClientSource(const AidlTypenames& typenames,
-                                       const AidlInterface& interface, const Options& options) {
+unique_ptr<Document> BuildClientSource(const TypeNamespace& types, const AidlInterface& interface,
+                                       const Options& options) {
   vector<string> include_list = {
       HeaderFile(interface, ClassNames::CLIENT, false),
       kParcelHeader,
@@ -458,9 +468,9 @@
   for (const auto& method : interface.GetMethods()) {
     unique_ptr<Declaration> m;
     if (method->IsUserDefined()) {
-      m = DefineClientTransaction(typenames, interface, *method, options);
+      m = DefineClientTransaction(types, interface, *method, options);
     } else {
-      m = DefineClientMetaTransaction(typenames, interface, *method, options);
+      m = DefineClientMetaTransaction(types, interface, *method, options);
     }
     if (!m) { return nullptr; }
     file_decls.push_back(std::move(m));
@@ -472,20 +482,22 @@
 
 namespace {
 
-bool HandleServerTransaction(const AidlTypenames& typenames, const AidlInterface& interface,
+bool HandleServerTransaction(const TypeNamespace& types, const AidlInterface& interface,
                              const AidlMethod& method, const Options& options, StatementBlock* b) {
   // Declare all the parameters now.  In the common case, we expect no errors
   // in serialization.
   for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
-    if (!DeclareLocalVariable(*a, b, typenames)) {
+    if (!DeclareLocalVariable(*a, b)) {
       return false;
     }
   }
 
   // Declare a variable to hold the return value.
-  if (method.GetType().GetName() != "void") {
-    string type = CppNameOf(method.GetType(), typenames);
-    b->AddLiteral(StringPrintf("%s %s", type.c_str(), kReturnVarName));
+  const Type* return_type = method.GetType().GetLanguageType<Type>();
+  if (return_type != types.VoidType()) {
+    b->AddLiteral(StringPrintf(
+        "%s %s", return_type->CppType().c_str(),
+        kReturnVarName));
   }
 
   // Check that the client is calling the correct interface.
@@ -503,21 +515,23 @@
     // Deserialization looks roughly like:
     //     _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name);
     //     if (_aidl_ret_status != ::android::OK) { break; }
-    const string& var_name = "&" + BuildVarName(*a);
+    const Type* type = a->GetType().GetLanguageType<Type>();
+    const string& readMethod = type->ReadFromParcelMethod();
+
     if (a->IsIn()) {
-      const string& readMethod = ParcelReadMethodOf(a->GetType(), typenames);
-      b->AddStatement(
-          new Assignment{kAndroidStatusVarName,
-                         new MethodCall{string(kDataVarName) + "." + readMethod,
-                                        ParcelReadCastOf(a->GetType(), typenames, var_name)}});
+      b->AddStatement(new Assignment{
+          kAndroidStatusVarName,
+          new MethodCall{string(kDataVarName) + "." + readMethod,
+                         "&" + BuildVarName(*a)}});
       b->AddStatement(BreakOnStatusNotOk());
     } else if (a->IsOut() && a->GetType().IsArray()) {
       // Special case, the length of the out array is written into the parcel.
       //     _aidl_ret_status = _aidl_data.resizeOutVector(&out_param_name);
       //     if (_aidl_ret_status != ::android::OK) { break; }
-      b->AddStatement(
-          new Assignment{kAndroidStatusVarName,
-                         new MethodCall{string(kDataVarName) + ".resizeOutVector", var_name}});
+      b->AddStatement(new Assignment{
+          kAndroidStatusVarName,
+          new MethodCall{string(kDataVarName) + ".resizeOutVector",
+                         "&" + BuildVarName(*a)}});
       b->AddStatement(BreakOnStatusNotOk());
     }
   }
@@ -537,7 +551,8 @@
   // Call the actual method.  This is implemented by the subclass.
   vector<unique_ptr<AstNode>> status_args;
   status_args.emplace_back(new MethodCall(
-      method.GetName(), BuildArgList(typenames, method, false /* not for method decl */)));
+          method.GetName(),
+          BuildArgList(types, method, false /* not for method decl */)));
   b->AddStatement(new Statement(new MethodCall(
       StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName),
       ArgList(std::move(status_args)))));
@@ -566,13 +581,13 @@
   }
 
   // If we have a return value, write it first.
-  if (method.GetType().GetName() != "void") {
+  if (return_type != types.VoidType()) {
     string writeMethod =
-        string(kReplyVarName) + "->" + ParcelWriteMethodOf(method.GetType(), typenames);
-    b->AddStatement(new Assignment(
-        kAndroidStatusVarName,
-        new MethodCall(writeMethod,
-                       ParcelWriteCastOf(method.GetType(), typenames, kReturnVarName))));
+        string(kReplyVarName) + "->" +
+        return_type->WriteToParcelMethod();
+    b->AddStatement(new Assignment{
+        kAndroidStatusVarName, new MethodCall{writeMethod,
+        ArgList{return_type->WriteCast(kReturnVarName)}}});
     b->AddStatement(BreakOnStatusNotOk());
   }
   // Write each out parameter to the reply parcel.
@@ -580,18 +595,20 @@
     // Serialization looks roughly like:
     //     _aidl_ret_status = data.WriteInt32(out_param_name);
     //     if (_aidl_ret_status != ::android::OK) { break; }
-    const string& writeMethod = ParcelWriteMethodOf(a->GetType(), typenames);
-    b->AddStatement(new Assignment(
+    const Type* type = a->GetType().GetLanguageType<Type>();
+    const string& writeMethod = type->WriteToParcelMethod();
+
+    b->AddStatement(new Assignment{
         kAndroidStatusVarName,
-        new MethodCall(string(kReplyVarName) + "->" + writeMethod,
-                       ParcelWriteCastOf(a->GetType(), typenames, BuildVarName(*a)))));
+        new MethodCall{string(kReplyVarName) + "->" + writeMethod,
+                       type->WriteCast(BuildVarName(*a))}});
     b->AddStatement(BreakOnStatusNotOk());
   }
 
   return true;
 }
 
-bool HandleServerMetaTransaction(const AidlTypenames&, const AidlInterface& interface,
+bool HandleServerMetaTransaction(const TypeNamespace&, const AidlInterface& interface,
                                  const AidlMethod& method, const Options& options,
                                  StatementBlock* b) {
   CHECK(!method.IsUserDefined());
@@ -610,30 +627,18 @@
 
 }  // namespace
 
-unique_ptr<Document> BuildServerSource(const AidlTypenames& typenames,
-                                       const AidlInterface& interface, const Options& options) {
+unique_ptr<Document> BuildServerSource(const TypeNamespace& types, const AidlInterface& interface,
+                                       const Options& options) {
   const string bn_name = ClassName(interface, ClassNames::SERVER);
   vector<string> include_list{
       HeaderFile(interface, ClassNames::SERVER, false),
-      kParcelHeader,
-      kStabilityHeader,
+      kParcelHeader
   };
   if (options.GenLog()) {
     include_list.emplace_back("chrono");
     include_list.emplace_back("functional");
     include_list.emplace_back("json/value.h");
   }
-
-  unique_ptr<ConstructorImpl> constructor{
-      new ConstructorImpl{ClassName(interface, ClassNames::SERVER), ArgList{}, {}}};
-
-  if (interface.IsVintfStability()) {
-    constructor->GetStatementBlock()->AddLiteral("::android::internal::Stability::markVintf(this)");
-  } else {
-    constructor->GetStatementBlock()->AddLiteral(
-        "::android::internal::Stability::markCompilationUnit(this)");
-  }
-
   unique_ptr<MethodImpl> on_transact{new MethodImpl{
       kAndroidStatusLiteral, bn_name, "onTransact",
       ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
@@ -659,9 +664,9 @@
 
     bool success = false;
     if (method->IsUserDefined()) {
-      success = HandleServerTransaction(typenames, interface, *method, options, b);
+      success = HandleServerTransaction(types, interface, *method, options, b);
     } else {
-      success = HandleServerMetaTransaction(typenames, interface, *method, options, b);
+      success = HandleServerMetaTransaction(types, interface, *method, options, b);
     }
     if (!success) {
       return nullptr;
@@ -692,7 +697,6 @@
   on_transact->GetStatementBlock()->AddLiteral(
       StringPrintf("return %s", kAndroidStatusVarName));
   vector<unique_ptr<Declaration>> decls;
-  decls.push_back(std::move(constructor));
   decls.push_back(std::move(on_transact));
 
   if (options.Version() > 0) {
@@ -716,7 +720,7 @@
       new CppSource{include_list, NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
 }
 
-unique_ptr<Document> BuildInterfaceSource(const AidlTypenames& typenames,
+unique_ptr<Document> BuildInterfaceSource(const TypeNamespace& types,
                                           const AidlInterface& interface, const Options& options) {
   vector<string> include_list{
       HeaderFile(interface, ClassNames::RAW, false),
@@ -740,7 +744,8 @@
     const AidlConstantValue& value = constant->GetValue();
     if (value.GetType() != AidlConstantValue::Type::STRING) continue;
 
-    std::string cppType = CppNameOf(constant->GetType(), typenames);
+    std::string cppType = constant->GetType().GetLanguageType<Type>()->CppType();
+
     unique_ptr<MethodImpl> getter(new MethodImpl("const " + cppType + "&",
                                                  ClassName(interface, ClassNames::INTERFACE),
                                                  constant->GetName(), {}));
@@ -769,7 +774,7 @@
     if (method->IsUserDefined()) {
       std::ostringstream code;
       code << "::android::binder::Status " << default_impl << "::" << method->GetName()
-           << BuildArgList(typenames, *method, true, true).ToString() << " {\n"
+           << BuildArgList(types, *method, true, true).ToString() << " {\n"
            << "  return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);\n"
            << "}\n";
       decls.emplace_back(new LiteralDecl(code.str()));
@@ -789,8 +794,8 @@
       NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
 }
 
-unique_ptr<Document> BuildClientHeader(const AidlTypenames& typenames,
-                                       const AidlInterface& interface, const Options& options) {
+unique_ptr<Document> BuildClientHeader(const TypeNamespace& types, const AidlInterface& interface,
+                                       const Options& options) {
   const string i_name = ClassName(interface, ClassNames::INTERFACE);
   const string bp_name = ClassName(interface, ClassNames::CLIENT);
 
@@ -814,9 +819,9 @@
 
   for (const auto& method: interface.GetMethods()) {
     if (method->IsUserDefined()) {
-      publics.push_back(BuildMethodDecl(*method, typenames, false));
+      publics.push_back(BuildMethodDecl(*method, types, false));
     } else {
-      publics.push_back(BuildMetaMethodDecl(*method, typenames, options, false));
+      publics.push_back(BuildMetaMethodDecl(*method, types, options, false));
     }
   }
 
@@ -846,14 +851,11 @@
                     NestInNamespaces(std::move(bp_class), interface.GetSplitPackage())}};
 }
 
-unique_ptr<Document> BuildServerHeader(const AidlTypenames& /* typenames */,
+unique_ptr<Document> BuildServerHeader(const TypeNamespace& /* types */,
                                        const AidlInterface& interface, const Options& options) {
   const string i_name = ClassName(interface, ClassNames::INTERFACE);
   const string bn_name = ClassName(interface, ClassNames::SERVER);
 
-  unique_ptr<ConstructorDecl> constructor{
-      new ConstructorDecl{bn_name, ArgList{}, ConstructorDecl::IS_EXPLICIT}};
-
   unique_ptr<Declaration> on_transact{new MethodDecl{
       kAndroidStatusLiteral, "onTransact",
       ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
@@ -866,7 +868,6 @@
   vector<string> includes = {"binder/IInterface.h", HeaderFile(interface, ClassNames::RAW, false)};
 
   vector<unique_ptr<Declaration>> publics;
-  publics.push_back(std::move(constructor));
   publics.push_back(std::move(on_transact));
 
   if (options.Version() > 0) {
@@ -894,16 +895,20 @@
                     NestInNamespaces(std::move(bn_class), interface.GetSplitPackage())}};
 }
 
-unique_ptr<Document> BuildInterfaceHeader(const AidlTypenames& typenames,
+unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types,
                                           const AidlInterface& interface, const Options& options) {
   set<string> includes = {kIBinderHeader, kIInterfaceHeader, kStatusHeader, kStrongPointerHeader};
 
   for (const auto& method : interface.GetMethods()) {
     for (const auto& argument : method->GetArguments()) {
-      AddHeaders(argument->GetType(), typenames, includes);
+      const Type* type = argument->GetType().GetLanguageType<Type>();
+      type->GetHeaders(&includes);
     }
 
-    AddHeaders(method->GetType(), typenames, includes);
+    const Type* return_type = method->GetType().GetLanguageType<Type>();
+    if (return_type != nullptr) {
+      return_type->GetHeaders(&includes);
+    }
   }
 
   const string i_name = ClassName(interface, ClassNames::INTERFACE);
@@ -920,21 +925,20 @@
   }
 
   std::vector<std::unique_ptr<Declaration>> string_constants;
-  unique_ptr<Enum> int_constant_enum{new Enum{"", "int32_t", false}};
+  unique_ptr<Enum> int_constant_enum{new Enum{"", "int32_t"}};
   for (const auto& constant : interface.GetConstantDeclarations()) {
     const AidlConstantValue& value = constant->GetValue();
 
     switch (value.GetType()) {
       case AidlConstantValue::Type::STRING: {
-        std::string cppType = CppNameOf(constant->GetType(), typenames);
+        std::string cppType = constant->GetType().GetLanguageType<Type>()->CppType();
         unique_ptr<Declaration> getter(new MethodDecl("const " + cppType + "&", constant->GetName(),
                                                       {}, MethodDecl::IS_STATIC));
         string_constants.push_back(std::move(getter));
         break;
       }
-      case AidlConstantValue::Type::BOOLEAN:  // fall-through
-      case AidlConstantValue::Type::INT8:     // fall-through
-      case AidlConstantValue::Type::INT32: {
+      case AidlConstantValue::Type::INTEGRAL:
+      case AidlConstantValue::Type::HEXIDECIMAL: {
         int_constant_enum->AddValue(constant->GetName(),
                                     constant->ValueString(ConstantValueDecorator));
         break;
@@ -963,9 +967,9 @@
     for (const auto& method : interface.GetMethods()) {
       if (method->IsUserDefined()) {
         // Each method gets an enum entry and pure virtual declaration.
-        if_class->AddPublic(BuildMethodDecl(*method, typenames, true));
+        if_class->AddPublic(BuildMethodDecl(*method, types, true));
       } else {
-        if_class->AddPublic(BuildMetaMethodDecl(*method, typenames, options, true));
+        if_class->AddPublic(BuildMetaMethodDecl(*method, types, options, true));
       }
     }
   }
@@ -977,10 +981,9 @@
   vector<string> method_decls;
   for (const auto& method : interface.GetMethods()) {
     if (method->IsUserDefined()) {
-      method_decls.emplace_back(BuildMethodDecl(*method, typenames, false)->ToString());
+      method_decls.emplace_back(BuildMethodDecl(*method, types, false)->ToString());
     } else {
-      method_decls.emplace_back(
-          BuildMetaMethodDecl(*method, typenames, options, false)->ToString());
+      method_decls.emplace_back(BuildMetaMethodDecl(*method, types, options, false)->ToString());
     }
   }
 
@@ -999,45 +1002,25 @@
                     NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
 }
 
-std::unique_ptr<Document> BuildParcelHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildParcelHeader(const TypeNamespace& /*types*/,
                                             const AidlStructuredParcelable& parcel,
                                             const Options&) {
   unique_ptr<ClassDecl> parcel_class{new ClassDecl{parcel.GetName(), "::android::Parcelable"}};
 
   set<string> includes = {kStatusHeader, kParcelHeader};
-  includes.insert("tuple");
   for (const auto& variable : parcel.GetFields()) {
-    AddHeaders(variable->GetType(), typenames, includes);
+    const Type* type = variable->GetType().GetLanguageType<Type>();
+    type->GetHeaders(&includes);
   }
 
-  set<string> operators = {"<", ">", "==", ">=", "<=", "!="};
-  for (const auto& op : operators) {
-    std::ostringstream operator_code;
-    std::vector<std::string> variable_name;
-    std::vector<std::string> rhs_variable_name;
-    for (const auto& variable : parcel.GetFields()) {
-      variable_name.push_back(variable->GetName());
-      rhs_variable_name.push_back("rhs." + variable->GetName());
-    }
-
-    operator_code << "inline bool operator" << op << "(const " << parcel.GetName()
-                  << "& rhs) const {\n"
-                  << "  return "
-                  << "std::tie(" << Join(variable_name, ", ") << ")" << op << "std::tie("
-                  << Join(rhs_variable_name, ", ") << ")"
-                  << ";\n"
-                  << "}\n";
-
-    parcel_class->AddPublic(std::unique_ptr<LiteralDecl>(new LiteralDecl(operator_code.str())));
-  }
   for (const auto& variable : parcel.GetFields()) {
+    const Type* type = variable->GetType().GetLanguageType<Type>();
 
     std::ostringstream out;
-    std::string cppType = CppNameOf(variable->GetType(), typenames);
-    out << cppType.c_str() << " " << variable->GetName().c_str();
+    out << type->CppType().c_str() << " " << variable->GetName().c_str();
     if (variable->GetDefaultValue()) {
-      out << " = " << cppType.c_str() << "(" << variable->ValueString(ConstantValueDecorator)
-          << ")";
+      out << " = " << type->CppType().c_str() << "("
+          << variable->ValueString(ConstantValueDecorator) << ")";
     }
     out << ";\n";
 
@@ -1057,7 +1040,7 @@
       BuildHeaderGuard(parcel, ClassNames::BASE), vector<string>(includes.begin(), includes.end()),
       NestInNamespaces(std::move(parcel_class), parcel.GetSplitPackage())}};
 }
-std::unique_ptr<Document> BuildParcelSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildParcelSource(const TypeNamespace& /*types*/,
                                             const AidlStructuredParcelable& parcel,
                                             const Options&) {
   unique_ptr<MethodImpl> read{new MethodImpl{kAndroidStatusLiteral, parcel.GetName(),
@@ -1074,12 +1057,11 @@
       "size_t _aidl_parcelable_size = static_cast<size_t>(_aidl_parcelable_raw_size);\n");
 
   for (const auto& variable : parcel.GetFields()) {
-    string method = ParcelReadMethodOf(variable->GetType(), typenames);
+    string method = variable->GetType().GetLanguageType<Type>()->ReadFromParcelMethod();
 
     read_block->AddStatement(new Assignment(
         kAndroidStatusVarName, new MethodCall(StringPrintf("_aidl_parcel->%s", method.c_str()),
-                                              ParcelReadCastOf(variable->GetType(), typenames,
-                                                               "&" + variable->GetName()))));
+                                              ArgList("&" + variable->GetName()))));
     read_block->AddStatement(ReturnOnStatusNotOk());
     read_block->AddLiteral(StringPrintf(
         "if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) {\n"
@@ -1102,11 +1084,11 @@
       "_aidl_parcel->writeInt32(0);");
 
   for (const auto& variable : parcel.GetFields()) {
-    string method = ParcelWriteMethodOf(variable->GetType(), typenames);
+    string method = variable->GetType().GetLanguageType<Type>()->WriteToParcelMethod();
+
     write_block->AddStatement(new Assignment(
-        kAndroidStatusVarName,
-        new MethodCall(StringPrintf("_aidl_parcel->%s", method.c_str()),
-                       ParcelWriteCastOf(variable->GetType(), typenames, variable->GetName()))));
+        kAndroidStatusVarName, new MethodCall(StringPrintf("_aidl_parcel->%s", method.c_str()),
+                                              ArgList(variable->GetName()))));
     write_block->AddStatement(ReturnOnStatusNotOk());
   }
 
@@ -1122,46 +1104,26 @@
   file_decls.push_back(std::move(write));
 
   set<string> includes = {};
-  AddHeaders(parcel, includes);
+  parcel.GetLanguageType<Type>()->GetHeaders(&includes);
 
   return unique_ptr<Document>{
       new CppSource{vector<string>(includes.begin(), includes.end()),
                     NestInNamespaces(std::move(file_decls), parcel.GetSplitPackage())}};
 }
 
-std::unique_ptr<Document> BuildEnumHeader(const AidlTypenames& typenames,
-                                          const AidlEnumDeclaration& enum_decl) {
-  unique_ptr<Enum> generated_enum{
-      new Enum{enum_decl.GetName(), CppNameOf(enum_decl.GetBackingType(), typenames), true}};
-  for (const auto& enumerator : enum_decl.GetEnumerators()) {
-    generated_enum->AddValue(
-        enumerator->GetName(),
-        enumerator->ValueString(enum_decl.GetBackingType(), ConstantValueDecorator));
-  }
-
-  set<string> includes = {};
-  AddHeaders(enum_decl.GetBackingType(), typenames, includes);
-
-  return unique_ptr<Document>{
-      new CppHeader{BuildHeaderGuard(enum_decl, ClassNames::BASE),
-                    vector<string>(includes.begin(), includes.end()),
-                    NestInNamespaces(std::move(generated_enum), enum_decl.GetSplitPackage())}};
-}
-
-bool WriteHeader(const Options& options, const AidlTypenames& typenames,
-                 const AidlInterface& interface, const IoDelegate& io_delegate,
-                 ClassNames header_type) {
+bool WriteHeader(const Options& options, const TypeNamespace& types, const AidlInterface& interface,
+                 const IoDelegate& io_delegate, ClassNames header_type) {
   unique_ptr<Document> header;
   switch (header_type) {
     case ClassNames::INTERFACE:
-      header = BuildInterfaceHeader(typenames, interface, options);
+      header = BuildInterfaceHeader(types, interface, options);
       header_type = ClassNames::RAW;
       break;
     case ClassNames::CLIENT:
-      header = BuildClientHeader(typenames, interface, options);
+      header = BuildClientHeader(types, interface, options);
       break;
     case ClassNames::SERVER:
-      header = BuildServerHeader(typenames, interface, options);
+      header = BuildServerHeader(types, interface, options);
       break;
     default:
       LOG(FATAL) << "aidl internal error";
@@ -1188,19 +1150,22 @@
 using namespace internals;
 
 bool GenerateCppInterface(const string& output_file, const Options& options,
-                          const AidlTypenames& typenames, const AidlInterface& interface,
+                          const TypeNamespace& types, const AidlInterface& interface,
                           const IoDelegate& io_delegate) {
-  auto interface_src = BuildInterfaceSource(typenames, interface, options);
-  auto client_src = BuildClientSource(typenames, interface, options);
-  auto server_src = BuildServerSource(typenames, interface, options);
+  auto interface_src = BuildInterfaceSource(types, interface, options);
+  auto client_src = BuildClientSource(types, interface, options);
+  auto server_src = BuildServerSource(types, interface, options);
 
   if (!interface_src || !client_src || !server_src) {
     return false;
   }
 
-  if (!WriteHeader(options, typenames, interface, io_delegate, ClassNames::INTERFACE) ||
-      !WriteHeader(options, typenames, interface, io_delegate, ClassNames::CLIENT) ||
-      !WriteHeader(options, typenames, interface, io_delegate, ClassNames::SERVER)) {
+  if (!WriteHeader(options, types, interface, io_delegate,
+                   ClassNames::INTERFACE) ||
+      !WriteHeader(options, types, interface, io_delegate,
+                   ClassNames::CLIENT) ||
+      !WriteHeader(options, types, interface, io_delegate,
+                   ClassNames::SERVER)) {
     return false;
   }
 
@@ -1218,10 +1183,10 @@
 }
 
 bool GenerateCppParcel(const string& output_file, const Options& options,
-                       const AidlTypenames& typenames, const AidlStructuredParcelable& parcelable,
+                       const cpp::TypeNamespace& types, const AidlStructuredParcelable& parcelable,
                        const IoDelegate& io_delegate) {
-  auto header = BuildParcelHeader(typenames, parcelable, options);
-  auto source = BuildParcelSource(typenames, parcelable, options);
+  auto header = BuildParcelHeader(types, parcelable, options);
+  auto source = BuildParcelSource(types, parcelable, options);
 
   if (!header || !source) {
     return false;
@@ -1249,79 +1214,29 @@
   return true;
 }
 
-bool GenerateCppParcelDeclaration(const std::string& filename, const Options& options,
-                                  const AidlParcelable& parcelable, const IoDelegate& io_delegate) {
-  CodeWriterPtr source_writer = io_delegate.GetCodeWriter(filename);
-  *source_writer
+bool GenerateCppParcelDeclaration(const std::string& filename, const IoDelegate& io_delegate) {
+  CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
+  *code_writer
       << "// This file is intentionally left blank as placeholder for parcel declaration.\n";
-  CHECK(source_writer->Close());
-
-  // TODO(b/111362593): no unecessary files just to have consistent output with interfaces
-  const string header_path = options.OutputHeaderDir() + HeaderFile(parcelable, ClassNames::RAW);
-  unique_ptr<CodeWriter> header_writer(io_delegate.GetCodeWriter(header_path));
-  header_writer->Write("#error TODO(b/111362593) parcelables do not have headers");
-  CHECK(header_writer->Close());
-  const string bp_header = options.OutputHeaderDir() + HeaderFile(parcelable, ClassNames::CLIENT);
-  unique_ptr<CodeWriter> bp_writer(io_delegate.GetCodeWriter(bp_header));
-  bp_writer->Write("#error TODO(b/111362593) parcelables do not have bp classes");
-  CHECK(bp_writer->Close());
-  const string bn_header = options.OutputHeaderDir() + HeaderFile(parcelable, ClassNames::SERVER);
-  unique_ptr<CodeWriter> bn_writer(io_delegate.GetCodeWriter(bn_header));
-  bn_writer->Write("#error TODO(b/111362593) parcelables do not have bn classes");
-  CHECK(bn_writer->Close());
 
   return true;
 }
 
-bool GenerateCppEnumDeclaration(const std::string& filename, const Options& options,
-                                const AidlTypenames& typenames,
-                                const AidlEnumDeclaration& enum_decl,
-                                const IoDelegate& io_delegate) {
-  auto header = BuildEnumHeader(typenames, enum_decl);
-  if (!header) return false;
-
-  const string header_path = options.OutputHeaderDir() + HeaderFile(enum_decl, ClassNames::RAW);
-  unique_ptr<CodeWriter> header_writer(io_delegate.GetCodeWriter(header_path));
-  header->Write(header_writer.get());
-  CHECK(header_writer->Close());
-
-  // TODO(b/111362593): no unnecessary files just to have consistent output with interfaces
-  CodeWriterPtr source_writer = io_delegate.GetCodeWriter(filename);
-  *source_writer
-      << "// This file is intentionally left blank as placeholder for enum declaration.\n";
-  CHECK(source_writer->Close());
-  const string bp_header = options.OutputHeaderDir() + HeaderFile(enum_decl, ClassNames::CLIENT);
-  unique_ptr<CodeWriter> bp_writer(io_delegate.GetCodeWriter(bp_header));
-  bp_writer->Write("#error TODO(b/111362593) enums do not have bp classes");
-  CHECK(bp_writer->Close());
-  const string bn_header = options.OutputHeaderDir() + HeaderFile(enum_decl, ClassNames::SERVER);
-  unique_ptr<CodeWriter> bn_writer(io_delegate.GetCodeWriter(bn_header));
-  bn_writer->Write("#error TODO(b/111362593) enums do not have bn classes");
-  CHECK(bn_writer->Close());
-
-  return true;
-}
-
-bool GenerateCpp(const string& output_file, const Options& options, const AidlTypenames& typenames,
+bool GenerateCpp(const string& output_file, const Options& options, const TypeNamespace& types,
                  const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
   const AidlStructuredParcelable* parcelable = defined_type.AsStructuredParcelable();
   if (parcelable != nullptr) {
-    return GenerateCppParcel(output_file, options, typenames, *parcelable, io_delegate);
+    return GenerateCppParcel(output_file, options, types, *parcelable, io_delegate);
   }
 
   const AidlParcelable* parcelable_decl = defined_type.AsParcelable();
   if (parcelable_decl != nullptr) {
-    return GenerateCppParcelDeclaration(output_file, options, *parcelable_decl, io_delegate);
-  }
-
-  const AidlEnumDeclaration* enum_decl = defined_type.AsEnumDeclaration();
-  if (enum_decl != nullptr) {
-    return GenerateCppEnumDeclaration(output_file, options, typenames, *enum_decl, io_delegate);
+    return GenerateCppParcelDeclaration(output_file, io_delegate);
   }
 
   const AidlInterface* interface = defined_type.AsInterface();
   if (interface != nullptr) {
-    return GenerateCppInterface(output_file, options, typenames, *interface, io_delegate);
+    return GenerateCppInterface(output_file, options, types, *interface, io_delegate);
   }
 
   CHECK(false) << "Unrecognized type sent for cpp generation.";
diff --git a/generate_cpp.h b/generate_cpp.h
index 3fd7caf..9b34b96 100644
--- a/generate_cpp.h
+++ b/generate_cpp.h
@@ -24,43 +24,41 @@
 #include "aidl_to_cpp_common.h"
 #include "ast_cpp.h"
 #include "options.h"
+#include "type_cpp.h"
 
 namespace android {
 namespace aidl {
 namespace cpp {
 
-bool GenerateCpp(const string& output_file, const Options& options, const AidlTypenames& typenames,
+bool GenerateCpp(const string& output_file, const Options& options, const cpp::TypeNamespace& types,
                  const AidlDefinedType& parsed_doc, const IoDelegate& io_delegate);
 
 namespace internals {
-std::unique_ptr<Document> BuildClientSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildClientSource(const TypeNamespace& types,
                                             const AidlInterface& parsed_doc,
                                             const Options& options);
-std::unique_ptr<Document> BuildServerSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildServerSource(const TypeNamespace& types,
                                             const AidlInterface& parsed_doc,
                                             const Options& options);
-std::unique_ptr<Document> BuildInterfaceSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildInterfaceSource(const TypeNamespace& types,
                                                const AidlInterface& parsed_doc,
                                                const Options& options);
-std::unique_ptr<Document> BuildClientHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildClientHeader(const TypeNamespace& types,
                                             const AidlInterface& parsed_doc,
                                             const Options& options);
-std::unique_ptr<Document> BuildServerHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildServerHeader(const TypeNamespace& types,
                                             const AidlInterface& parsed_doc,
                                             const Options& options);
-std::unique_ptr<Document> BuildInterfaceHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types,
                                                const AidlInterface& parsed_doc,
                                                const Options& options);
 
-std::unique_ptr<Document> BuildParcelHeader(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildParcelHeader(const TypeNamespace& types,
                                             const AidlStructuredParcelable& parsed_doc,
                                             const Options& options);
-std::unique_ptr<Document> BuildParcelSource(const AidlTypenames& typenames,
+std::unique_ptr<Document> BuildParcelSource(const TypeNamespace& types,
                                             const AidlStructuredParcelable& parsed_doc,
                                             const Options& options);
-
-std::unique_ptr<Document> BuildEnumHeader(const AidlTypenames& typenames,
-                                          const AidlEnumDeclaration& parsed_doc);
 }
 }  // namespace cpp
 }  // namespace aidl
diff --git a/generate_cpp_unittest.cpp b/generate_cpp_unittest.cpp
index fd6c9f0..a9ba8cd 100644
--- a/generate_cpp_unittest.cpp
+++ b/generate_cpp_unittest.cpp
@@ -27,6 +27,7 @@
 #include "os.h"
 #include "tests/fake_io_delegate.h"
 #include "tests/test_util.h"
+#include "type_cpp.h"
 
 using ::android::aidl::test::FakeIoDelegate;
 using ::android::base::StringPrintf;
@@ -726,7 +727,7 @@
 )";
 
 const char kExpectedComplexTypeServerHeaderOutput[] =
-    R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_
 #define AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_
 
 #include <binder/IInterface.h>
@@ -738,7 +739,6 @@
 
 class BnComplexTypeInterface : public ::android::BnInterface<IComplexTypeInterface> {
 public:
-  explicit BnComplexTypeInterface();
   ::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) override;
 };  // class BnComplexTypeInterface
 
@@ -752,17 +752,11 @@
 const char kExpectedComplexTypeServerSourceOutput[] =
     R"(#include <android/os/BnComplexTypeInterface.h>
 #include <binder/Parcel.h>
-#include <binder/Stability.h>
 
 namespace android {
 
 namespace os {
 
-BnComplexTypeInterface::BnComplexTypeInterface()
-{
-  ::android::internal::Stability::markCompilationUnit(this);
-}
-
 ::android::status_t BnComplexTypeInterface::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
   ::android::status_t _aidl_ret_status = ::android::OK;
   switch (_aidl_code) {
@@ -1005,17 +999,11 @@
 const char kExpectedComplexTypeServerWithTraceSourceOutput[] =
     R"(#include <android/os/BnComplexTypeInterface.h>
 #include <binder/Parcel.h>
-#include <binder/Stability.h>
 
 namespace android {
 
 namespace os {
 
-BnComplexTypeInterface::BnComplexTypeInterface()
-{
-  ::android::internal::Stability::markCompilationUnit(this);
-}
-
 ::android::status_t BnComplexTypeInterface::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
   ::android::status_t _aidl_ret_status = ::android::OK;
   switch (_aidl_code) {
@@ -1378,85 +1366,13 @@
 }  // namespace android
 )";
 
-const string kEnumAIDL = R"(package android.os;
-enum TestEnum {
-  ZERO,
-  ONE,
-  THREE = 3,
-  FOUR = 3 + 1,
-  FIVE,
-  SIX,
-  SEVEN,
-  EIGHT = 16 / 2,
-  NINE,
-  TEN,
-})";
-
-const char kExpectedEnumHeaderOutput[] =
-    R"(#ifndef AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-#define AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-
-#include <cstdint>
-
-namespace android {
-
-namespace os {
-
-enum class TestEnum : int8_t {
-  ZERO = 0,
-  ONE = 1,
-  THREE = 3,
-  FOUR = 4,
-  FIVE = 5,
-  SIX = 6,
-  SEVEN = 7,
-  EIGHT = 8,
-  NINE = 9,
-  TEN = 10,
-};
-
-}  // namespace os
-
-}  // namespace android
-
-#endif  // AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-)";
-
-const string kEnumWithBackingTypeAIDL = R"(package android.os;
-@Backing(type="long")
-enum TestEnum {
-  FOO = 1,
-  BAR = 2,
-})";
-
-const char kExpectedEnumWithBackingTypeHeaderOutput[] =
-    R"(#ifndef AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-#define AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-
-#include <cstdint>
-
-namespace android {
-
-namespace os {
-
-enum class TestEnum : int64_t {
-  FOO = 1L,
-  BAR = 2L,
-};
-
-}  // namespace os
-
-}  // namespace android
-
-#endif  // AIDL_GENERATED_ANDROID_OS_TEST_ENUM_H_
-)";
-
 }  // namespace
 
 class ASTTest : public ::testing::Test {
  protected:
   ASTTest(const string& cmdline, const string& file_contents)
       : options_(Options::From(cmdline)), file_contents_(file_contents) {
+    types_.Init();
   }
 
   AidlInterface* ParseSingleInterface() {
@@ -1466,7 +1382,7 @@
     vector<string> imported_files;
     ImportResolver import_resolver{io_delegate_, options_.InputFiles().at(0), {"."}, {}};
     AidlError err = ::android::aidl::internals::load_and_validate_aidl(
-        options_.InputFiles().front(), options_, io_delegate_, &typenames_, &defined_types,
+        options_.InputFiles().front(), options_, io_delegate_, &types_, &defined_types,
         &imported_files);
 
     if (err != AidlError::OK) {
@@ -1479,25 +1395,6 @@
     return defined_types.front()->AsInterface();
   }
 
-  AidlEnumDeclaration* ParseSingleEnumDeclaration() {
-    io_delegate_.SetFileContents(options_.InputFiles().at(0), file_contents_);
-
-    vector<AidlDefinedType*> defined_types;
-    vector<string> imported_files;
-    AidlError err = ::android::aidl::internals::load_and_validate_aidl(
-        options_.InputFiles().front(), options_, io_delegate_, &typenames_, &defined_types,
-        &imported_files);
-
-    if (err != AidlError::OK) {
-      return nullptr;
-    }
-
-    EXPECT_EQ(1ul, defined_types.size());
-    EXPECT_NE(nullptr, defined_types.front()->AsEnumDeclaration());
-
-    return defined_types.front()->AsEnumDeclaration();
-  }
-
   void Compare(Document* doc, const char* expected) {
     string output;
     doc->Write(CodeWriter::ForString(&output).get());
@@ -1513,7 +1410,7 @@
   const Options options_;
   const string file_contents_;
   FakeIoDelegate io_delegate_;
-  AidlTypenames typenames_;
+  TypeNamespace types_;
 };
 
 class ComplexTypeInterfaceASTTest : public ASTTest {
@@ -1529,42 +1426,42 @@
 TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientHeader) {
   AidlInterface* interface = ParseSingleInterface();
   ASSERT_NE(interface, nullptr);
-  unique_ptr<Document> doc = internals::BuildClientHeader(typenames_, *interface, options_);
+  unique_ptr<Document> doc = internals::BuildClientHeader(types_, *interface, options_);
   Compare(doc.get(), kExpectedComplexTypeClientHeaderOutput);
 }
 
 TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSource) {
   AidlInterface* interface = ParseSingleInterface();
   ASSERT_NE(interface, nullptr);
-  unique_ptr<Document> doc = internals::BuildClientSource(typenames_, *interface, options_);
+  unique_ptr<Document> doc = internals::BuildClientSource(types_, *interface, options_);
   Compare(doc.get(), kExpectedComplexTypeClientSourceOutput);
 }
 
 TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerHeader) {
   AidlInterface* interface = ParseSingleInterface();
   ASSERT_NE(interface, nullptr);
-  unique_ptr<Document> doc = internals::BuildServerHeader(typenames_, *interface, options_);
+  unique_ptr<Document> doc = internals::BuildServerHeader(types_, *interface, options_);
   Compare(doc.get(), kExpectedComplexTypeServerHeaderOutput);
 }
 
 TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSource) {
   AidlInterface* interface = ParseSingleInterface();
   ASSERT_NE(interface, nullptr);
-  unique_ptr<Document> doc = internals::BuildServerSource(typenames_, *interface, options_);
+  unique_ptr<Document> doc = internals::BuildServerSource(types_, *interface, options_);
   Compare(doc.get(), kExpectedComplexTypeServerSourceOutput);
 }
 
 TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceHeader) {
   AidlInterface* interface = ParseSingleInterface();
   ASSERT_NE(interface, nullptr);
-  unique_ptr<Document> doc = internals::BuildInterfaceHeader(typenames_, *interface, options_);
+  unique_ptr<Document> doc = internals::BuildInterfaceHeader(types_, *interface, options_);
   Compare(doc.get(), kExpectedComplexTypeInterfaceHeaderOutput);
 }
 
 TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceSource) {
   AidlInterface* interface = ParseSingleInterface();
   ASSERT_NE(interface, nullptr);
-  unique_ptr<Document> doc = internals::BuildInterfaceSource(typenames_, *interface, options_);
+  unique_ptr<Document> doc = internals::BuildInterfaceSource(types_, *interface, options_);
   Compare(doc.get(), kExpectedComplexTypeInterfaceSourceOutput);
 }
 
@@ -1580,14 +1477,14 @@
 TEST_F(ComplexTypeInterfaceASTTestWithTrace, GeneratesClientSource) {
   AidlInterface* interface = ParseSingleInterface();
   ASSERT_NE(interface, nullptr);
-  unique_ptr<Document> doc = internals::BuildClientSource(typenames_, *interface, options_);
+  unique_ptr<Document> doc = internals::BuildClientSource(types_, *interface, options_);
   Compare(doc.get(), kExpectedComplexTypeClientWithTraceSourceOutput);
 }
 
 TEST_F(ComplexTypeInterfaceASTTestWithTrace, GeneratesServerSource) {
   AidlInterface* interface = ParseSingleInterface();
   ASSERT_NE(interface, nullptr);
-  unique_ptr<Document> doc = internals::BuildServerSource(typenames_, *interface, options_);
+  unique_ptr<Document> doc = internals::BuildServerSource(types_, *interface, options_);
   Compare(doc.get(), kExpectedComplexTypeServerWithTraceSourceOutput);
 }
 
@@ -1611,7 +1508,7 @@
   // Confirm that this is working correctly without I/O problems.
   AidlInterface* interface = ParseSingleInterface();
   ASSERT_NE(interface, nullptr);
-  ASSERT_TRUE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
+  ASSERT_TRUE(GenerateCpp(options_.OutputFile(), options_, types_, *interface, io_delegate_));
 }
 
 TEST_F(IoErrorHandlingTest, HandlesBadHeaderWrite) {
@@ -1624,7 +1521,7 @@
       StringPrintf("%s%c%s", kHeaderDir, OS_PATH_SEPARATOR,
                    kInterfaceHeaderRelPath);
   io_delegate_.AddBrokenFilePath(header_path);
-  ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
+  ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, types_, *interface, io_delegate_));
   // We should never attempt to write the C++ file if we fail writing headers.
   ASSERT_FALSE(io_delegate_.GetWrittenContents(kOutputPath, nullptr));
   // We should remove partial results.
@@ -1638,36 +1535,11 @@
 
   // Simulate issues closing the cpp file.
   io_delegate_.AddBrokenFilePath(kOutputPath);
-  ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
+  ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, types_, *interface, io_delegate_));
   // We should remove partial results.
   ASSERT_TRUE(io_delegate_.PathWasRemoved(kOutputPath));
 }
 
-class EnumASTTest : public ASTTest {
- public:
-  EnumASTTest() : ASTTest("aidl --lang=cpp -I . -o out android/os/TestEnum.aidl", kEnumAIDL) {}
-};
-
-TEST_F(EnumASTTest, GeneratesEnumHeader) {
-  AidlEnumDeclaration* enum_decl = ParseSingleEnumDeclaration();
-  ASSERT_NE(enum_decl, nullptr);
-  unique_ptr<Document> doc = internals::BuildEnumHeader(typenames_, *enum_decl);
-  Compare(doc.get(), kExpectedEnumHeaderOutput);
-}
-
-class EnumWithBackingTypeASTTest : public ASTTest {
- public:
-  EnumWithBackingTypeASTTest()
-      : ASTTest("aidl --lang=cpp -I . -o out android/os/TestEnum.aidl", kEnumWithBackingTypeAIDL) {}
-};
-
-TEST_F(EnumWithBackingTypeASTTest, GeneratesEnumHeader) {
-  AidlEnumDeclaration* enum_decl = ParseSingleEnumDeclaration();
-  ASSERT_NE(enum_decl, nullptr);
-  unique_ptr<Document> doc = internals::BuildEnumHeader(typenames_, *enum_decl);
-  Compare(doc.get(), kExpectedEnumWithBackingTypeHeaderOutput);
-}
-
 }  // namespace cpp
 }  // namespace aidl
 }  // namespace android
diff --git a/generate_java.cpp b/generate_java.cpp
index 966ed58..0d96203 100644
--- a/generate_java.cpp
+++ b/generate_java.cpp
@@ -19,7 +19,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <map>
 #include <memory>
 #include <sstream>
 
@@ -27,7 +26,7 @@
 
 #include "aidl_to_java.h"
 #include "code_writer.h"
-#include "logging.h"
+#include "type_java.h"
 
 using std::unique_ptr;
 using ::android::aidl::java::Variable;
@@ -38,12 +37,12 @@
 namespace java {
 
 bool generate_java_interface(const string& filename, const AidlInterface* iface,
-                             const AidlTypenames& typenames, const IoDelegate& io_delegate,
+                             JavaTypeNamespace* types, const IoDelegate& io_delegate,
                              const Options& options) {
-  auto cl = generate_binder_interface_class(iface, typenames, options);
+  Class* cl = generate_binder_interface_class(iface, types, options);
 
-  std::unique_ptr<Document> document =
-      std::make_unique<Document>("" /* no comment */, iface->GetPackage(), std::move(cl));
+  Document* document =
+      new Document("" /* no comment */, iface->GetPackage(), unique_ptr<Class>(cl));
 
   CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
   document->Write(code_writer.get());
@@ -52,11 +51,11 @@
 }
 
 bool generate_java_parcel(const std::string& filename, const AidlStructuredParcelable* parcel,
-                          const AidlTypenames& typenames, const IoDelegate& io_delegate) {
-  auto cl = generate_parcel_class(parcel, typenames);
+                          AidlTypenames& typenames, const IoDelegate& io_delegate) {
+  Class* cl = generate_parcel_class(parcel, typenames);
 
-  std::unique_ptr<Document> document =
-      std::make_unique<Document>("" /* no comment */, parcel->GetPackage(), std::move(cl));
+  Document* document =
+      new Document("" /* no comment */, parcel->GetPackage(), unique_ptr<Class>(cl));
 
   CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
   document->Write(code_writer.get());
@@ -64,38 +63,26 @@
   return true;
 }
 
-bool generate_java_enum_declaration(const std::string& filename,
-                                    const AidlEnumDeclaration* enum_decl,
-                                    const AidlTypenames& typenames, const IoDelegate& io_delegate) {
-  CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
-  generate_enum(code_writer, enum_decl, typenames);
-  return true;
-}
-
 bool generate_java(const std::string& filename, const AidlDefinedType* defined_type,
-                   const AidlTypenames& typenames, const IoDelegate& io_delegate,
+                   JavaTypeNamespace* types, const IoDelegate& io_delegate,
                    const Options& options) {
-  if (const AidlStructuredParcelable* parcelable = defined_type->AsStructuredParcelable();
-      parcelable != nullptr) {
-    return generate_java_parcel(filename, parcelable, typenames, io_delegate);
+  const AidlStructuredParcelable* parcelable = defined_type->AsStructuredParcelable();
+  if (parcelable != nullptr) {
+    return generate_java_parcel(filename, parcelable, types->typenames_, io_delegate);
   }
 
-  if (const AidlEnumDeclaration* enum_decl = defined_type->AsEnumDeclaration();
-      enum_decl != nullptr) {
-    return generate_java_enum_declaration(filename, enum_decl, typenames, io_delegate);
+  const AidlInterface* interface = defined_type->AsInterface();
+  if (interface != nullptr) {
+    return generate_java_interface(filename, interface, types, io_delegate, options);
   }
 
-  if (const AidlInterface* interface = defined_type->AsInterface(); interface != nullptr) {
-    return generate_java_interface(filename, interface, typenames, io_delegate, options);
-  }
-
-  CHECK(false) << "Unrecognized type sent for java generation.";
+  CHECK(false) << "Unrecognized type sent for cpp generation.";
   return false;
 }
 
-std::unique_ptr<android::aidl::java::Class> generate_parcel_class(
-    const AidlStructuredParcelable* parcel, const AidlTypenames& typenames) {
-  auto parcel_class = std::make_unique<Class>();
+android::aidl::java::Class* generate_parcel_class(const AidlStructuredParcelable* parcel,
+                                                  AidlTypenames& typenames) {
+  Class* parcel_class = new Class;
   parcel_class->comment = parcel->GetComments();
   parcel_class->modifiers = PUBLIC;
   parcel_class->what = Class::CLASS;
@@ -104,18 +91,20 @@
   parcel_class->annotations = generate_java_annotations(*parcel);
 
   for (const auto& variable : parcel->GetFields()) {
+    const Type* type = variable->GetType().GetLanguageType<Type>();
+
     std::ostringstream out;
     out << variable->GetType().GetComments() << "\n";
     for (const auto& a : generate_java_annotations(variable->GetType())) {
       out << a << "\n";
     }
-    out << "public " << JavaSignatureOf(variable->GetType(), typenames) << " "
+    out << "public " << type->JavaType() << (variable->GetType().IsArray() ? "[]" : "") << " "
         << variable->GetName();
     if (variable->GetDefaultValue()) {
-      out << " = " << variable->ValueString(ConstantValueDecorator);
+      out << " = " << variable->ValueString(AidlConstantValueDecorator);
     }
     out << ";\n";
-    parcel_class->elements.push_back(std::make_shared<LiteralClassElement>(out.str()));
+    parcel_class->elements.push_back(new LiteralClassElement(out.str()));
   }
 
   std::ostringstream out;
@@ -133,23 +122,23 @@
   out << "    return new " << parcel->GetName() << "[_aidl_size];\n";
   out << "  }\n";
   out << "};\n";
-  parcel_class->elements.push_back(std::make_shared<LiteralClassElement>(out.str()));
+  parcel_class->elements.push_back(new LiteralClassElement(out.str()));
 
-  auto flag_variable = std::make_shared<Variable>("int", "_aidl_flag");
-  auto parcel_variable = std::make_shared<Variable>("android.os.Parcel", "_aidl_parcel");
+  Variable* flag_variable = new Variable("int", "_aidl_flag");
+  Variable* parcel_variable = new Variable("android.os.Parcel", "_aidl_parcel");
 
-  auto write_method = std::make_shared<Method>();
+  Method* write_method = new Method;
   write_method->modifiers = PUBLIC | OVERRIDE | FINAL;
   write_method->returnType = "void";
   write_method->name = "writeToParcel";
   write_method->parameters.push_back(parcel_variable);
   write_method->parameters.push_back(flag_variable);
-  write_method->statements = std::make_shared<StatementBlock>();
+  write_method->statements = new StatementBlock();
 
   out.str("");
   out << "int _aidl_start_pos = _aidl_parcel.dataPosition();\n"
       << "_aidl_parcel.writeInt(0);\n";
-  write_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
+  write_method->statements->Add(new LiteralStatement(out.str()));
 
   for (const auto& field : parcel->GetFields()) {
     string code;
@@ -158,13 +147,13 @@
         .writer = *(writer.get()),
         .typenames = typenames,
         .type = field->GetType(),
-        .parcel = parcel_variable->name,
         .var = field->GetName(),
+        .parcel = parcel_variable->name,
         .is_return_value = false,
     };
     WriteToParcelFor(context);
     writer->Close();
-    write_method->statements->Add(std::make_shared<LiteralStatement>(code));
+    write_method->statements->Add(new LiteralStatement(code));
   }
 
   out.str("");
@@ -173,16 +162,16 @@
       << "_aidl_parcel.writeInt(_aidl_end_pos - _aidl_start_pos);\n"
       << "_aidl_parcel.setDataPosition(_aidl_end_pos);\n";
 
-  write_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
+  write_method->statements->Add(new LiteralStatement(out.str()));
 
   parcel_class->elements.push_back(write_method);
 
-  auto read_method = std::make_shared<Method>();
+  Method* read_method = new Method;
   read_method->modifiers = PUBLIC | FINAL;
   read_method->returnType = "void";
   read_method->name = "readFromParcel";
   read_method->parameters.push_back(parcel_variable);
-  read_method->statements = std::make_shared<StatementBlock>();
+  read_method->statements = new StatementBlock();
 
   out.str("");
   out << "int _aidl_start_pos = _aidl_parcel.dataPosition();\n"
@@ -190,12 +179,12 @@
       << "if (_aidl_parcelable_size < 0) return;\n"
       << "try {\n";
 
-  read_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
+  read_method->statements->Add(new LiteralStatement(out.str()));
 
   out.str("");
   out << "  if (_aidl_parcel.dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) return;\n";
 
-  std::shared_ptr<LiteralStatement> sizeCheck = nullptr;
+  LiteralStatement* sizeCheck = nullptr;
   // keep this across different fields in order to create the classloader
   // at most once.
   bool is_classloader_created = false;
@@ -206,15 +195,15 @@
         .writer = *(writer.get()),
         .typenames = typenames,
         .type = field->GetType(),
-        .parcel = parcel_variable->name,
         .var = field->GetName(),
+        .parcel = parcel_variable->name,
         .is_classloader_created = &is_classloader_created,
     };
     context.writer.Indent();
     CreateFromParcelFor(context);
     writer->Close();
-    read_method->statements->Add(std::make_shared<LiteralStatement>(code));
-    if (!sizeCheck) sizeCheck = std::make_shared<LiteralStatement>(out.str());
+    read_method->statements->Add(new LiteralStatement(code));
+    if (!sizeCheck) sizeCheck = new LiteralStatement(out.str());
     read_method->statements->Add(sizeCheck);
   }
 
@@ -223,67 +212,25 @@
       << "  _aidl_parcel.setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n"
       << "}\n";
 
-  read_method->statements->Add(std::make_shared<LiteralStatement>(out.str()));
+  read_method->statements->Add(new LiteralStatement(out.str()));
 
   parcel_class->elements.push_back(read_method);
 
-  auto describe_contents_method = std::make_shared<Method>();
+  Method* describe_contents_method = new Method;
   describe_contents_method->modifiers = PUBLIC | OVERRIDE;
   describe_contents_method->returnType = "int";
   describe_contents_method->name = "describeContents";
-  describe_contents_method->statements = std::make_shared<StatementBlock>();
-  describe_contents_method->statements->Add(std::make_shared<LiteralStatement>("return 0;\n"));
+  describe_contents_method->statements = new StatementBlock();
+  describe_contents_method->statements->Add(new LiteralStatement("return 0;\n"));
   parcel_class->elements.push_back(describe_contents_method);
 
   return parcel_class;
 }
 
-void generate_enum(const CodeWriterPtr& code_writer, const AidlEnumDeclaration* enum_decl,
-                   const AidlTypenames& typenames) {
-  code_writer->Write(
-      "/*\n"
-      " * This file is auto-generated.  DO NOT MODIFY.\n"
-      " */\n");
-
-  code_writer->Write("package %s;\n", enum_decl->GetPackage().c_str());
-  code_writer->Write("%s\n", enum_decl->GetComments().c_str());
-  for (const std::string& annotation : generate_java_annotations(*enum_decl)) {
-    code_writer->Write(annotation.c_str());
-  }
-  code_writer->Write("public @interface %s {\n", enum_decl->GetName().c_str());
-  code_writer->Indent();
-  for (const auto& enumerator : enum_decl->GetEnumerators()) {
-    code_writer->Write(enumerator->GetComments().c_str());
-    code_writer->Write(
-        "public static final %s %s = %s;\n",
-        JavaSignatureOf(enum_decl->GetBackingType(), typenames).c_str(),
-        enumerator->GetName().c_str(),
-        enumerator->ValueString(enum_decl->GetBackingType(), ConstantValueDecorator).c_str());
-  }
-  code_writer->Dedent();
-  code_writer->Write("}\n");
-}
-
-std::string generate_java_annotation_parameters(const AidlAnnotation& a) {
-  const std::map<std::string, std::string> params = a.AnnotationParams(ConstantValueDecorator);
-  if (params.empty()) {
-    return "";
-  }
-  std::vector<string> parameters_decl;
-  for (const auto& name_and_param : params) {
-    const std::string& param_name = name_and_param.first;
-    const std::string& param_value = name_and_param.second;
-    parameters_decl.push_back(param_name + " = " + param_value);
-  }
-  return "(" + base::Join(parameters_decl, ", ") + ")";
-}
-
 std::vector<std::string> generate_java_annotations(const AidlAnnotatable& a) {
   std::vector<std::string> result;
-  const AidlAnnotation* unsupported_app_usage = a.UnsupportedAppUsage();
-  if (unsupported_app_usage != nullptr) {
-    result.emplace_back("@dalvik.annotation.compat.UnsupportedAppUsage" +
-                        generate_java_annotation_parameters(*unsupported_app_usage));
+  if (a.IsUnsupportedAppUsage()) {
+    result.emplace_back("@android.annotation.UnsupportedAppUsage");
   }
   if (a.IsSystemApi()) {
     result.emplace_back("@android.annotation.SystemApi");
@@ -292,5 +239,5 @@
 }
 
 }  // namespace java
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/generate_java.h b/generate_java.h
index d2c8a6d..f2cc7fa 100644
--- a/generate_java.h
+++ b/generate_java.h
@@ -20,6 +20,7 @@
 #include "ast_java.h"
 #include "io_delegate.h"
 #include "options.h"
+#include "type_java.h"
 
 #include <string>
 
@@ -28,20 +29,18 @@
 namespace java {
 
 bool generate_java(const std::string& filename, const AidlDefinedType* iface,
-                   const AidlTypenames& typenames, const IoDelegate& io_delegate,
+                   java::JavaTypeNamespace* types, const IoDelegate& io_delegate,
                    const Options& options);
 
-std::unique_ptr<android::aidl::java::Class> generate_binder_interface_class(
-    const AidlInterface* iface, const AidlTypenames& typenames, const Options& options);
+android::aidl::java::Class* generate_binder_interface_class(const AidlInterface* iface,
+                                                            java::JavaTypeNamespace* types,
+                                                            const Options& options);
 
-std::unique_ptr<android::aidl::java::Class> generate_parcel_class(
-    const AidlStructuredParcelable* parcel, const AidlTypenames& typenames);
-
-void generate_enum(const CodeWriterPtr& code_writer, const AidlEnumDeclaration* enum_decl,
-                   const AidlTypenames& typenames);
+android::aidl::java::Class* generate_parcel_class(const AidlStructuredParcelable* parcel,
+                                                  AidlTypenames& typenames);
 
 std::vector<std::string> generate_java_annotations(const AidlAnnotatable& a);
 
 }  // namespace java
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/generate_java_binder.cpp b/generate_java_binder.cpp
index b791241..8ced119 100644
--- a/generate_java_binder.cpp
+++ b/generate_java_binder.cpp
@@ -17,8 +17,8 @@
 #include "aidl.h"
 #include "aidl_to_java.h"
 #include "generate_java.h"
-#include "logging.h"
 #include "options.h"
+#include "type_java.h"
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -47,20 +47,20 @@
 class VariableFactory {
  public:
   using Variable = ::android::aidl::java::Variable;
+  using Type = ::android::aidl::java::Type;
 
   explicit VariableFactory(const std::string& base) : base_(base), index_(0) {}
-  std::shared_ptr<Variable> Get(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
-    auto v = std::make_shared<Variable>(JavaSignatureOf(type, typenames),
-                                        StringPrintf("%s%d", base_.c_str(), index_));
+  Variable* Get(const Type* type) {
+    Variable* v = new Variable(type->JavaType(), StringPrintf("%s%d", base_.c_str(), index_));
     vars_.push_back(v);
     index_++;
     return v;
   }
 
-  std::shared_ptr<Variable> Get(int index) { return vars_[index]; }
+  Variable* Get(int index) { return vars_[index]; }
 
  private:
-  std::vector<std::shared_ptr<Variable>> vars_;
+  std::vector<Variable*> vars_;
   std::string base_;
   int index_;
 
@@ -70,16 +70,17 @@
 // =================================================
 class StubClass : public Class {
  public:
-  StubClass(const AidlInterface* interfaceType, const Options& options);
+  StubClass(const Type* type, const InterfaceType* interfaceType, JavaTypeNamespace* types,
+            const Options& options);
   ~StubClass() override = default;
 
-  std::shared_ptr<Variable> transact_code;
-  std::shared_ptr<Variable> transact_data;
-  std::shared_ptr<Variable> transact_reply;
-  std::shared_ptr<Variable> transact_flags;
-  std::shared_ptr<SwitchStatement> transact_switch;
-  std::shared_ptr<StatementBlock> transact_statements;
-  std::shared_ptr<SwitchStatement> code_to_method_name_switch;
+  Variable* transact_code;
+  Variable* transact_data;
+  Variable* transact_reply;
+  Variable* transact_flags;
+  SwitchStatement* transact_switch;
+  StatementBlock* transact_statements;
+  SwitchStatement* code_to_method_name_switch;
 
   // Where onTransact cases should be generated as separate methods.
   bool transact_outline;
@@ -91,18 +92,21 @@
   // Finish generation. This will add a default case to the switch.
   void finish();
 
-  std::shared_ptr<Expression> get_transact_descriptor(const AidlMethod* method);
+  Expression* get_transact_descriptor(const JavaTypeNamespace* types,
+                                      const AidlMethod* method);
 
  private:
-  void make_as_interface(const AidlInterface* interfaceType);
+  void make_as_interface(const InterfaceType* interfaceType,
+                         JavaTypeNamespace* types);
 
-  std::shared_ptr<Variable> transact_descriptor;
+  Variable* transact_descriptor;
   const Options& options_;
 
   DISALLOW_COPY_AND_ASSIGN(StubClass);
 };
 
-StubClass::StubClass(const AidlInterface* interfaceType, const Options& options)
+StubClass::StubClass(const Type* type, const InterfaceType* interfaceType, JavaTypeNamespace* types,
+                     const Options& options)
     : Class(), options_(options) {
   transact_descriptor = nullptr;
   transact_outline = false;
@@ -111,100 +115,97 @@
   this->comment = "/** Local-side IPC implementation stub class. */";
   this->modifiers = PUBLIC | ABSTRACT | STATIC;
   this->what = Class::CLASS;
-  this->type = interfaceType->GetCanonicalName() + ".Stub";
-  this->extends = "android.os.Binder";
-  this->interfaces.push_back(interfaceType->GetCanonicalName());
+  this->type = type->JavaType();
+  this->extends = types->BinderNativeType()->JavaType();
+  this->interfaces.push_back(interfaceType->JavaType());
 
   // descriptor
-  auto descriptor = std::make_shared<Field>(
-      STATIC | FINAL | PRIVATE, std::make_shared<Variable>("java.lang.String", "DESCRIPTOR"));
-  descriptor->value = "\"" + interfaceType->GetCanonicalName() + "\"";
+  Field* descriptor = new Field(STATIC | FINAL | PRIVATE,
+                                new Variable(types->StringType()->JavaType(), "DESCRIPTOR"));
+  descriptor->value = "\"" + interfaceType->JavaType() + "\"";
   this->elements.push_back(descriptor);
 
   // ctor
-  auto ctor = std::make_shared<Method>();
+  Method* ctor = new Method;
   ctor->modifiers = PUBLIC;
   ctor->comment =
       "/** Construct the stub at attach it to the "
       "interface. */";
   ctor->name = "Stub";
-  ctor->statements = std::make_shared<StatementBlock>();
-  auto attach = std::make_shared<MethodCall>(
-      THIS_VALUE, "attachInterface",
-      std::vector<std::shared_ptr<Expression>>{THIS_VALUE,
-                                               std::make_shared<LiteralExpression>("DESCRIPTOR")});
+  ctor->statements = new StatementBlock;
+  MethodCall* attach =
+      new MethodCall(THIS_VALUE, "attachInterface", 2, THIS_VALUE,
+                     new LiteralExpression("DESCRIPTOR"));
   ctor->statements->Add(attach);
   this->elements.push_back(ctor);
 
   // asInterface
-  make_as_interface(interfaceType);
+  make_as_interface(interfaceType, types);
 
   // asBinder
-  auto asBinder = std::make_shared<Method>();
+  Method* asBinder = new Method;
   asBinder->modifiers = PUBLIC | OVERRIDE;
-  asBinder->returnType = "android.os.IBinder";
+  asBinder->returnType = types->IBinderType()->JavaType();
   asBinder->name = "asBinder";
-  asBinder->statements = std::make_shared<StatementBlock>();
-  asBinder->statements->Add(std::make_shared<ReturnStatement>(THIS_VALUE));
+  asBinder->statements = new StatementBlock;
+  asBinder->statements->Add(new ReturnStatement(THIS_VALUE));
   this->elements.push_back(asBinder);
 
   if (options_.GenTransactionNames()) {
     // getDefaultTransactionName
-    auto getDefaultTransactionName = std::make_shared<Method>();
+    Method* getDefaultTransactionName = new Method;
     getDefaultTransactionName->comment = "/** @hide */";
     getDefaultTransactionName->modifiers = PUBLIC | STATIC;
-    getDefaultTransactionName->returnType = "java.lang.String";
+    getDefaultTransactionName->returnType = types->StringType()->JavaType();
     getDefaultTransactionName->name = "getDefaultTransactionName";
-    auto code = std::make_shared<Variable>("int", "transactionCode");
+    Variable* code = new Variable(types->IntType()->JavaType(), "transactionCode");
     getDefaultTransactionName->parameters.push_back(code);
-    getDefaultTransactionName->statements = std::make_shared<StatementBlock>();
-    this->code_to_method_name_switch = std::make_shared<SwitchStatement>(code);
+    getDefaultTransactionName->statements = new StatementBlock;
+    this->code_to_method_name_switch = new SwitchStatement(code);
     getDefaultTransactionName->statements->Add(this->code_to_method_name_switch);
     this->elements.push_back(getDefaultTransactionName);
 
     // getTransactionName
-    auto getTransactionName = std::make_shared<Method>();
+    Method* getTransactionName = new Method;
     getTransactionName->comment = "/** @hide */";
     getTransactionName->modifiers = PUBLIC;
-    getTransactionName->returnType = "java.lang.String";
+    getTransactionName->returnType = types->StringType()->JavaType();
     getTransactionName->name = "getTransactionName";
-    auto code2 = std::make_shared<Variable>("int", "transactionCode");
+    Variable* code2 = new Variable(types->IntType()->JavaType(), "transactionCode");
     getTransactionName->parameters.push_back(code2);
-    getTransactionName->statements = std::make_shared<StatementBlock>();
-    getTransactionName->statements->Add(std::make_shared<ReturnStatement>(
-        std::make_shared<MethodCall>(THIS_VALUE, "getDefaultTransactionName",
-                                     std::vector<std::shared_ptr<Expression>>{code2})));
+    getTransactionName->statements = new StatementBlock;
+    getTransactionName->statements->Add(
+        new ReturnStatement(new MethodCall(THIS_VALUE, "getDefaultTransactionName", 1, code2)));
     this->elements.push_back(getTransactionName);
   }
 
   // onTransact
-  this->transact_code = std::make_shared<Variable>("int", "code");
-  this->transact_data = std::make_shared<Variable>("android.os.Parcel", "data");
-  this->transact_reply = std::make_shared<Variable>("android.os.Parcel", "reply");
-  this->transact_flags = std::make_shared<Variable>("int", "flags");
-  auto onTransact = std::make_shared<Method>();
+  this->transact_code = new Variable(types->IntType()->JavaType(), "code");
+  this->transact_data = new Variable(types->ParcelType()->JavaType(), "data");
+  this->transact_reply = new Variable(types->ParcelType()->JavaType(), "reply");
+  this->transact_flags = new Variable(types->IntType()->JavaType(), "flags");
+  Method* onTransact = new Method;
   onTransact->modifiers = PUBLIC | OVERRIDE;
-  onTransact->returnType = "boolean";
+  onTransact->returnType = types->BoolType()->JavaType();
   onTransact->name = "onTransact";
   onTransact->parameters.push_back(this->transact_code);
   onTransact->parameters.push_back(this->transact_data);
   onTransact->parameters.push_back(this->transact_reply);
   onTransact->parameters.push_back(this->transact_flags);
-  onTransact->statements = std::make_shared<StatementBlock>();
+  onTransact->statements = new StatementBlock;
   transact_statements = onTransact->statements;
-  onTransact->exceptions.push_back("android.os.RemoteException");
+  onTransact->exceptions.push_back(types->RemoteExceptionType()->JavaType());
   this->elements.push_back(onTransact);
-  this->transact_switch = std::make_shared<SwitchStatement>(this->transact_code);
+  this->transact_switch = new SwitchStatement(this->transact_code);
 }
 
 void StubClass::finish() {
-  auto default_case = std::make_shared<Case>();
+  Case* default_case = new Case;
 
-  auto superCall = std::make_shared<MethodCall>(
-      SUPER_VALUE, "onTransact",
-      std::vector<std::shared_ptr<Expression>>{this->transact_code, this->transact_data,
-                                               this->transact_reply, this->transact_flags});
-  default_case->statements->Add(std::make_shared<ReturnStatement>(superCall));
+  MethodCall* superCall = new MethodCall(
+        SUPER_VALUE, "onTransact", 4, this->transact_code, this->transact_data,
+        this->transact_reply, this->transact_flags);
+  default_case->statements->Add(new ReturnStatement(superCall));
   transact_switch->cases.push_back(default_case);
 
   transact_statements->Add(this->transact_switch);
@@ -214,8 +215,8 @@
     // Some transaction codes are common, e.g. INTERFACE_TRANSACTION or DUMP_TRANSACTION.
     // Common transaction codes will not be resolved to a string by getTransactionName. The method
     // will return NULL in this case.
-    auto code_switch_default_case = std::make_shared<Case>();
-    code_switch_default_case->statements->Add(std::make_shared<ReturnStatement>(NULL_VALUE));
+    Case* code_switch_default_case = new Case;
+    code_switch_default_case->statements->Add(new ReturnStatement(NULL_VALUE));
     this->code_to_method_name_switch->cases.push_back(code_switch_default_case);
   }
 }
@@ -223,18 +224,19 @@
 // The the expression for the interface's descriptor to be used when
 // generating code for the given method. Null is acceptable for method
 // and stands for synthetic cases.
-std::shared_ptr<Expression> StubClass::get_transact_descriptor(const AidlMethod* method) {
+Expression* StubClass::get_transact_descriptor(const JavaTypeNamespace* types,
+                                               const AidlMethod* method) {
   if (transact_outline) {
     if (method != nullptr) {
       // When outlining, each outlined method needs its own literal.
       if (outline_methods.count(method) != 0) {
-        return std::make_shared<LiteralExpression>("DESCRIPTOR");
+        return new LiteralExpression("DESCRIPTOR");
       }
     } else {
       // Synthetic case. A small number is assumed. Use its own descriptor
       // if there are only synthetic cases.
       if (outline_methods.size() == all_method_count) {
-        return std::make_shared<LiteralExpression>("DESCRIPTOR");
+        return new LiteralExpression("DESCRIPTOR");
       }
     }
   }
@@ -242,38 +244,41 @@
   // When not outlining, store the descriptor literal into a local variable, in
   // an effort to save const-string instructions in each switch case.
   if (transact_descriptor == nullptr) {
-    transact_descriptor = std::make_shared<Variable>("java.lang.String", "descriptor");
-    transact_statements->Add(std::make_shared<VariableDeclaration>(
-        transact_descriptor, std::make_shared<LiteralExpression>("DESCRIPTOR")));
+    transact_descriptor = new Variable(types->StringType()->JavaType(), "descriptor");
+    transact_statements->Add(
+        new VariableDeclaration(transact_descriptor,
+                                new LiteralExpression("DESCRIPTOR")));
   }
   return transact_descriptor;
 }
 
-void StubClass::make_as_interface(const AidlInterface* interfaceType) {
-  auto obj = std::make_shared<Variable>("android.os.IBinder", "obj");
+void StubClass::make_as_interface(const InterfaceType* interfaceType,
+                                  JavaTypeNamespace* types) {
+  Variable* obj = new Variable(types->IBinderType()->JavaType(), "obj");
 
-  auto m = std::make_shared<Method>();
+  Method* m = new Method;
   m->comment = "/**\n * Cast an IBinder object into an ";
-  m->comment += interfaceType->GetCanonicalName();
+  m->comment += interfaceType->JavaType();
   m->comment += " interface,\n";
   m->comment += " * generating a proxy if needed.\n */";
   m->modifiers = PUBLIC | STATIC;
-  m->returnType = interfaceType->GetCanonicalName();
+  m->returnType = interfaceType->JavaType();
   m->name = "asInterface";
   m->parameters.push_back(obj);
-  m->statements = std::make_shared<StatementBlock>();
+  m->statements = new StatementBlock;
 
-  auto ifstatement = std::make_shared<IfStatement>();
-  ifstatement->expression = std::make_shared<Comparison>(obj, "==", NULL_VALUE);
-  ifstatement->statements = std::make_shared<StatementBlock>();
-  ifstatement->statements->Add(std::make_shared<ReturnStatement>(NULL_VALUE));
+  IfStatement* ifstatement = new IfStatement();
+  ifstatement->expression = new Comparison(obj, "==", NULL_VALUE);
+  ifstatement->statements = new StatementBlock;
+  ifstatement->statements->Add(new ReturnStatement(NULL_VALUE));
   m->statements->Add(ifstatement);
 
   // IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
-  auto queryLocalInterface = std::make_shared<MethodCall>(obj, "queryLocalInterface");
-  queryLocalInterface->arguments.push_back(std::make_shared<LiteralExpression>("DESCRIPTOR"));
-  auto iin = std::make_shared<Variable>("android.os.IInterface", "iin");
-  auto iinVd = std::make_shared<VariableDeclaration>(iin, queryLocalInterface);
+  MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
+  queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
+  IInterfaceType iinType(types);
+  Variable* iin = new Variable(iinType.JavaType(), "iin");
+  VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface);
   m->statements->Add(iinVd);
 
   // Ensure the instance type of the local object is as expected.
@@ -282,19 +287,19 @@
 
   // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>)
   // iin;
-  auto iinNotNull = std::make_shared<Comparison>(iin, "!=", NULL_VALUE);
-  auto instOfCheck = std::make_shared<Comparison>(
-      iin, " instanceof ", std::make_shared<LiteralExpression>(interfaceType->GetCanonicalName()));
-  auto instOfStatement = std::make_shared<IfStatement>();
-  instOfStatement->expression = std::make_shared<Comparison>(iinNotNull, "&&", instOfCheck);
-  instOfStatement->statements = std::make_shared<StatementBlock>();
-  instOfStatement->statements->Add(std::make_shared<ReturnStatement>(
-      std::make_shared<Cast>(interfaceType->GetCanonicalName(), iin)));
+  Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE);
+  Comparison* instOfCheck =
+      new Comparison(iin, " instanceof ",
+                     new LiteralExpression(interfaceType->JavaType()));
+  IfStatement* instOfStatement = new IfStatement();
+  instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck);
+  instOfStatement->statements = new StatementBlock;
+  instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType->JavaType(), iin)));
   m->statements->Add(instOfStatement);
 
-  auto ne = std::make_shared<NewExpression>(interfaceType->GetCanonicalName() + ".Stub.Proxy");
+  NewExpression* ne = new NewExpression(interfaceType->GetProxy()->InstantiableName());
   ne->arguments.push_back(obj);
-  m->statements->Add(std::make_shared<ReturnStatement>(ne));
+  m->statements->Add(new ReturnStatement(ne));
 
   this->elements.push_back(m);
 }
@@ -302,130 +307,129 @@
 // =================================================
 class ProxyClass : public Class {
  public:
-  ProxyClass(const AidlInterface* interfaceType, const Options& options);
+  ProxyClass(const JavaTypeNamespace* types, const Type* type, const InterfaceType* interfaceType,
+             const Options& options);
   ~ProxyClass() override;
 
-  std::shared_ptr<Variable> mRemote;
+  Variable* mRemote;
 };
 
-ProxyClass::ProxyClass(const AidlInterface* interfaceType, const Options& options) : Class() {
+ProxyClass::ProxyClass(const JavaTypeNamespace* types, const Type* type,
+                       const InterfaceType* interfaceType, const Options& options)
+    : Class() {
   this->modifiers = PRIVATE | STATIC;
   this->what = Class::CLASS;
-  this->type = interfaceType->GetCanonicalName() + ".Stub.Proxy";
-  this->interfaces.push_back(interfaceType->GetCanonicalName());
+  this->type = type->JavaType();
+  this->interfaces.push_back(interfaceType->JavaType());
 
   // IBinder mRemote
-  mRemote = std::make_shared<Variable>("android.os.IBinder", "mRemote");
-  this->elements.push_back(std::make_shared<Field>(PRIVATE, mRemote));
+  mRemote = new Variable(types->IBinderType()->JavaType(), "mRemote");
+  this->elements.push_back(new Field(PRIVATE, mRemote));
 
   // Proxy()
-  auto remote = std::make_shared<Variable>("android.os.IBinder", "remote");
-  auto ctor = std::make_shared<Method>();
+  Variable* remote = new Variable(types->IBinderType()->JavaType(), "remote");
+  Method* ctor = new Method;
   ctor->name = "Proxy";
-  ctor->statements = std::make_shared<StatementBlock>();
+  ctor->statements = new StatementBlock;
   ctor->parameters.push_back(remote);
-  ctor->statements->Add(std::make_shared<Assignment>(mRemote, remote));
+  ctor->statements->Add(new Assignment(mRemote, remote));
   this->elements.push_back(ctor);
 
   if (options.Version() > 0) {
     std::ostringstream code;
     code << "private int mCachedVersion = -1;\n";
-    this->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
+    this->elements.emplace_back(new LiteralClassElement(code.str()));
   }
 
   // IBinder asBinder()
-  auto asBinder = std::make_shared<Method>();
+  Method* asBinder = new Method;
   asBinder->modifiers = PUBLIC | OVERRIDE;
-  asBinder->returnType = "android.os.IBinder";
+  asBinder->returnType = types->IBinderType()->JavaType();
   asBinder->name = "asBinder";
-  asBinder->statements = std::make_shared<StatementBlock>();
-  asBinder->statements->Add(std::make_shared<ReturnStatement>(mRemote));
+  asBinder->statements = new StatementBlock;
+  asBinder->statements->Add(new ReturnStatement(mRemote));
   this->elements.push_back(asBinder);
 }
 
 ProxyClass::~ProxyClass() {}
 
 // =================================================
-static void generate_new_array(const AidlTypeSpecifier& type, const AidlTypenames& typenames,
-                               std::shared_ptr<StatementBlock> addTo, std::shared_ptr<Variable> v,
-                               std::shared_ptr<Variable> parcel) {
-  auto len = std::make_shared<Variable>("int", v->name + "_length");
-  addTo->Add(
-      std::make_shared<VariableDeclaration>(len, std::make_shared<MethodCall>(parcel, "readInt")));
-  auto lencheck = std::make_shared<IfStatement>();
-  lencheck->expression =
-      std::make_shared<Comparison>(len, "<", std::make_shared<LiteralExpression>("0"));
-  lencheck->statements->Add(std::make_shared<Assignment>(v, NULL_VALUE));
-  lencheck->elseif = std::make_shared<IfStatement>();
-  lencheck->elseif->statements->Add(std::make_shared<Assignment>(
-      v, std::make_shared<NewArrayExpression>(InstantiableJavaSignatureOf(type, typenames), len)));
+static void generate_new_array(const Type* t, StatementBlock* addTo,
+                               Variable* v, Variable* parcel,
+                               JavaTypeNamespace* types) {
+  Variable* len = new Variable(types->IntType()->JavaType(), v->name + "_length");
+  addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt")));
+  IfStatement* lencheck = new IfStatement();
+  lencheck->expression = new Comparison(len, "<", new LiteralExpression("0"));
+  lencheck->statements->Add(new Assignment(v, NULL_VALUE));
+  lencheck->elseif = new IfStatement();
+  lencheck->elseif->statements->Add(new Assignment(v, new NewArrayExpression(t->JavaType(), len)));
   addTo->Add(lencheck);
 }
 
-static void generate_write_to_parcel(const AidlTypeSpecifier& type,
-                                     std::shared_ptr<StatementBlock> addTo,
-                                     std::shared_ptr<Variable> v, std::shared_ptr<Variable> parcel,
-                                     bool is_return_value, const AidlTypenames& typenames) {
+static void generate_write_to_parcel(const AidlTypeSpecifier& type, StatementBlock* addTo,
+                                     Variable* v, Variable* parcel, bool is_return_value,
+                                     const AidlTypenames& typenames) {
   string code;
   CodeWriterPtr writer = CodeWriter::ForString(&code);
   CodeGeneratorContext context{
       .writer = *(writer.get()),
       .typenames = typenames,
       .type = type,
-      .parcel = parcel->name,
       .var = v->name,
+      .parcel = parcel->name,
       .is_return_value = is_return_value,
   };
   WriteToParcelFor(context);
   writer->Close();
-  addTo->Add(std::make_shared<LiteralStatement>(code));
+  addTo->Add(new LiteralStatement(code));
 }
 
 static void generate_int_constant(Class* interface, const std::string& name,
                                   const std::string& value) {
   auto code = StringPrintf("public static final int %s = %s;\n", name.c_str(), value.c_str());
-  interface->elements.push_back(std::make_shared<LiteralClassElement>(code));
+  interface->elements.push_back(new LiteralClassElement(code));
 }
 
 static void generate_string_constant(Class* interface, const std::string& name,
                                      const std::string& value) {
   auto code = StringPrintf("public static final String %s = %s;\n", name.c_str(), value.c_str());
-  interface->elements.push_back(std::make_shared<LiteralClassElement>(code));
+  interface->elements.push_back(new LiteralClassElement(code));
 }
 
-static std::shared_ptr<Method> generate_interface_method(const AidlMethod& method,
-                                                         const AidlTypenames& typenames) {
-  auto decl = std::make_shared<Method>();
+static std::unique_ptr<Method> generate_interface_method(
+    const AidlMethod& method, JavaTypeNamespace* types) {
+  std::unique_ptr<Method> decl(new Method);
   decl->comment = method.GetComments();
   decl->modifiers = PUBLIC;
-  decl->returnType = JavaSignatureOf(method.GetType(), typenames);
+  decl->returnType = method.GetType().GetLanguageType<Type>()->JavaType();
+  decl->returnTypeDimension = method.GetType().IsArray() ? 1 : 0;
   decl->name = method.GetName();
   decl->annotations = generate_java_annotations(method.GetType());
 
   for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-    decl->parameters.push_back(
-        std::make_shared<Variable>(JavaSignatureOf(arg->GetType(), typenames), arg->GetName()));
+    decl->parameters.push_back(new Variable(arg->GetType().GetLanguageType<Type>()->JavaType(),
+                                            arg->GetName(), arg->GetType().IsArray() ? 1 : 0));
   }
 
-  decl->exceptions.push_back("android.os.RemoteException");
+  decl->exceptions.push_back(types->RemoteExceptionType()->JavaType());
 
   return decl;
 }
 
 static void generate_stub_code(const AidlInterface& iface, const AidlMethod& method, bool oneway,
-                               std::shared_ptr<Variable> transact_data,
-                               std::shared_ptr<Variable> transact_reply,
-                               const AidlTypenames& typenames,
-                               std::shared_ptr<StatementBlock> statements,
-                               std::shared_ptr<StubClass> stubClass, const Options& options) {
-  std::shared_ptr<TryStatement> tryStatement;
-  std::shared_ptr<FinallyStatement> finallyStatement;
-  auto realCall = std::make_shared<MethodCall>(THIS_VALUE, method.GetName());
+                               Variable* transact_data, Variable* transact_reply,
+                               JavaTypeNamespace* types, StatementBlock* statements,
+                               StubClass* stubClass, const Options& options) {
+  TryStatement* tryStatement = nullptr;
+  FinallyStatement* finallyStatement = nullptr;
+  MethodCall* realCall = new MethodCall(THIS_VALUE, method.GetName());
 
   // interface token validation is the very first thing we do
-  statements->Add(std::make_shared<MethodCall>(
-      transact_data, "enforceInterface",
-      std::vector<std::shared_ptr<Expression>>{stubClass->get_transact_descriptor(&method)}));
+  statements->Add(new MethodCall(transact_data,
+                                 "enforceInterface", 1,
+                                 stubClass->get_transact_descriptor(types,
+                                                                    &method)));
 
   // args
   VariableFactory stubArgs("_arg");
@@ -434,29 +438,29 @@
     // at most once.
     bool is_classloader_created = false;
     for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-      std::shared_ptr<Variable> v = stubArgs.Get(arg->GetType(), typenames);
+      const Type* t = arg->GetType().GetLanguageType<Type>();
+      Variable* v = stubArgs.Get(t);
+      v->dimension = arg->GetType().IsArray() ? 1 : 0;
 
-      statements->Add(std::make_shared<VariableDeclaration>(v));
+      statements->Add(new VariableDeclaration(v));
 
       if (arg->GetDirection() & AidlArgument::IN_DIR) {
         string code;
         CodeWriterPtr writer = CodeWriter::ForString(&code);
         CodeGeneratorContext context{.writer = *(writer.get()),
-                                     .typenames = typenames,
+                                     .typenames = types->typenames_,
                                      .type = arg->GetType(),
-                                     .parcel = transact_data->name,
                                      .var = v->name,
+                                     .parcel = transact_data->name,
                                      .is_classloader_created = &is_classloader_created};
         CreateFromParcelFor(context);
         writer->Close();
-        statements->Add(std::make_shared<LiteralStatement>(code));
+        statements->Add(new LiteralStatement(code));
       } else {
         if (!arg->GetType().IsArray()) {
-          statements->Add(std::make_shared<Assignment>(
-              v, std::make_shared<NewExpression>(
-                     InstantiableJavaSignatureOf(arg->GetType(), typenames))));
+          statements->Add(new Assignment(v, new NewExpression(t->InstantiableName())));
         } else {
-          generate_new_array(arg->GetType(), typenames, statements, v, transact_data);
+          generate_new_array(t, statements, v, transact_data, types);
         }
       }
 
@@ -466,20 +470,18 @@
 
   if (options.GenTraces()) {
     // try and finally, but only when generating trace code
-    tryStatement = std::make_shared<TryStatement>();
-    finallyStatement = std::make_shared<FinallyStatement>();
+    tryStatement = new TryStatement();
+    finallyStatement = new FinallyStatement();
 
-    tryStatement->statements->Add(std::make_shared<MethodCall>(
-        std::make_shared<LiteralExpression>("android.os.Trace"), "traceBegin",
-        std::vector<std::shared_ptr<Expression>>{
-            std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL"),
-            std::make_shared<StringLiteralExpression>(iface.GetName() + "::" + method.GetName() +
-                                                      "::server")}));
+    tryStatement->statements->Add(new MethodCall(
+        new LiteralExpression("android.os.Trace"), "traceBegin", 2,
+        new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"),
+        new StringLiteralExpression(iface.GetName() + "::"
+            + method.GetName() + "::server")));
 
-    finallyStatement->statements->Add(std::make_shared<MethodCall>(
-        std::make_shared<LiteralExpression>("android.os.Trace"), "traceEnd",
-        std::vector<std::shared_ptr<Expression>>{
-            std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL")}));
+    finallyStatement->statements->Add(new MethodCall(
+        new LiteralExpression("android.os.Trace"), "traceEnd", 1,
+        new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL")));
   }
 
   // the real call
@@ -494,180 +496,181 @@
 
     if (!oneway) {
       // report that there were no exceptions
-      auto ex = std::make_shared<MethodCall>(transact_reply, "writeNoException");
+      MethodCall* ex =
+          new MethodCall(transact_reply, "writeNoException", 0);
       statements->Add(ex);
     }
   } else {
-    auto _result =
-        std::make_shared<Variable>(JavaSignatureOf(method.GetType(), typenames), "_result");
+    Variable* _result = new Variable(method.GetType().GetLanguageType<Type>()->JavaType(),
+                                     "_result", method.GetType().IsArray() ? 1 : 0);
     if (options.GenTraces()) {
-      statements->Add(std::make_shared<VariableDeclaration>(_result));
+      statements->Add(new VariableDeclaration(_result));
       statements->Add(tryStatement);
-      tryStatement->statements->Add(std::make_shared<Assignment>(_result, realCall));
+      tryStatement->statements->Add(new Assignment(_result, realCall));
       statements->Add(finallyStatement);
     } else {
-      statements->Add(std::make_shared<VariableDeclaration>(_result, realCall));
+      statements->Add(new VariableDeclaration(_result, realCall));
     }
 
     if (!oneway) {
       // report that there were no exceptions
-      auto ex = std::make_shared<MethodCall>(transact_reply, "writeNoException");
+      MethodCall* ex =
+          new MethodCall(transact_reply, "writeNoException", 0);
       statements->Add(ex);
     }
 
     // marshall the return value
     generate_write_to_parcel(method.GetType(), statements, _result, transact_reply, true,
-                             typenames);
+                             types->typenames_);
   }
 
   // out parameters
   int i = 0;
   for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-    std::shared_ptr<Variable> v = stubArgs.Get(i++);
+    Variable* v = stubArgs.Get(i++);
 
     if (arg->GetDirection() & AidlArgument::OUT_DIR) {
-      generate_write_to_parcel(arg->GetType(), statements, v, transact_reply, true, typenames);
+      generate_write_to_parcel(arg->GetType(), statements, v, transact_reply, true,
+                               types->typenames_);
     }
   }
 
   // return true
-  statements->Add(std::make_shared<ReturnStatement>(TRUE_VALUE));
+  statements->Add(new ReturnStatement(TRUE_VALUE));
 }
 
 static void generate_stub_case(const AidlInterface& iface, const AidlMethod& method,
                                const std::string& transactCodeName, bool oneway,
-                               std::shared_ptr<StubClass> stubClass, const AidlTypenames& typenames,
+                               StubClass* stubClass, JavaTypeNamespace* types,
                                const Options& options) {
-  auto c = std::make_shared<Case>(transactCodeName);
+  Case* c = new Case(transactCodeName);
 
   generate_stub_code(iface, method, oneway, stubClass->transact_data, stubClass->transact_reply,
-                     typenames, c->statements, stubClass, options);
+                     types, c->statements, stubClass, options);
 
   stubClass->transact_switch->cases.push_back(c);
 }
 
 static void generate_stub_case_outline(const AidlInterface& iface, const AidlMethod& method,
                                        const std::string& transactCodeName, bool oneway,
-                                       std::shared_ptr<StubClass> stubClass,
-                                       const AidlTypenames& typenames, const Options& options) {
+                                       StubClass* stubClass, JavaTypeNamespace* types,
+                                       const Options& options) {
   std::string outline_name = "onTransact$" + method.GetName() + "$";
   // Generate an "outlined" method with the actual code.
   {
-    auto transact_data = std::make_shared<Variable>("android.os.Parcel", "data");
-    auto transact_reply = std::make_shared<Variable>("android.os.Parcel", "reply");
-    auto onTransact_case = std::make_shared<Method>();
+    Variable* transact_data = new Variable(types->ParcelType()->JavaType(), "data");
+    Variable* transact_reply = new Variable(types->ParcelType()->JavaType(), "reply");
+    Method* onTransact_case = new Method;
     onTransact_case->modifiers = PRIVATE;
-    onTransact_case->returnType = "boolean";
+    onTransact_case->returnType = types->BoolType()->JavaType();
     onTransact_case->name = outline_name;
     onTransact_case->parameters.push_back(transact_data);
     onTransact_case->parameters.push_back(transact_reply);
-    onTransact_case->statements = std::make_shared<StatementBlock>();
-    onTransact_case->exceptions.push_back("android.os.RemoteException");
+    onTransact_case->statements = new StatementBlock;
+    onTransact_case->exceptions.push_back(types->RemoteExceptionType()->JavaType());
     stubClass->elements.push_back(onTransact_case);
 
-    generate_stub_code(iface, method, oneway, transact_data, transact_reply, typenames,
+    generate_stub_code(iface, method, oneway, transact_data, transact_reply, types,
                        onTransact_case->statements, stubClass, options);
   }
 
   // Generate the case dispatch.
   {
-    auto c = std::make_shared<Case>(transactCodeName);
+    Case* c = new Case(transactCodeName);
 
-    auto helper_call =
-        std::make_shared<MethodCall>(THIS_VALUE, outline_name,
-                                     std::vector<std::shared_ptr<Expression>>{
-                                         stubClass->transact_data, stubClass->transact_reply});
-    c->statements->Add(std::make_shared<ReturnStatement>(helper_call));
+    MethodCall* helper_call = new MethodCall(THIS_VALUE,
+                                             outline_name,
+                                             2,
+                                             stubClass->transact_data,
+                                             stubClass->transact_reply);
+    c->statements->Add(new ReturnStatement(helper_call));
 
     stubClass->transact_switch->cases.push_back(c);
   }
 }
 
-static std::shared_ptr<Method> generate_proxy_method(
+static std::unique_ptr<Method> generate_proxy_method(
     const AidlInterface& iface, const AidlMethod& method, const std::string& transactCodeName,
-    bool oneway, std::shared_ptr<ProxyClass> proxyClass, const AidlTypenames& typenames,
-    const Options& options) {
-  auto proxy = std::make_shared<Method>();
+    bool oneway, ProxyClass* proxyClass, JavaTypeNamespace* types, const Options& options) {
+  std::unique_ptr<Method> proxy(new Method);
   proxy->comment = method.GetComments();
   proxy->modifiers = PUBLIC | OVERRIDE;
-  proxy->returnType = JavaSignatureOf(method.GetType(), typenames);
+  proxy->returnType = method.GetType().GetLanguageType<Type>()->JavaType();
+  proxy->returnTypeDimension = method.GetType().IsArray() ? 1 : 0;
   proxy->name = method.GetName();
-  proxy->statements = std::make_shared<StatementBlock>();
+  proxy->statements = new StatementBlock;
   for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-    proxy->parameters.push_back(
-        std::make_shared<Variable>(JavaSignatureOf(arg->GetType(), typenames), arg->GetName()));
+    proxy->parameters.push_back(new Variable(arg->GetType().GetLanguageType<Type>()->JavaType(),
+                                             arg->GetName(), arg->GetType().IsArray() ? 1 : 0));
   }
-  proxy->exceptions.push_back("android.os.RemoteException");
+  proxy->exceptions.push_back(types->RemoteExceptionType()->JavaType());
 
   // the parcels
-  auto _data = std::make_shared<Variable>("android.os.Parcel", "_data");
-  proxy->statements->Add(std::make_shared<VariableDeclaration>(
-      _data, std::make_shared<MethodCall>("android.os.Parcel", "obtain")));
-  std::shared_ptr<Variable> _reply = nullptr;
+  Variable* _data = new Variable(types->ParcelType()->JavaType(), "_data");
+  proxy->statements->Add(
+      new VariableDeclaration(_data, new MethodCall(types->ParcelType()->JavaType(), "obtain")));
+  Variable* _reply = nullptr;
   if (!oneway) {
-    _reply = std::make_shared<Variable>("android.os.Parcel", "_reply");
-    proxy->statements->Add(std::make_shared<VariableDeclaration>(
-        _reply, std::make_shared<MethodCall>("android.os.Parcel", "obtain")));
+    _reply = new Variable(types->ParcelType()->JavaType(), "_reply");
+    proxy->statements->Add(
+        new VariableDeclaration(_reply, new MethodCall(types->ParcelType()->JavaType(), "obtain")));
   }
 
   // the return value
-  std::shared_ptr<Variable> _result = nullptr;
+  Variable* _result = nullptr;
   if (method.GetType().GetName() != "void") {
-    _result = std::make_shared<Variable>(*proxy->returnType, "_result");
-    proxy->statements->Add(std::make_shared<VariableDeclaration>(_result));
+    _result = new Variable(*proxy->returnType, "_result", method.GetType().IsArray() ? 1 : 0);
+    proxy->statements->Add(new VariableDeclaration(_result));
   }
 
   // try and finally
-  auto tryStatement = std::make_shared<TryStatement>();
+  TryStatement* tryStatement = new TryStatement();
   proxy->statements->Add(tryStatement);
-  auto finallyStatement = std::make_shared<FinallyStatement>();
+  FinallyStatement* finallyStatement = new FinallyStatement();
   proxy->statements->Add(finallyStatement);
 
   if (options.GenTraces()) {
-    tryStatement->statements->Add(std::make_shared<MethodCall>(
-        std::make_shared<LiteralExpression>("android.os.Trace"), "traceBegin",
-        std::vector<std::shared_ptr<Expression>>{
-            std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL"),
-            std::make_shared<StringLiteralExpression>(iface.GetName() + "::" + method.GetName() +
-                                                      "::client")}));
+    tryStatement->statements->Add(new MethodCall(
+          new LiteralExpression("android.os.Trace"), "traceBegin", 2,
+          new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL"),
+          new StringLiteralExpression(iface.GetName() + "::" +
+                                      method.GetName() + "::client")));
   }
 
   // the interface identifier token: the DESCRIPTOR constant, marshalled as a
   // string
-  tryStatement->statements->Add(std::make_shared<MethodCall>(
-      _data, "writeInterfaceToken",
-      std::vector<std::shared_ptr<Expression>>{std::make_shared<LiteralExpression>("DESCRIPTOR")}));
+  tryStatement->statements->Add(new MethodCall(
+      _data, "writeInterfaceToken", 1, new LiteralExpression("DESCRIPTOR")));
 
   // the parameters
   for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
-    auto v = std::make_shared<Variable>(JavaSignatureOf(arg->GetType(), typenames), arg->GetName());
+    const Type* t = arg->GetType().GetLanguageType<Type>();
+    Variable* v = new Variable(t->JavaType(), arg->GetName(), arg->GetType().IsArray() ? 1 : 0);
     AidlArgument::Direction dir = arg->GetDirection();
     if (dir == AidlArgument::OUT_DIR && arg->GetType().IsArray()) {
-      auto checklen = std::make_shared<IfStatement>();
-      checklen->expression = std::make_shared<Comparison>(v, "==", NULL_VALUE);
-      checklen->statements->Add(std::make_shared<MethodCall>(
-          _data, "writeInt",
-          std::vector<std::shared_ptr<Expression>>{std::make_shared<LiteralExpression>("-1")}));
-      checklen->elseif = std::make_shared<IfStatement>();
-      checklen->elseif->statements->Add(std::make_shared<MethodCall>(
-          _data, "writeInt",
-          std::vector<std::shared_ptr<Expression>>{std::make_shared<FieldVariable>(v, "length")}));
+      IfStatement* checklen = new IfStatement();
+      checklen->expression = new Comparison(v, "==", NULL_VALUE);
+      checklen->statements->Add(
+          new MethodCall(_data, "writeInt", 1, new LiteralExpression("-1")));
+      checklen->elseif = new IfStatement();
+      checklen->elseif->statements->Add(
+          new MethodCall(_data, "writeInt", 1, new FieldVariable(v, "length")));
       tryStatement->statements->Add(checklen);
     } else if (dir & AidlArgument::IN_DIR) {
       generate_write_to_parcel(arg->GetType(), tryStatement->statements, v, _data, false,
-                               typenames);
+                               types->typenames_);
+    } else {
+      delete v;
     }
   }
 
   // the transact call
-  auto call = std::make_shared<MethodCall>(
-      proxyClass->mRemote, "transact",
-      std::vector<std::shared_ptr<Expression>>{
-          std::make_shared<LiteralExpression>("Stub." + transactCodeName), _data,
-          _reply ? _reply : NULL_VALUE,
-          std::make_shared<LiteralExpression>(oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0")});
-  auto _status = std::make_shared<Variable>("boolean", "_status");
-  tryStatement->statements->Add(std::make_shared<VariableDeclaration>(_status, call));
+  unique_ptr<MethodCall> call(new MethodCall(
+      proxyClass->mRemote, "transact", 4, new LiteralExpression("Stub." + transactCodeName), _data,
+      _reply ? _reply : NULL_VALUE,
+      new LiteralExpression(oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0")));
+  unique_ptr<Variable> _status(new Variable(types->BoolType()->JavaType(), "_status"));
+  tryStatement->statements->Add(new VariableDeclaration(_status.release(), call.release()));
 
   // If the transaction returns false, which means UNKNOWN_TRANSACTION, fall
   // back to the local method in the default impl, if set before.
@@ -676,7 +679,7 @@
     arg_names.emplace_back(arg->GetName());
   }
   bool has_return_type = method.GetType().GetName() != "void";
-  tryStatement->statements->Add(std::make_shared<LiteralStatement>(
+  tryStatement->statements->Add(new LiteralStatement(
       android::base::StringPrintf(has_return_type ? "if (!_status && getDefaultImpl() != null) {\n"
                                                     "  return getDefaultImpl().%s(%s);\n"
                                                     "}\n"
@@ -688,7 +691,7 @@
 
   // throw back exceptions.
   if (_reply) {
-    auto ex = std::make_shared<MethodCall>(_reply, "readException");
+    MethodCall* ex = new MethodCall(_reply, "readException", 0);
     tryStatement->statements->Add(ex);
   }
 
@@ -701,14 +704,14 @@
       string code;
       CodeWriterPtr writer = CodeWriter::ForString(&code);
       CodeGeneratorContext context{.writer = *(writer.get()),
-                                   .typenames = typenames,
+                                   .typenames = types->typenames_,
                                    .type = method.GetType(),
-                                   .parcel = _reply->name,
                                    .var = _result->name,
+                                   .parcel = _reply->name,
                                    .is_classloader_created = &is_classloader_created};
       CreateFromParcelFor(context);
       writer->Close();
-      tryStatement->statements->Add(std::make_shared<LiteralStatement>(code));
+      tryStatement->statements->Add(new LiteralStatement(code));
     }
 
     // the out/inout parameters
@@ -717,69 +720,66 @@
         string code;
         CodeWriterPtr writer = CodeWriter::ForString(&code);
         CodeGeneratorContext context{.writer = *(writer.get()),
-                                     .typenames = typenames,
+                                     .typenames = types->typenames_,
                                      .type = arg->GetType(),
-                                     .parcel = _reply->name,
                                      .var = arg->GetName(),
+                                     .parcel = _reply->name,
                                      .is_classloader_created = &is_classloader_created};
         ReadFromParcelFor(context);
         writer->Close();
-        tryStatement->statements->Add(std::make_shared<LiteralStatement>(code));
+        tryStatement->statements->Add(new LiteralStatement(code));
       }
     }
 
-    finallyStatement->statements->Add(std::make_shared<MethodCall>(_reply, "recycle"));
+    finallyStatement->statements->Add(new MethodCall(_reply, "recycle"));
   }
-  finallyStatement->statements->Add(std::make_shared<MethodCall>(_data, "recycle"));
+  finallyStatement->statements->Add(new MethodCall(_data, "recycle"));
 
   if (options.GenTraces()) {
-    finallyStatement->statements->Add(std::make_shared<MethodCall>(
-        std::make_shared<LiteralExpression>("android.os.Trace"), "traceEnd",
-        std::vector<std::shared_ptr<Expression>>{
-            std::make_shared<LiteralExpression>("android.os.Trace.TRACE_TAG_AIDL")}));
+    finallyStatement->statements->Add(new MethodCall(
+        new LiteralExpression("android.os.Trace"), "traceEnd", 1,
+        new LiteralExpression("android.os.Trace.TRACE_TAG_AIDL")));
   }
 
   if (_result != nullptr) {
-    proxy->statements->Add(std::make_shared<ReturnStatement>(_result));
+    proxy->statements->Add(new ReturnStatement(_result));
   }
 
   return proxy;
 }
 
 static void generate_methods(const AidlInterface& iface, const AidlMethod& method, Class* interface,
-                             std::shared_ptr<StubClass> stubClass,
-                             std::shared_ptr<ProxyClass> proxyClass, int index,
-                             const AidlTypenames& typenames, const Options& options) {
+                             StubClass* stubClass, ProxyClass* proxyClass, int index,
+                             JavaTypeNamespace* types, const Options& options) {
   const bool oneway = method.IsOneway();
 
   // == the TRANSACT_ constant =============================================
   string transactCodeName = "TRANSACTION_";
   transactCodeName += method.GetName();
 
-  auto transactCode =
-      std::make_shared<Field>(STATIC | FINAL, std::make_shared<Variable>("int", transactCodeName));
+  Field* transactCode =
+      new Field(STATIC | FINAL, new Variable(types->IntType()->JavaType(), transactCodeName));
   transactCode->value =
       StringPrintf("(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
   stubClass->elements.push_back(transactCode);
 
   // getTransactionName
   if (options.GenTransactionNames()) {
-    auto c = std::make_shared<Case>(transactCodeName);
-    c->statements->Add(std::make_shared<ReturnStatement>(
-        std::make_shared<StringLiteralExpression>(method.GetName())));
+    Case* c = new Case(transactCodeName);
+    c->statements->Add(new ReturnStatement(new StringLiteralExpression(method.GetName())));
     stubClass->code_to_method_name_switch->cases.push_back(c);
   }
 
   // == the declaration in the interface ===================================
-  std::shared_ptr<ClassElement> decl;
+  ClassElement* decl;
   if (method.IsUserDefined()) {
-    decl = generate_interface_method(method, typenames);
+    decl = generate_interface_method(method, types).release();
   } else {
     if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
       std::ostringstream code;
       code << "public int " << kGetInterfaceVersion << "() "
            << "throws android.os.RemoteException;\n";
-      decl = std::make_shared<LiteralClassElement>(code.str());
+      decl = new LiteralClassElement(code.str());
     }
   }
   interface->elements.push_back(decl);
@@ -789,29 +789,30 @@
     bool outline_stub =
         stubClass->transact_outline && stubClass->outline_methods.count(&method) != 0;
     if (outline_stub) {
-      generate_stub_case_outline(iface, method, transactCodeName, oneway, stubClass, typenames,
+      generate_stub_case_outline(iface, method, transactCodeName, oneway, stubClass, types,
                                  options);
     } else {
-      generate_stub_case(iface, method, transactCodeName, oneway, stubClass, typenames, options);
+      generate_stub_case(iface, method, transactCodeName, oneway, stubClass, types, options);
     }
   } else {
     if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
-      auto c = std::make_shared<Case>(transactCodeName);
+      Case* c = new Case(transactCodeName);
       std::ostringstream code;
       code << "data.enforceInterface(descriptor);\n"
            << "reply.writeNoException();\n"
            << "reply.writeInt(" << kGetInterfaceVersion << "());\n"
            << "return true;\n";
-      c->statements->Add(std::make_shared<LiteralStatement>(code.str()));
+      c->statements->Add(new LiteralStatement(code.str()));
       stubClass->transact_switch->cases.push_back(c);
     }
   }
 
   // == the proxy method ===================================================
-  std::shared_ptr<ClassElement> proxy = nullptr;
+  ClassElement* proxy = nullptr;
   if (method.IsUserDefined()) {
-    proxy = generate_proxy_method(iface, method, transactCodeName, oneway, proxyClass, typenames,
-                                  options);
+    proxy =
+        generate_proxy_method(iface, method, transactCodeName, oneway, proxyClass, types, options)
+            .release();
 
   } else {
     if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
@@ -825,13 +826,8 @@
            << "    android.os.Parcel reply = android.os.Parcel.obtain();\n"
            << "    try {\n"
            << "      data.writeInterfaceToken(DESCRIPTOR);\n"
-           << "      boolean _status = mRemote.transact(Stub." << transactCodeName << ", "
+           << "      mRemote.transact(Stub." << transactCodeName << ", "
            << "data, reply, 0);\n"
-           << "      if (!_status) {\n"
-           << "        if (getDefaultImpl() != null) {\n"
-           << "          return getDefaultImpl().getInterfaceVersion();\n"
-           << "        }\n"
-           << "      }\n"
            << "      reply.readException();\n"
            << "      mCachedVersion = reply.readInt();\n"
            << "    } finally {\n"
@@ -841,7 +837,7 @@
            << "  }\n"
            << "  return mCachedVersion;\n"
            << "}\n";
-      proxy = std::make_shared<LiteralClassElement>(code.str());
+      proxy = new LiteralClassElement(code.str());
     }
   }
   if (proxy != nullptr) {
@@ -849,24 +845,25 @@
   }
 }
 
-static void generate_interface_descriptors(std::shared_ptr<StubClass> stub,
-                                           std::shared_ptr<ProxyClass> proxy) {
+static void generate_interface_descriptors(StubClass* stub, ProxyClass* proxy,
+                                           const JavaTypeNamespace* types) {
   // the interface descriptor transaction handler
-  auto c = std::make_shared<Case>("INTERFACE_TRANSACTION");
-  c->statements->Add(std::make_shared<MethodCall>(
-      stub->transact_reply, "writeString",
-      std::vector<std::shared_ptr<Expression>>{stub->get_transact_descriptor(nullptr)}));
-  c->statements->Add(std::make_shared<ReturnStatement>(TRUE_VALUE));
+  Case* c = new Case("INTERFACE_TRANSACTION");
+  c->statements->Add(new MethodCall(stub->transact_reply, "writeString", 1,
+                                    stub->get_transact_descriptor(types,
+                                                                  nullptr)));
+  c->statements->Add(new ReturnStatement(TRUE_VALUE));
   stub->transact_switch->cases.push_back(c);
 
   // and the proxy-side method returning the descriptor directly
-  auto getDesc = std::make_shared<Method>();
+  Method* getDesc = new Method;
   getDesc->modifiers = PUBLIC;
-  getDesc->returnType = "java.lang.String";
+  getDesc->returnType = types->StringType()->JavaType();
+  getDesc->returnTypeDimension = 0;
   getDesc->name = "getInterfaceDescriptor";
-  getDesc->statements = std::make_shared<StatementBlock>();
+  getDesc->statements = new StatementBlock;
   getDesc->statements->Add(
-      std::make_shared<ReturnStatement>(std::make_shared<LiteralExpression>("DESCRIPTOR")));
+      new ReturnStatement(new LiteralExpression("DESCRIPTOR")));
   proxy->elements.push_back(getDesc);
 }
 
@@ -881,7 +878,8 @@
 //
 // Requirements: non_outline_count <= outline_threshold.
 static void compute_outline_methods(const AidlInterface* iface,
-                                    const std::shared_ptr<StubClass> stub, size_t outline_threshold,
+                                    StubClass* stub,
+                                    size_t outline_threshold,
                                     size_t non_outline_count) {
   CHECK_LE(non_outline_count, outline_threshold);
   // We'll outline (create sub methods) if there are more than min_methods
@@ -907,41 +905,45 @@
   }
 }
 
-static shared_ptr<ClassElement> generate_default_impl_method(const AidlMethod& method,
-                                                             const AidlTypenames& typenames) {
-  auto default_method = std::make_shared<Method>();
+static unique_ptr<ClassElement> generate_default_impl_method(const AidlMethod& method) {
+  unique_ptr<Method> default_method(new Method);
   default_method->comment = method.GetComments();
   default_method->modifiers = PUBLIC | OVERRIDE;
-  default_method->returnType = JavaSignatureOf(method.GetType(), typenames);
+  default_method->returnType = method.GetType().GetLanguageType<Type>()->JavaType();
+  default_method->returnTypeDimension = method.GetType().IsArray() ? 1 : 0;
   default_method->name = method.GetName();
-  default_method->statements = std::make_shared<StatementBlock>();
+  default_method->statements = new StatementBlock;
   for (const auto& arg : method.GetArguments()) {
     default_method->parameters.push_back(
-        std::make_shared<Variable>(JavaSignatureOf(arg->GetType(), typenames), arg->GetName()));
+        new Variable(arg->GetType().GetLanguageType<Type>()->JavaType(), arg->GetName(),
+                     arg->GetType().IsArray() ? 1 : 0));
   }
-  default_method->exceptions.push_back("android.os.RemoteException");
+  default_method->exceptions.push_back(method.GetType()
+                                           .GetLanguageType<Type>()
+                                           ->GetTypeNamespace()
+                                           ->RemoteExceptionType()
+                                           ->JavaType());
 
   if (method.GetType().GetName() != "void") {
-    const string& defaultValue = DefaultJavaValueOf(method.GetType(), typenames);
+    const string& defaultValue = DefaultJavaValueOf(method.GetType());
     default_method->statements->Add(
-        std::make_shared<LiteralStatement>(StringPrintf("return %s;\n", defaultValue.c_str())));
+        new LiteralStatement(StringPrintf("return %s;\n", defaultValue.c_str())));
   }
   return default_method;
 }
 
-static shared_ptr<Class> generate_default_impl_class(const AidlInterface& iface,
-                                                     const AidlTypenames& typenames,
+static unique_ptr<Class> generate_default_impl_class(const AidlInterface& iface,
                                                      const Options& options) {
-  auto default_class = std::make_shared<Class>();
+  unique_ptr<Class> default_class(new Class);
   default_class->comment = "/** Default implementation for " + iface.GetName() + ". */";
   default_class->modifiers = PUBLIC | STATIC;
   default_class->what = Class::CLASS;
-  default_class->type = iface.GetCanonicalName() + ".Default";
-  default_class->interfaces.emplace_back(iface.GetCanonicalName());
+  default_class->type = iface.GetLanguageType<InterfaceType>()->GetDefaultImpl()->JavaType();
+  default_class->interfaces.emplace_back(iface.GetLanguageType<InterfaceType>()->JavaType());
 
   for (const auto& m : iface.GetMethods()) {
     if (m->IsUserDefined()) {
-      default_class->elements.emplace_back(generate_default_impl_method(*m.get(), typenames));
+      default_class->elements.emplace_back(generate_default_impl_method(*(m.get())).release());
     } else {
       if (m->GetName() == kGetInterfaceVersion && options.Version() > 0) {
         // This is called only when the remote side is not implementing this
@@ -955,30 +957,31 @@
              << "public int " << kGetInterfaceVersion << "() {\n"
              << "  return -1;\n"
              << "}\n";
-        default_class->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
+        default_class->elements.emplace_back(new LiteralClassElement(code.str()));
       }
     }
   }
 
   default_class->elements.emplace_back(
-      std::make_shared<LiteralClassElement>("@Override\n"
-                                            "public android.os.IBinder asBinder() {\n"
-                                            "  return null;\n"
-                                            "}\n"));
+      new LiteralClassElement("@Override\n"
+                              "public android.os.IBinder asBinder() {\n"
+                              "  return null;\n"
+                              "}\n"));
 
   return default_class;
 }
 
-std::unique_ptr<Class> generate_binder_interface_class(const AidlInterface* iface,
-                                                       const AidlTypenames& typenames,
-                                                       const Options& options) {
+Class* generate_binder_interface_class(const AidlInterface* iface, JavaTypeNamespace* types,
+                                       const Options& options) {
+  const InterfaceType* interfaceType = iface->GetLanguageType<InterfaceType>();
+
   // the interface class
-  auto interface = std::make_unique<Class>();
+  Class* interface = new Class;
   interface->comment = iface->GetComments();
   interface->modifiers = PUBLIC;
   interface->what = Class::INTERFACE;
-  interface->type = iface->GetCanonicalName();
-  interface->interfaces.push_back("android.os.IInterface");
+  interface->type = interfaceType->JavaType();
+  interface->interfaces.push_back(types->IInterfaceType()->JavaType());
   interface->annotations = generate_java_annotations(*iface);
 
   if (options.Version()) {
@@ -990,15 +993,16 @@
          << " * that the remote object is implementing.\n"
          << " */\n"
          << "public static final int VERSION = " << options.Version() << ";\n";
-    interface->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
+    interface->elements.emplace_back(new LiteralClassElement(code.str()));
   }
 
   // the default impl class
-  auto default_impl = generate_default_impl_class(*iface, typenames, options);
+  Class* default_impl = generate_default_impl_class(*iface, options).release();
   interface->elements.emplace_back(default_impl);
 
   // the stub inner class
-  auto stub = std::make_shared<StubClass>(iface, options);
+  StubClass* stub =
+      new StubClass(interfaceType->GetStub(), interfaceType, types, options);
   interface->elements.push_back(stub);
 
   compute_outline_methods(iface,
@@ -1007,11 +1011,11 @@
                           options.onTransact_non_outline_count_);
 
   // the proxy inner class
-  auto proxy = std::make_shared<ProxyClass>(iface, options);
+  ProxyClass* proxy = new ProxyClass(types, interfaceType->GetProxy(), interfaceType, options);
   stub->elements.push_back(proxy);
 
   // stub and proxy support for getInterfaceDescriptor()
-  generate_interface_descriptors(stub, proxy);
+  generate_interface_descriptors(stub, proxy, types);
 
   // all the declared constants of the interface
   for (const auto& constant : iface->GetConstantDeclarations()) {
@@ -1019,14 +1023,13 @@
 
     switch (value.GetType()) {
       case AidlConstantValue::Type::STRING: {
-        generate_string_constant(interface.get(), constant->GetName(),
+        generate_string_constant(interface, constant->GetName(),
                                  constant->ValueString(ConstantValueDecorator));
         break;
       }
-      case AidlConstantValue::Type::BOOLEAN:  // fall-through
-      case AidlConstantValue::Type::INT8:     // fall-through
-      case AidlConstantValue::Type::INT32: {
-        generate_int_constant(interface.get(), constant->GetName(),
+      case AidlConstantValue::Type::INTEGRAL:
+      case AidlConstantValue::Type::HEXIDECIMAL: {
+        generate_int_constant(interface, constant->GetName(),
                               constant->ValueString(ConstantValueDecorator));
         break;
       }
@@ -1039,7 +1042,13 @@
   // all the declared methods of the interface
 
   for (const auto& item : iface->GetMethods()) {
-    generate_methods(*iface, *item, interface.get(), stub, proxy, item->GetId(), typenames,
+    generate_methods(*iface,
+                     *item,
+                     interface,
+                     stub,
+                     proxy,
+                     item->GetId(),
+                     types,
                      options);
   }
 
@@ -1049,8 +1058,8 @@
   // supported.
   // TODO(b/111417145) make this conditional depending on the Java language
   // version requested
-  const string i_name = iface->GetCanonicalName();
-  stub->elements.emplace_back(std::make_shared<LiteralClassElement>(
+  const string i_name = interfaceType->JavaType();
+  stub->elements.emplace_back(new LiteralClassElement(
       StringPrintf("public static boolean setDefaultImpl(%s impl) {\n"
                    "  if (Stub.Proxy.sDefaultImpl == null && impl != null) {\n"
                    "    Stub.Proxy.sDefaultImpl = impl;\n"
@@ -1060,14 +1069,14 @@
                    "}\n",
                    i_name.c_str())));
   stub->elements.emplace_back(
-      std::make_shared<LiteralClassElement>(StringPrintf("public static %s getDefaultImpl() {\n"
-                                                         "  return Stub.Proxy.sDefaultImpl;\n"
-                                                         "}\n",
-                                                         i_name.c_str())));
+      new LiteralClassElement(StringPrintf("public static %s getDefaultImpl() {\n"
+                                           "  return Stub.Proxy.sDefaultImpl;\n"
+                                           "}\n",
+                                           i_name.c_str())));
 
   // the static field is defined in the proxy class, not in the interface class
   // because all fields in an interface class are by default final.
-  proxy->elements.emplace_back(std::make_shared<LiteralClassElement>(
+  proxy->elements.emplace_back(new LiteralClassElement(
       StringPrintf("public static %s sDefaultImpl;\n", i_name.c_str())));
 
   stub->finish();
@@ -1076,5 +1085,5 @@
 }
 
 }  // namespace java
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/generate_ndk.cpp b/generate_ndk.cpp
index fc9cc20..f0445f7 100644
--- a/generate_ndk.cpp
+++ b/generate_ndk.cpp
@@ -93,59 +93,27 @@
   CHECK(code_writer->Close());
 }
 
-void GenerateNdkEnumDeclaration(const string& output_file, const Options& options,
-                                const AidlTypenames& types, const AidlEnumDeclaration& defined_type,
-                                const IoDelegate& io_delegate) {
-  const string header_path =
-      options.OutputHeaderDir() + NdkHeaderFile(defined_type, ClassNames::RAW);
-  unique_ptr<CodeWriter> header_writer(io_delegate.GetCodeWriter(header_path));
-  GenerateEnumHeader(*header_writer, types, defined_type, options);
-  CHECK(header_writer->Close());
-
-  const string bp_header =
-      options.OutputHeaderDir() + NdkHeaderFile(defined_type, ClassNames::CLIENT);
-  unique_ptr<CodeWriter> bp_writer(io_delegate.GetCodeWriter(bp_header));
-  *bp_writer << "#error TODO(b/111362593) enums do not have bp classes\n";
-  CHECK(bp_writer->Close());
-
-  const string bn_header =
-      options.OutputHeaderDir() + NdkHeaderFile(defined_type, ClassNames::SERVER);
-  unique_ptr<CodeWriter> bn_writer(io_delegate.GetCodeWriter(bn_header));
-  *bn_writer << "#error TODO(b/111362593) enums do not have bn classes\n";
-  CHECK(bn_writer->Close());
-
-  unique_ptr<CodeWriter> source_writer = io_delegate.GetCodeWriter(output_file);
-  *source_writer
-      << "// This file is intentionally left blank as placeholder for enum declaration.\n";
-  CHECK(source_writer->Close());
-}
-
 void GenerateNdk(const string& output_file, const Options& options, const AidlTypenames& types,
                  const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
-  if (const AidlStructuredParcelable* parcelable = defined_type.AsStructuredParcelable();
-      parcelable != nullptr) {
+  const AidlStructuredParcelable* parcelable = defined_type.AsStructuredParcelable();
+  if (parcelable != nullptr) {
     GenerateNdkParcel(output_file, options, types, *parcelable, io_delegate);
     return;
   }
 
-  if (const AidlParcelable* parcelable_decl = defined_type.AsParcelable();
-      parcelable_decl != nullptr) {
+  const AidlParcelable* parcelable_decl = defined_type.AsParcelable();
+  if (parcelable_decl != nullptr) {
     GenerateNdkParcelDeclaration(output_file, io_delegate);
     return;
   }
 
-  if (const AidlEnumDeclaration* enum_decl = defined_type.AsEnumDeclaration();
-      enum_decl != nullptr) {
-    GenerateNdkEnumDeclaration(output_file, options, types, *enum_decl, io_delegate);
-    return;
-  }
-
-  if (const AidlInterface* interface = defined_type.AsInterface(); interface != nullptr) {
+  const AidlInterface* interface = defined_type.AsInterface();
+  if (interface != nullptr) {
     GenerateNdkInterface(output_file, options, types, *interface, io_delegate);
     return;
   }
 
-  CHECK(false) << "Unrecognized type sent for NDK cpp generation.";
+  CHECK(false) << "Unrecognized type sent for cpp generation.";
 }
 namespace internals {
 
@@ -170,14 +138,7 @@
 
 static void GenerateHeaderIncludes(CodeWriter& out, const AidlTypenames& types,
                                    const AidlDefinedType& defined_type) {
-  out << "#include <cstdint>\n";
-  out << "#include <memory>\n";
-  out << "#include <optional>\n";
-  out << "#include <string>\n";
-  out << "#include <vector>\n";
-  out << "#ifdef BINDER_STABILITY_SUPPORT\n";
-  out << "#include <android/binder_stability.h>\n";
-  out << "#endif  // BINDER_STABILITY_SUPPORT\n";
+  out << "#include <android/binder_parcel_utils.h>\n";
 
   types.IterateTypes([&](const AidlDefinedType& other_defined_type) {
     if (&other_defined_type == &defined_type) return;
@@ -190,9 +151,6 @@
           << NdkHeaderFile(other_defined_type, ClassNames::BASE, false /*use_os_sep*/) << ">\n";
     } else if (other_defined_type.AsParcelable() != nullptr) {
       out << "#include \"" << other_defined_type.AsParcelable()->GetCppHeader() << "\"\n";
-    } else if (other_defined_type.AsEnumDeclaration() != nullptr) {
-      out << "#include <"
-          << NdkHeaderFile(other_defined_type, ClassNames::BASE, false /*use_os_sep*/) << ">\n";
     } else {
       AIDL_FATAL(defined_type) << "Unrecognized type.";
     }
@@ -200,8 +158,6 @@
 }
 static void GenerateSourceIncludes(CodeWriter& out, const AidlTypenames& types,
                                    const AidlDefinedType& /*defined_type*/) {
-  out << "#include <android/binder_parcel_utils.h>\n";
-
   types.IterateTypes([&](const AidlDefinedType& a_defined_type) {
     if (a_defined_type.AsInterface() != nullptr) {
       out << "#include <" << NdkHeaderFile(a_defined_type, ClassNames::CLIENT, false /*use_os_sep*/)
@@ -217,8 +173,6 @@
 static void GenerateConstantDeclarations(CodeWriter& out, const AidlInterface& interface) {
   for (const auto& constant : interface.GetConstantDeclarations()) {
     const AidlConstantValue& value = constant->GetValue();
-    CHECK(value.GetType() != AidlConstantValue::Type::UNARY &&
-          value.GetType() != AidlConstantValue::Type::BINARY);
     if (value.GetType() == AidlConstantValue::Type::STRING) {
       out << "static const char* " << constant->GetName() << ";\n";
     }
@@ -228,11 +182,8 @@
   bool hasIntegralConstant = false;
   for (const auto& constant : interface.GetConstantDeclarations()) {
     const AidlConstantValue& value = constant->GetValue();
-    CHECK(value.GetType() != AidlConstantValue::Type::UNARY &&
-          value.GetType() != AidlConstantValue::Type::BINARY);
-    if (value.GetType() == AidlConstantValue::Type::BOOLEAN ||
-        value.GetType() == AidlConstantValue::Type::INT8 ||
-        value.GetType() == AidlConstantValue::Type::INT32) {
+    if (value.GetType() == AidlConstantValue::Type::HEXIDECIMAL ||
+        value.GetType() == AidlConstantValue::Type::INTEGRAL) {
       hasIntegralConstant = true;
       break;
     }
@@ -243,10 +194,9 @@
     out.Indent();
     for (const auto& constant : interface.GetConstantDeclarations()) {
       const AidlConstantValue& value = constant->GetValue();
-      if (value.GetType() == AidlConstantValue::Type::BOOLEAN ||
-          value.GetType() == AidlConstantValue::Type::INT8 ||
-          value.GetType() == AidlConstantValue::Type::INT32) {
-        out << constant->GetName() << " = " << constant->ValueString(ConstantValueDecorator)
+      if (value.GetType() == AidlConstantValue::Type::HEXIDECIMAL ||
+          value.GetType() == AidlConstantValue::Type::INTEGRAL) {
+        out << constant->GetName() << " = " << constant->ValueString(AidlConstantValueDecorator)
             << ",\n";
       }
     }
@@ -259,11 +209,9 @@
 
   for (const auto& constant : interface.GetConstantDeclarations()) {
     const AidlConstantValue& value = constant->GetValue();
-    CHECK(value.GetType() != AidlConstantValue::Type::UNARY &&
-          value.GetType() != AidlConstantValue::Type::BINARY);
     if (value.GetType() == AidlConstantValue::Type::STRING) {
       out << "const char* " << clazz << "::" << constant->GetName() << " = "
-          << constant->ValueString(ConstantValueDecorator) << ";\n";
+          << constant->ValueString(AidlConstantValueDecorator) << ";\n";
     }
   }
 }
@@ -338,11 +286,7 @@
   out << MethodId(method) << ",\n";
   out << "_aidl_in.getR(),\n";
   out << "_aidl_out.getR(),\n";
-  out << (method.IsOneway() ? "FLAG_ONEWAY" : "0") << "\n";
-  out << "#ifdef BINDER_STABILITY_SUPPORT\n";
-  out << "| FLAG_PRIVATE_LOCAL\n";
-  out << "#endif  // BINDER_STABILITY_SUPPORT\n";
-  out << ");\n";
+  out << (method.IsOneway() ? "FLAG_ONEWAY" : "0") << ");\n";
   out.Dedent();
 
   // If the method is not implmented in the server side but the client has
@@ -490,7 +434,7 @@
   }
   out << "return _aidl_ret_status;\n";
   out.Dedent();
-  out << "}\n\n";
+  out << "};\n\n";
 
   out << "static AIBinder_Class* " << kClazz << " = ::ndk::ICInterface::defineClass(" << clazz
       << "::" << kDescriptor << ", _aidl_onTransact);\n\n";
@@ -529,15 +473,6 @@
   out << "::ndk::SpAIBinder " << clazz << "::createBinder() {\n";
   out.Indent();
   out << "AIBinder* binder = AIBinder_new(" << kClazz << ", static_cast<void*>(this));\n";
-
-  out << "#ifdef BINDER_STABILITY_SUPPORT\n";
-  if (defined_type.IsVintfStability()) {
-    out << "AIBinder_markVintfStability(binder);\n";
-  } else {
-    out << "AIBinder_markCompilationUnitStability(binder);\n";
-  }
-  out << "#endif  // BINDER_STABILITY_SUPPORT\n";
-
   out << "return ::ndk::SpAIBinder(binder);\n";
   out.Dedent();
   out << "}\n";
@@ -838,7 +773,7 @@
   for (const auto& variable : defined_type.GetFields()) {
     out << NdkNameOf(types, variable->GetType(), StorageMode::STACK) << " " << variable->GetName();
     if (variable->GetDefaultValue()) {
-      out << " = " << variable->ValueString(ConstantValueDecorator);
+      out << " = " << variable->ValueString(AidlConstantValueDecorator);
     }
     out << ";\n";
   }
@@ -925,27 +860,6 @@
   out << "\n";
   LeaveNdkNamespace(out, defined_type);
 }
-
-void GenerateEnumHeader(CodeWriter& out, const AidlTypenames& types,
-                        const AidlEnumDeclaration& enum_decl, const Options& /*options*/) {
-  out << "#pragma once\n";
-  out << "\n";
-
-  GenerateHeaderIncludes(out, types, enum_decl);
-
-  EnterNdkNamespace(out, enum_decl);
-  out << "enum class " << enum_decl.GetName() << " : "
-      << NdkNameOf(types, enum_decl.GetBackingType(), StorageMode::STACK) << " {\n";
-  out.Indent();
-  for (const auto& enumerator : enum_decl.GetEnumerators()) {
-    out << enumerator->GetName() << " = "
-        << enumerator->ValueString(enum_decl.GetBackingType(), ConstantValueDecorator) << ",\n";
-  }
-  out.Dedent();
-  out << "};\n";
-  LeaveNdkNamespace(out, enum_decl);
-}
-
 }  // namespace internals
 }  // namespace ndk
 }  // namespace aidl
diff --git a/generate_ndk.h b/generate_ndk.h
index 94a7669..740883e 100644
--- a/generate_ndk.h
+++ b/generate_ndk.h
@@ -52,9 +52,6 @@
 void GenerateParcelSource(CodeWriter& out, const AidlTypenames& types,
                           const AidlStructuredParcelable& defined_type, const Options& options);
 
-void GenerateEnumHeader(CodeWriter& out, const AidlTypenames& types,
-                        const AidlEnumDeclaration& enum_decl, const Options& options);
-
 }  // namespace internals
 }  // namespace ndk
 }  // namespace aidl
diff --git a/import_resolver.cpp b/import_resolver.cpp
index 0500cf8..4e4176f 100644
--- a/import_resolver.cpp
+++ b/import_resolver.cpp
@@ -17,8 +17,6 @@
 #include "import_resolver.h"
 #include "aidl_language.h"
 
-#include <algorithm>
-
 #include <android-base/file.h>
 #include <android-base/strings.h>
 #include <unistd.h>
@@ -67,10 +65,6 @@
       found_paths.emplace_back(path);
     }
   }
-  // remove duplicates
-  std::sort(found_paths.begin(), found_paths.end());
-  auto last = std::unique(found_paths.begin(), found_paths.end());
-  found_paths.erase(last, found_paths.end());
 
   int num_found = found_paths.size();
   if (num_found == 0) {
@@ -92,5 +86,5 @@
   }
 }
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/import_resolver.h b/import_resolver.h
index 0a34e05..569c94f 100644
--- a/import_resolver.h
+++ b/import_resolver.h
@@ -47,5 +47,5 @@
   DISALLOW_COPY_AND_ASSIGN(ImportResolver);
 };
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/io_delegate.h b/io_delegate.h
index a53bb8f..70556ad 100644
--- a/io_delegate.h
+++ b/io_delegate.h
@@ -65,5 +65,5 @@
   DISALLOW_COPY_AND_ASSIGN(IoDelegate);
 };  // class IoDelegate
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/io_delegate_unittest.cpp b/io_delegate_unittest.cpp
index 39982bc..5227d0b 100644
--- a/io_delegate_unittest.cpp
+++ b/io_delegate_unittest.cpp
@@ -42,5 +42,5 @@
   EXPECT_EQ(absolute_path[0], '/');
 }
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/line_reader.cpp b/line_reader.cpp
index 66446c0..5e076d8 100644
--- a/line_reader.cpp
+++ b/line_reader.cpp
@@ -87,5 +87,5 @@
   return unique_ptr<LineReader>(new MemoryLineReader(contents));
 }
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/line_reader.h b/line_reader.h
index 5883af4..baf9c06 100644
--- a/line_reader.h
+++ b/line_reader.h
@@ -39,5 +39,5 @@
   DISALLOW_COPY_AND_ASSIGN(LineReader);
 };  // class LineReader
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/main.cpp b/main.cpp
index 1199579..d21819a 100644
--- a/main.cpp
+++ b/main.cpp
@@ -25,6 +25,11 @@
 
 using android::aidl::Options;
 
+// aidl is leaky. Turn off LeakSanitizer by default. b/37749857
+extern "C" const char* __asan_default_options() {
+  return "detect_leaks=0";
+}
+
 int main(int argc, char* argv[]) {
   android::base::InitLogging(argv);
   LOG(DEBUG) << "aidl starting";
diff --git a/main_cpp.cpp b/main_cpp.cpp
index 5cb778c..72b3ffb 100644
--- a/main_cpp.cpp
+++ b/main_cpp.cpp
@@ -23,6 +23,11 @@
 
 using android::aidl::Options;
 
+// aidl is leaky. Turn off LeakSanitizer by default. b/37749857
+extern "C" const char *__asan_default_options() {
+    return "detect_leaks=0";
+}
+
 int main(int argc, char* argv[]) {
   android::base::InitLogging(argv);
   LOG(DEBUG) << "aidl starting";
diff --git a/options.cpp b/options.cpp
index fa34a9d..ff99dad 100644
--- a/options.cpp
+++ b/options.cpp
@@ -39,7 +39,7 @@
 string Options::GetUsage() const {
   std::ostringstream sstr;
   sstr << "usage:" << endl
-       << myname_ << " --lang={java|cpp|ndk} [OPTION]... INPUT..." << endl
+       << myname_ << " --lang={java|cpp} [OPTION]... INPUT..." << endl
        << "   Generate Java or C++ files for AIDL file(s)." << endl
        << endl
        << myname_ << " --preprocess OUTPUT INPUT..." << endl
@@ -90,8 +90,6 @@
        << "  --structured" << endl
        << "          Whether this interface is defined exclusively in AIDL." << endl
        << "          It is therefore a candidate for stabilization." << endl
-       << "  --stability=<level>" << endl
-       << "          The stability requirement of this interface." << endl
        << "  -t, --trace" << endl
        << "          Include tracing code for systrace. Note that if either" << endl
        << "          the client or service code is not auto-generated by this" << endl
@@ -112,9 +110,6 @@
        << "  --log" << endl
        << "          Information about the transaction, e.g., method name, argument" << endl
        << "          values, execution time, etc., is provided via callback." << endl
-       << "  --parcelable-to-string" << endl
-       << "          Generates an implementation of toString() for Java parcelables," << endl
-       << "          and ostream& operator << for C++ parcelables." << endl
        << "  --help" << endl
        << "          Show this help." << endl
        << endl
@@ -133,14 +128,6 @@
   return sstr.str();
 }
 
-bool Options::StabilityFromString(const std::string& stability, Stability* out_stability) {
-  if (stability == "vintf") {
-    *out_stability = Stability::VINTF;
-    return true;
-  }
-  return false;
-}
-
 Options Options::From(const string& cmdline) {
   vector<string> args = Split(cmdline, " ");
   return From(args);
@@ -181,13 +168,11 @@
         {"out", required_argument, 0, 'o'},
         {"header_out", required_argument, 0, 'h'},
         {"ninja", no_argument, 0, 'n'},
-        {"stability", required_argument, 0, 'Y'},
         {"structured", no_argument, 0, 'S'},
         {"trace", no_argument, 0, 't'},
         {"transaction_names", no_argument, 0, 'c'},
         {"version", required_argument, 0, 'v'},
         {"log", no_argument, 0, 'L'},
-        {"parcelable-to-string", no_argument, 0, 'P'},
         {"help", no_argument, 0, 'e'},
         {0, 0, 0, 0},
     };
@@ -273,15 +258,6 @@
       case 'S':
         structured_ = true;
         break;
-      case 'Y': {
-        const string stability_str = Trim(optarg);
-        if (!StabilityFromString(stability_str, &stability_)) {
-          error_message_ << "Unrecognized stability level: '" << stability_str
-                         << "'. Must be vintf." << endl;
-          return;
-        }
-        break;
-      }
       case 't':
         gen_traces_ = true;
         break;
@@ -316,9 +292,6 @@
         output_file_ = Trim(optarg);
         task_ = Task::DUMP_MAPPINGS;
         break;
-      case 'P':
-        gen_parcelable_to_string_ = true;
-        break;
       default:
         std::cerr << GetUsage();
         exit(1);
@@ -463,5 +436,5 @@
   CHECK(output_header_dir_.empty() || output_header_dir_.back() == OS_PATH_SEPARATOR);
 }
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/options.h b/options.h
index 43334a7..403301d 100644
--- a/options.h
+++ b/options.h
@@ -63,9 +63,6 @@
 
   enum class Task { UNSPECIFIED, COMPILE, PREPROCESS, DUMP_API, CHECK_API, DUMP_MAPPINGS };
 
-  enum class Stability { UNSPECIFIED, VINTF };
-  bool StabilityFromString(const std::string& stability, Stability* out_stability);
-
   Options(int argc, const char* const argv[], Language default_lang = Language::UNSPECIFIED);
 
   static Options From(const string& cmdline);
@@ -77,8 +74,6 @@
   // capacity to be stabilized.
   bool IsStructured() const { return structured_; }
 
-  Stability GetStability() const { return stability_; }
-
   Language TargetLanguage() const { return language_; }
   bool IsCppOutput() const { return language_ == Language::CPP || language_ == Language::NDK; }
 
@@ -123,8 +118,6 @@
 
   bool GenLog() const { return gen_log_; }
 
-  bool GenParcelableToString() const { return gen_parcelable_to_string_; }
-
   bool Ok() const { return error_message_.stream_.str().empty(); }
 
   string GetErrorMessage() const { return error_message_.stream_.str(); }
@@ -143,6 +136,7 @@
   Options() = default;
 
   const string myname_;
+  bool structured_ = false;
   Language language_ = Language::UNSPECIFIED;
   Task task_ = Task::COMPILE;
   set<string> import_dirs_;
@@ -152,8 +146,6 @@
   bool gen_traces_ = false;
   bool gen_transaction_names_ = false;
   bool dependency_file_ninja_ = false;
-  bool structured_ = false;
-  Stability stability_ = Stability::UNSPECIFIED;
   string output_dir_;
   string output_header_dir_;
   bool fail_on_parcelable_ = false;
@@ -162,9 +154,8 @@
   string output_file_;
   int version_ = 0;
   bool gen_log_ = false;
-  bool gen_parcelable_to_string_ = false;
   ErrorMessage error_message_;
 };
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/options_unittest.cpp b/options_unittest.cpp
index 97b4c0c..27cfb9d 100644
--- a/options_unittest.cpp
+++ b/options_unittest.cpp
@@ -135,23 +135,6 @@
   EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
   EXPECT_EQ(false, options->AutoDepFile());
   EXPECT_EQ(false, options->DependencyFileNinja());
-  EXPECT_EQ(false, options->GenParcelableToString());
-
-  const char* argv[] = {
-      "aidl",  "-b", kCompileCommandIncludePath, kCompileCommandInput, "--parcelable-to-string",
-      nullptr,
-  };
-  options = GetOptions(argv);
-  EXPECT_EQ(Options::Task::COMPILE, options->GetTask());
-  EXPECT_EQ(Options::Language::JAVA, options->TargetLanguage());
-  EXPECT_EQ(true, options->FailOnParcelable());
-  EXPECT_EQ(1u, options->ImportDirs().size());
-  EXPECT_EQ(0u, options->PreprocessedFiles().size());
-  EXPECT_EQ(string{kCompileCommandInput}, options->InputFiles().front());
-  EXPECT_EQ(string{kCompileCommandJavaOutput}, options->OutputFile());
-  EXPECT_EQ(false, options->AutoDepFile());
-  EXPECT_EQ(false, options->DependencyFileNinja());
-  EXPECT_EQ(true, options->GenParcelableToString());
 }
 
 TEST(OptionsTests, ParsesCompileJavaNinja) {
@@ -176,27 +159,6 @@
   EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
   EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
   EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
-  EXPECT_EQ(false, options->GenParcelableToString());
-
-  const char* argv[] = {
-      "aidl-cpp",
-      kCompileCommandIncludePath,
-      kCompileDepFile,
-      kCompileCommandInput,
-      kCompileCommandHeaderDir,
-      kCompileCommandCppOutput,
-      "--parcelable-to-string",
-      nullptr,
-  };
-  options = GetOptions(argv, Options::Language::CPP);
-  ASSERT_EQ(1u, options->ImportDirs().size());
-  EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2), *options->ImportDirs().begin());
-  EXPECT_EQ(string{kCompileDepFile}.substr(2), options->DependencyFile());
-  EXPECT_EQ(false, options->DependencyFileNinja());
-  EXPECT_EQ(kCompileCommandInput, options->InputFiles().front());
-  EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
-  EXPECT_EQ(kCompileCommandCppOutput, options->OutputFile());
-  EXPECT_EQ(true, options->GenParcelableToString());
 }
 
 TEST(OptionsTests, ParsesCompileCppNinja) {
@@ -314,5 +276,5 @@
   EXPECT_EQ(false, GetOptions(arg_with_no_header_dir)->Ok());
 }
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/runtests.sh b/runtests.sh
index 5f99122..aff108f 100755
--- a/runtests.sh
+++ b/runtests.sh
@@ -20,16 +20,22 @@
 fi
 
 echo "Running tests"
-set -ex
+set -e # fail early
 
+# NOTE We can't actually run these commands, since they rely on functions added
+#      by build/envsetup.sh to the bash shell environment.
+echo "+ mmma $ANDROID_BUILD_TOP/system/tools/aidl"
 $ANDROID_BUILD_TOP/build/soong/soong_ui.bash --make-mode \
     MODULES-IN-system-tools-aidl
 
+set -x # print commands
 
 ${ANDROID_HOST_OUT}/nativetest64/aidl_unittests/aidl_unittests
 
 adb root
-adb sync data
+adb wait-for-device
+adb remount
+adb sync
 adb install -r \
     ${ANDROID_PRODUCT_OUT}/system/app/aidl_test_services/aidl_test_services.apk
 ${ANDROID_BUILD_TOP}/system/tools/aidl/tests/integration-test.py
diff --git a/runtests_asan.sh b/runtests_asan.sh
deleted file mode 100755
index b796fba..0000000
--- a/runtests_asan.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env bash
-
-# Copyright (C) 2019 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-export ASAN_OPTIONS=""
-export SANITIZE_HOST=address
-
-./runtests.sh
-
diff --git a/tests/aidl_parser_fuzzer.cpp b/tests/aidl_parser_fuzzer.cpp
deleted file mode 100644
index a3269ce..0000000
--- a/tests/aidl_parser_fuzzer.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "aidl.h"
-#include "fake_io_delegate.h"
-#include "options.h"
-
-#include <iostream>
-
-#ifdef FUZZ_LOG
-constexpr bool kFuzzLog = true;
-#else
-constexpr bool kFuzzLog = false;
-#endif
-
-using android::aidl::test::FakeIoDelegate;
-
-void fuzz(uint8_t options, const std::string& content) {
-  uint8_t lang = options & 0x3;
-  std::string langOpt;
-  switch (lang) {
-    case 1:
-      langOpt = "cpp";
-      break;
-    case 2:
-      langOpt = "ndk";
-      break;
-    case 3:
-      langOpt = "java";
-      break;
-    default:
-      return;
-  }
-
-  // TODO: fuzz multiple files
-  // TODO: fuzz arguments
-  FakeIoDelegate io;
-  io.SetFileContents("a/path/Foo.aidl", content);
-
-  std::vector<std::string> args;
-  args.emplace_back("aidl");
-  args.emplace_back("--lang=" + langOpt);
-  args.emplace_back("-b");
-  args.emplace_back("-I .");
-  args.emplace_back("-o out");
-  // corresponding items also in aidl_parser_fuzzer.dict
-  args.emplace_back("a/path/Foo.aidl");
-
-  if (kFuzzLog) {
-    std::cout << "lang: " << langOpt << " content: " << content << std::endl;
-  }
-
-  int ret = android::aidl::compile_aidl(Options::From(args), io);
-  if (ret != 0) return;
-
-  if (kFuzzLog) {
-    for (const std::string& f : io.ListOutputFiles()) {
-      std::string output;
-      if (io.GetWrittenContents(f, &output)) {
-        std::cout << "OUTPUT " << f << ": " << std::endl;
-        std::cout << output << std::endl;
-      }
-    }
-  }
-}
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
-  if (size <= 1) return 0;  // no use
-
-  uint8_t options = *data;
-  data++;
-  size--;
-
-  std::string content(reinterpret_cast<const char*>(data), size);
-  fuzz(options, content);
-
-  return 0;
-}
diff --git a/tests/aidl_parser_fuzzer.dict b/tests/aidl_parser_fuzzer.dict
deleted file mode 100644
index 1f882a0..0000000
--- a/tests/aidl_parser_fuzzer.dict
+++ /dev/null
@@ -1,62 +0,0 @@
-# keywords
-" parcelable "
-" import "
-" package "
-" in "
-" out "
-" inout "
-" cpp_header "
-" const "
-" true "
-" false "
-" interface "
-" oneway "
-" enum "
-
-# types
-" void "
-" boolean "
-" byte "
-" char "
-" int "
-" long "
-" float "
-" double "
-" String "
-" List "
-" Map "
-" IBinder "
-" FileDescriptor "
-" CharSequence "
-" ParcelFileDescriptor "
-" java.util.List "
-" java.util.Map "
-" android.os.ParcelFileDescriptor "
-
-# annotations
-" @nullable "
-" @utf8InCpp "
-" @VintfStability "
-" @UnsupportedAppUsage "
-" @SystemApi "
-" @JavaOnlyStableParcelable "
-" @Backing "
-" expectedSignature "
-" implicitMember "
-" maxTargetSdk "
-" publicAlternatives "
-" trackingBug "
-" type "
-
-# ignorable imports
-" android.os.IInterface "
-" android.os.IBinder "
-" android.os.Parcelable "
-" android.os.Parcel "
-" android.content.Context "
-" java.lang.String "
-
-# specific to fuzzer
-" a.path "
-" Foo "
-
diff --git a/tests/aidl_test_client.cpp b/tests/aidl_test_client.cpp
index 678edc5..f4850b0 100644
--- a/tests/aidl_test_client.cpp
+++ b/tests/aidl_test_client.cpp
@@ -90,12 +90,8 @@
 
   if (!client_tests::ConfirmPersistableBundles(service)) return 1;
 
-  if (!client_tests::ConfirmIntfConstantExpressions(service)) return 1;
-
   if (!client_tests::ConfirmStructuredParcelables(service)) return 1;
 
-  if (!client_tests::ConfirmStructuredParcelablesEquality(service)) return 1;
-
   if (!client_tests::ConfirmFileDescriptors(service)) return 1;
 
   if (!client_tests::ConfirmFileDescriptorArrays(service)) return 1;
diff --git a/tests/aidl_test_client_nullables.cpp b/tests/aidl_test_client_nullables.cpp
index f4eab3a..805827c 100644
--- a/tests/aidl_test_client_nullables.cpp
+++ b/tests/aidl_test_client_nullables.cpp
@@ -31,10 +31,7 @@
 using android::binder::Status;
 
 // generated
-using android::aidl::tests::ByteEnum;
-using android::aidl::tests::IntEnum;
 using android::aidl::tests::ITestService;
-using android::aidl::tests::LongEnum;
 using android::aidl::tests::SimpleParcelable;
 
 using std::string;
@@ -235,27 +232,6 @@
     return false;
   }
 
-  if (!ConfirmNullableType(
-          s, "byte enum array",
-          unique_ptr<vector<ByteEnum>>(new vector<ByteEnum>({ByteEnum::FOO, ByteEnum::BAR})),
-          &ITestService::RepeatNullableByteEnumArray)) {
-    return false;
-  }
-
-  if (!ConfirmNullableType(
-          s, "int enum array",
-          unique_ptr<vector<IntEnum>>(new vector<IntEnum>({IntEnum::FOO, IntEnum::BAR})),
-          &ITestService::RepeatNullableIntEnumArray)) {
-    return false;
-  }
-
-  if (!ConfirmNullableType(
-          s, "long enum array",
-          unique_ptr<vector<LongEnum>>(new vector<LongEnum>({LongEnum::FOO, LongEnum::BAR})),
-          &ITestService::RepeatNullableLongEnumArray)) {
-    return false;
-  }
-
   if (!ConfirmNullableType(s, "string",
                            unique_ptr<String16>(new String16("Blooob")),
                            &ITestService::RepeatNullableString)) {
diff --git a/tests/aidl_test_client_parcelables.cpp b/tests/aidl_test_client_parcelables.cpp
index cc89270..7f52d73 100644
--- a/tests/aidl_test_client_parcelables.cpp
+++ b/tests/aidl_test_client_parcelables.cpp
@@ -26,7 +26,6 @@
 using android::binder::Status;
 
 // generated
-using android::aidl::tests::ConstantExpressionEnum;
 using android::aidl::tests::ITestService;
 using android::aidl::tests::SimpleParcelable;
 using android::os::PersistableBundle;
@@ -146,69 +145,7 @@
   return true;
 }
 
-bool ConfirmStructuredParcelablesEquality(const sp<ITestService>& s) {
-  StructuredParcelable parcelable1;
-  StructuredParcelable parcelable2;
-
-  parcelable1.f = 11;
-  parcelable2.f = 11;
-
-  s->FillOutStructuredParcelable(&parcelable1);
-  s->FillOutStructuredParcelable(&parcelable2);
-
-  sp<INamedCallback> callback1;
-  sp<INamedCallback> callback2;
-  s->GetOtherTestService(String16("callback1"), &callback1);
-  s->GetOtherTestService(String16("callback2"), &callback2);
-
-  parcelable1.ibinder = IInterface::asBinder(callback1);
-  parcelable2.ibinder = IInterface::asBinder(callback1);
-
-  if (parcelable1 != parcelable2) {
-    cout << "parcelable1 and parcelable2 should be same." << endl;
-    return false;
-  }
-  parcelable1.f = 0;
-  if (parcelable1 >= parcelable2) {
-    cout << "parcelable1 and parcelable2 should be different because of shouldContainThreeFs"
-         << endl;
-    return false;
-  }
-  parcelable1.f = 11;
-
-  parcelable1.shouldBeJerry = "Jarry";
-  if (!(parcelable1 < parcelable2)) {
-    cout << "parcelable1 and parcelable2 should be different because of shouldContainThreeFs"
-         << endl;
-    return false;
-  }
-  parcelable1.shouldBeJerry = "Jerry";
-
-  parcelable2.shouldContainThreeFs = {};
-  if (parcelable1 <= parcelable2) {
-    cout << "parcelable1 and parcelable2 should be different because of shouldContainThreeFs"
-         << endl;
-    return false;
-  }
-  parcelable2.shouldContainThreeFs = {parcelable2.f, parcelable2.f, parcelable2.f};
-
-  parcelable2.shouldBeIntBar = IntEnum::FOO;
-  if (!(parcelable1 > parcelable2)) {
-    cout << "parcelable1 and parcelable2 should be different because of shouldBeIntBar" << endl;
-    return false;
-  }
-  parcelable2.shouldBeIntBar = IntEnum::BAR;
-
-  parcelable2.ibinder = IInterface::asBinder(callback2);
-  if (parcelable1 == parcelable2) {
-    cout << "parcelable1 and parcelable2 should be different because of ibinder" << endl;
-    return false;
-  }
-  return true;
-}
-
 bool ConfirmStructuredParcelables(const sp<ITestService>& s) {
-  bool success = true;
   constexpr int kDesiredValue = 23;
 
   StructuredParcelable parcelable;
@@ -284,119 +221,6 @@
     return false;
   }
 
-  if (parcelable.int32_min != INT32_MIN) {
-    cout << "int32_min should be " << INT32_MIN << "but is " << parcelable.int32_min << endl;
-    return false;
-  }
-
-  if (parcelable.int32_max != INT32_MAX) {
-    cout << "int32_max should be " << INT32_MAX << "but is " << parcelable.int32_max << endl;
-    return false;
-  }
-
-  if (parcelable.int64_max != INT64_MAX) {
-    cout << "int64_max should be " << INT64_MAX << "but is " << parcelable.int64_max << endl;
-    return false;
-  }
-
-  if (parcelable.hexInt32_neg_1 != -1) {
-    cout << "hexInt32_neg_1 should be -1 but is " << parcelable.hexInt32_neg_1 << endl;
-    return false;
-  }
-
-  for (size_t ndx = 0; ndx < parcelable.int32_1.size(); ndx++) {
-    if (parcelable.int32_1[ndx] != 1) {
-      cout << "int32_1[" << ndx << "] should be 1 but is " << parcelable.int32_1[ndx] << endl;
-      success = false;
-    }
-  }
-  if (!success) {
-    return false;
-  }
-
-  for (size_t ndx = 0; ndx < parcelable.int64_1.size(); ndx++) {
-    if (parcelable.int64_1[ndx] != 1) {
-      cout << "int64_1[" << ndx << "] should be 1 but is " << parcelable.int64_1[ndx] << endl;
-      success = false;
-    }
-  }
-  if (!success) {
-    return false;
-  }
-
-  if (static_cast<int>(parcelable.hexInt32_pos_1) != 1) {
-    cout << "hexInt32_pos_1 should be 1 but is " << parcelable.hexInt32_pos_1 << endl;
-    return false;
-  }
-
-  if (parcelable.hexInt64_pos_1 != 1) {
-    cout << "hexInt64_pos_1 should be 1 but is " << parcelable.hexInt64_pos_1 << endl;
-    return false;
-  }
-
-  if (static_cast<int>(parcelable.const_exprs_1) != 1) {
-    cout << "parcelable.const_exprs_1 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_1) << endl;
-    return false;
-  }
-  if (static_cast<int>(parcelable.const_exprs_2) != 1) {
-    cout << "parcelable.const_exprs_2 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_2) << endl;
-    return false;
-  }
-  if (static_cast<int>(parcelable.const_exprs_3) != 1) {
-    cout << "parcelable.const_exprs_3 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_3) << endl;
-    return false;
-  }
-  if (static_cast<int>(parcelable.const_exprs_4) != 1) {
-    cout << "parcelable.const_exprs_4 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_4) << endl;
-    return false;
-  }
-  if (static_cast<int>(parcelable.const_exprs_5) != 1) {
-    cout << "parcelable.const_exprs_5 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_5) << endl;
-    return false;
-  }
-  if (static_cast<int>(parcelable.const_exprs_6) != 1) {
-    cout << "parcelable.const_exprs_6 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_6) << endl;
-    return false;
-  }
-  if (static_cast<int>(parcelable.const_exprs_7) != 1) {
-    cout << "parcelable.const_exprs_7 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_7) << endl;
-    return false;
-  }
-  if (static_cast<int>(parcelable.const_exprs_8) != 1) {
-    cout << "parcelable.const_exprs_8 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_8) << endl;
-    return false;
-  }
-  if (static_cast<int>(parcelable.const_exprs_9) != 1) {
-    cout << "parcelable.const_exprs_9 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_9) << endl;
-    return false;
-  }
-  if (static_cast<int>(parcelable.const_exprs_10) != 1) {
-    cout << "parcelable.const_exprs_10 should be 1 but is "
-         << static_cast<int>(parcelable.const_exprs_10) << endl;
-    return false;
-  }
-
-  if (parcelable.addString1 != "hello world!") {
-    cout << "parcelable.addString1 should be \"hello world!\" but is \"" << parcelable.addString1
-         << "\"" << endl;
-    return false;
-  }
-  if (parcelable.addString2 != "The quick brown fox jumps over the lazy dog.") {
-    cout << "parcelable.addString2 should be \"The quick brown fox jumps over the lazy dog.\""
-            " but is \""
-         << parcelable.addString2 << "\"" << endl;
-    return false;
-  }
-
   return true;
 }
 
diff --git a/tests/aidl_test_client_parcelables.h b/tests/aidl_test_client_parcelables.h
index 3031ad4..168f6cd 100644
--- a/tests/aidl_test_client_parcelables.h
+++ b/tests/aidl_test_client_parcelables.h
@@ -30,7 +30,6 @@
 bool ConfirmSimpleParcelables(const sp<ITestService>& s);
 bool ConfirmPersistableBundles(const sp<ITestService>& s);
 bool ConfirmStructuredParcelables(const sp<ITestService>& s);
-bool ConfirmStructuredParcelablesEquality(const sp<ITestService>& s);
 
 }  // namespace client
 }  // namespace tests
diff --git a/tests/aidl_test_client_primitives.cpp b/tests/aidl_test_client_primitives.cpp
index 2733800..98df528 100644
--- a/tests/aidl_test_client_primitives.cpp
+++ b/tests/aidl_test_client_primitives.cpp
@@ -21,11 +21,10 @@
 
 #include <utils/String16.h>
 #include <utils/String8.h>
+#include <binder/Value.h>
+#include <binder/Map.h>
 
-#include "android/aidl/tests/ByteEnum.h"
 #include "android/aidl/tests/INamedCallback.h"
-#include "android/aidl/tests/IntEnum.h"
-#include "android/aidl/tests/LongEnum.h"
 
 #include "test_helpers.h"
 
@@ -36,6 +35,8 @@
 
 // libbinder:
 using android::binder::Status;
+using android::binder::Value;
+using android::binder::Map;
 
 // generated
 using android::aidl::tests::ITestService;
@@ -54,28 +55,44 @@
 bool ConfirmPrimitiveRepeat(const sp<ITestService>& s) {
   cout << "Confirming passing and returning primitives works." << endl;
 
+  Map test_map;
+  test_map["first_val"] = int8_t{-128};
+  test_map["second_val"] = int32_t{1 << 30};
+  test_map["third_val"] = String16("OHAI");
+
   if (!RepeatPrimitive(s, &ITestService::RepeatBoolean, true) ||
       !RepeatPrimitive(s, &ITestService::RepeatByte, int8_t{-128}) ||
       !RepeatPrimitive(s, &ITestService::RepeatChar, char16_t{'A'}) ||
       !RepeatPrimitive(s, &ITestService::RepeatInt, int32_t{1 << 30}) ||
       !RepeatPrimitive(s, &ITestService::RepeatLong, int64_t{1LL << 60}) ||
-      !RepeatPrimitive(s, &ITestService::RepeatFloat, float{1.0f / 3.0f}) ||
-      !RepeatPrimitive(s, &ITestService::RepeatDouble, double{1.0 / 3.0}) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT2) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT3) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT4) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT5) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT6) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT7) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT8) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT9) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT10) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT11) ||
-      !RepeatPrimitive(s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT12) ||
-      !RepeatPrimitive(s, &ITestService::RepeatByteEnum, ByteEnum::FOO) ||
-      !RepeatPrimitive(s, &ITestService::RepeatIntEnum, IntEnum::BAR) ||
-      !RepeatPrimitive(s, &ITestService::RepeatLongEnum, LongEnum::FOO)) {
+      !RepeatPrimitive(s, &ITestService::RepeatFloat, float{1.0f/3.0f}) ||
+      !RepeatPrimitive(s, &ITestService::RepeatDouble, double{1.0/3.0}) ||
+      !RepeatPrimitive(s, &ITestService::RepeatMap, test_map) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT)  ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT2) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT3) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT4) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT5) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT6) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT7) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT8) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT9) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT10) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT11) ||
+      !RepeatPrimitive(
+          s, &ITestService::RepeatInt, ITestService::TEST_CONSTANT12)
+      ) {
     return false;
   }
 
@@ -106,20 +123,22 @@
 bool ConfirmReverseArrays(const sp<ITestService>& s) {
   cout << "Confirming passing and returning arrays works." << endl;
 
-  if (!ReverseArray(s, &ITestService::ReverseBoolean, {true, false, false}) ||
-      !ReverseArray(s, &ITestService::ReverseByte, {uint8_t{255}, uint8_t{0}, uint8_t{127}}) ||
-      !ReverseArray(s, &ITestService::ReverseChar, {char16_t{'A'}, char16_t{'B'}, char16_t{'C'}}) ||
-      !ReverseArray(s, &ITestService::ReverseInt, {1, 2, 3}) ||
-      !ReverseArray(s, &ITestService::ReverseLong, {-1LL, 0LL, int64_t{1LL << 60}}) ||
-      !ReverseArray(s, &ITestService::ReverseFloat, {-0.3f, -0.7f, 8.0f}) ||
-      !ReverseArray(s, &ITestService::ReverseDouble, {1.0 / 3.0, 1.0 / 7.0, 42.0}) ||
+  if (!ReverseArray(s, &ITestService::ReverseBoolean,
+                    {true, false, false}) ||
+      !ReverseArray(s, &ITestService::ReverseByte,
+                    {uint8_t{255}, uint8_t{0}, uint8_t{127}}) ||
+      !ReverseArray(s, &ITestService::ReverseChar,
+                    {char16_t{'A'}, char16_t{'B'}, char16_t{'C'}}) ||
+      !ReverseArray(s, &ITestService::ReverseInt,
+                    {1, 2, 3}) ||
+      !ReverseArray(s, &ITestService::ReverseLong,
+                    {-1LL, 0LL, int64_t{1LL << 60}}) ||
+      !ReverseArray(s, &ITestService::ReverseFloat,
+                    {-0.3f, -0.7f, 8.0f}) ||
+      !ReverseArray(s, &ITestService::ReverseDouble,
+                    {1.0/3.0, 1.0/7.0, 42.0}) ||
       !ReverseArray(s, &ITestService::ReverseString,
-                    {String16{"f"}, String16{"a"}, String16{"b"}}) ||
-      !ReverseArray(s, &ITestService::ReverseByteEnum,
-                    {ByteEnum::FOO, ByteEnum::BAR, ByteEnum::BAR}) ||
-      !ReverseArray(s, &ITestService::ReverseIntEnum, {IntEnum::FOO, IntEnum::BAR, IntEnum::BAR}) ||
-      !ReverseArray(s, &ITestService::ReverseLongEnum,
-                    {LongEnum::FOO, LongEnum::BAR, LongEnum::BAR})) {
+                    {String16{"f"}, String16{"a"}, String16{"b"}})) {
     return false;
   }
 
@@ -216,242 +235,6 @@
   return true;
 }
 
-bool ConfirmIntfConstantExpressions(const sp<ITestService>& s) {
-  (void)s;
-  bool ret = true;
-
-  if (ITestService::A1 != 1) {
-    cerr << "ITestService::A1 should be 1 but is " << ITestService::A1 << endl;
-    ret = false;
-  }
-  if (ITestService::A2 != 1) {
-    cerr << "ITestService::A2 should be 1 but is " << ITestService::A2 << endl;
-    ret = false;
-  }
-  if (ITestService::A3 != 1) {
-    cerr << "ITestService::A3 should be 1 but is " << ITestService::A3 << endl;
-    ret = false;
-  }
-  if (ITestService::A4 != 1) {
-    cerr << "ITestService::A4 should be 1 but is " << ITestService::A4 << endl;
-    ret = false;
-  }
-  if (ITestService::A5 != 1) {
-    cerr << "ITestService::A5 should be 1 but is " << ITestService::A5 << endl;
-    ret = false;
-  }
-  if (ITestService::A6 != 1) {
-    cerr << "ITestService::A6 should be 1 but is " << ITestService::A6 << endl;
-    ret = false;
-  }
-  if (ITestService::A7 != 1) {
-    cerr << "ITestService::A7 should be 1 but is " << ITestService::A7 << endl;
-    ret = false;
-  }
-  if (ITestService::A8 != 1) {
-    cerr << "ITestService::A8 should be 1 but is " << ITestService::A8 << endl;
-    ret = false;
-  }
-  if (ITestService::A9 != 1) {
-    cerr << "ITestService::A9 should be 1 but is " << ITestService::A9 << endl;
-    ret = false;
-  }
-  if (ITestService::A10 != 1) {
-    cerr << "ITestService::A10 should be 1 but is " << ITestService::A10 << endl;
-    ret = false;
-  }
-  if (ITestService::A11 != 1) {
-    cerr << "ITestService::A11 should be 1 but is " << ITestService::A11 << endl;
-    ret = false;
-  }
-  if (ITestService::A12 != 1) {
-    cerr << "ITestService::A12 should be 1 but is " << ITestService::A12 << endl;
-    ret = false;
-  }
-  if (ITestService::A13 != 1) {
-    cerr << "ITestService::A13 should be 1 but is " << ITestService::A13 << endl;
-    ret = false;
-  }
-  if (ITestService::A14 != 1) {
-    cerr << "ITestService::A14 should be 1 but is " << ITestService::A14 << endl;
-    ret = false;
-  }
-  if (ITestService::A15 != 1) {
-    cerr << "ITestService::A15 should be 1 but is " << ITestService::A15 << endl;
-    ret = false;
-  }
-  if (ITestService::A16 != 1) {
-    cerr << "ITestService::A16 should be 1 but is " << ITestService::A16 << endl;
-    ret = false;
-  }
-  if (ITestService::A17 != 1) {
-    cerr << "ITestService::A17 should be 1 but is " << ITestService::A17 << endl;
-    ret = false;
-  }
-  if (ITestService::A18 != 1) {
-    cerr << "ITestService::A18 should be 1 but is " << ITestService::A18 << endl;
-    ret = false;
-  }
-  if (ITestService::A19 != 1) {
-    cerr << "ITestService::A19 should be 1 but is " << ITestService::A19 << endl;
-    ret = false;
-  }
-  if (ITestService::A20 != 1) {
-    cerr << "ITestService::A20 should be 1 but is " << ITestService::A20 << endl;
-    ret = false;
-  }
-  if (ITestService::A21 != 1) {
-    cerr << "ITestService::A21 should be 1 but is " << ITestService::A21 << endl;
-    ret = false;
-  }
-  if (ITestService::A22 != 1) {
-    cerr << "ITestService::A22 should be 1 but is " << ITestService::A22 << endl;
-    ret = false;
-  }
-  if (ITestService::A23 != 1) {
-    cerr << "ITestService::A23 should be 1 but is " << ITestService::A23 << endl;
-    ret = false;
-  }
-  if (ITestService::A24 != 1) {
-    cerr << "ITestService::A24 should be 1 but is " << ITestService::A24 << endl;
-    ret = false;
-  }
-  if (ITestService::A25 != 1) {
-    cerr << "ITestService::A25 should be 1 but is " << ITestService::A25 << endl;
-    ret = false;
-  }
-  if (ITestService::A26 != 1) {
-    cerr << "ITestService::A26 should be 1 but is " << ITestService::A26 << endl;
-    ret = false;
-  }
-  if (ITestService::A27 != 1) {
-    cerr << "ITestService::A27 should be 1 but is " << ITestService::A27 << endl;
-    ret = false;
-  }
-  if (ITestService::A28 != 1) {
-    cerr << "ITestService::A28 should be 1 but is " << ITestService::A28 << endl;
-    ret = false;
-  }
-  if (ITestService::A29 != 1) {
-    cerr << "ITestService::A29 should be 1 but is " << ITestService::A29 << endl;
-    ret = false;
-  }
-  if (ITestService::A30 != 1) {
-    cerr << "ITestService::A30 should be 1 but is " << ITestService::A30 << endl;
-    ret = false;
-  }
-  if (ITestService::A31 != 1) {
-    cerr << "ITestService::A31 should be 1 but is " << ITestService::A31 << endl;
-    ret = false;
-  }
-  if (ITestService::A32 != 1) {
-    cerr << "ITestService::A32 should be 1 but is " << ITestService::A32 << endl;
-    ret = false;
-  }
-  if (ITestService::A33 != 1) {
-    cerr << "ITestService::A33 should be 1 but is " << ITestService::A33 << endl;
-    ret = false;
-  }
-  if (ITestService::A34 != 1) {
-    cerr << "ITestService::A34 should be 1 but is " << ITestService::A34 << endl;
-    ret = false;
-  }
-  if (ITestService::A35 != 1) {
-    cerr << "ITestService::A35 should be 1 but is " << ITestService::A35 << endl;
-    ret = false;
-  }
-  if (ITestService::A36 != 1) {
-    cerr << "ITestService::A36 should be 1 but is " << ITestService::A36 << endl;
-    ret = false;
-  }
-  if (ITestService::A37 != 1) {
-    cerr << "ITestService::A37 should be 1 but is " << ITestService::A37 << endl;
-    ret = false;
-  }
-  if (ITestService::A38 != 1) {
-    cerr << "ITestService::A38 should be 1 but is " << ITestService::A38 << endl;
-    ret = false;
-  }
-  if (ITestService::A39 != 1) {
-    cerr << "ITestService::A39 should be 1 but is " << ITestService::A39 << endl;
-    ret = false;
-  }
-  if (ITestService::A40 != 1) {
-    cerr << "ITestService::A40 should be 1 but is " << ITestService::A40 << endl;
-    ret = false;
-  }
-  if (ITestService::A41 != 1) {
-    cerr << "ITestService::A41 should be 1 but is " << ITestService::A41 << endl;
-    ret = false;
-  }
-  if (ITestService::A42 != 1) {
-    cerr << "ITestService::A42 should be 1 but is " << ITestService::A42 << endl;
-    ret = false;
-  }
-  if (ITestService::A43 != 1) {
-    cerr << "ITestService::A43 should be 1 but is " << ITestService::A43 << endl;
-    ret = false;
-  }
-  if (ITestService::A44 != 1) {
-    cerr << "ITestService::A44 should be 1 but is " << ITestService::A44 << endl;
-    ret = false;
-  }
-  if (ITestService::A45 != 1) {
-    cerr << "ITestService::A45 should be 1 but is " << ITestService::A45 << endl;
-    ret = false;
-  }
-  if (ITestService::A46 != 1) {
-    cerr << "ITestService::A46 should be 1 but is " << ITestService::A46 << endl;
-    ret = false;
-  }
-  if (ITestService::A47 != 1) {
-    cerr << "ITestService::A47 should be 1 but is " << ITestService::A47 << endl;
-    ret = false;
-  }
-  if (ITestService::A48 != 1) {
-    cerr << "ITestService::A48 should be 1 but is " << ITestService::A48 << endl;
-    ret = false;
-  }
-  if (ITestService::A49 != 1) {
-    cerr << "ITestService::A49 should be 1 but is " << ITestService::A49 << endl;
-    ret = false;
-  }
-  if (ITestService::A50 != 1) {
-    cerr << "ITestService::A50 should be 1 but is " << ITestService::A50 << endl;
-    ret = false;
-  }
-  if (ITestService::A51 != 1) {
-    cerr << "ITestService::A51 should be 1 but is " << ITestService::A51 << endl;
-    ret = false;
-  }
-  if (ITestService::A52 != 1) {
-    cerr << "ITestService::A52 should be 1 but is " << ITestService::A52 << endl;
-    ret = false;
-  }
-  if (ITestService::A53 != 1) {
-    cerr << "ITestService::A53 should be 1 but is " << ITestService::A53 << endl;
-    ret = false;
-  }
-  if (ITestService::A54 != 1) {
-    cerr << "ITestService::A54 should be 1 but is " << ITestService::A54 << endl;
-    ret = false;
-  }
-  if (ITestService::A55 != 1) {
-    cerr << "ITestService::A55 should be 1 but is " << ITestService::A55 << endl;
-    ret = false;
-  }
-  if (ITestService::A56 != 1) {
-    cerr << "ITestService::A56 should be 1 but is " << ITestService::A56 << endl;
-    ret = false;
-  }
-  if (ITestService::A57 != 1) {
-    cerr << "ITestService::A57 should be 1 but is " << ITestService::A57 << endl;
-    ret = false;
-  }
-
-  return ret;
-}
-
 }  // namespace client
 }  // namespace tests
 }  // namespace aidl
diff --git a/tests/aidl_test_client_primitives.h b/tests/aidl_test_client_primitives.h
index 0c2fef5..f9b39da 100644
--- a/tests/aidl_test_client_primitives.h
+++ b/tests/aidl_test_client_primitives.h
@@ -31,7 +31,6 @@
 bool ConfirmReverseArrays(const android::sp<ITestService>& s);
 bool ConfirmReverseLists(const android::sp<ITestService>& s);
 bool ConfirmReverseBinderLists(const android::sp<ITestService>& s);
-bool ConfirmIntfConstantExpressions(const sp<ITestService>& s);
 
 }  // namespace client
 }  // namespace tests
diff --git a/tests/aidl_test_service.cpp b/tests/aidl_test_service.cpp
index 3b0deed..6bb8a63 100644
--- a/tests/aidl_test_service.cpp
+++ b/tests/aidl_test_service.cpp
@@ -27,6 +27,7 @@
 #include <binder/IServiceManager.h>
 #include <binder/ProcessState.h>
 #include <binder/Status.h>
+#include <binder/Value.h>
 #include <utils/Errors.h>
 #include <utils/Log.h>
 #include <utils/Looper.h>
@@ -64,12 +65,9 @@
 // Generated code:
 using android::aidl::tests::BnNamedCallback;
 using android::aidl::tests::BnTestService;
-using android::aidl::tests::ByteEnum;
-using android::aidl::tests::ConstantExpressionEnum;
 using android::aidl::tests::INamedCallback;
-using android::aidl::tests::IntEnum;
-using android::aidl::tests::LongEnum;
 using android::aidl::tests::SimpleParcelable;
+using android::binder::Map;
 using android::os::ParcelFileDescriptor;
 using android::os::PersistableBundle;
 
@@ -122,6 +120,10 @@
     ALOGI("Repeating token %s", token_str.str().c_str());
   }
 
+  void LogRepeatedMapToken(const Map& token) {
+    ALOGI("Repeating Map with %d elements", (int)token.size());
+  }
+
   Status RepeatBoolean(bool token, bool* _aidl_return) override {
     LogRepeatedToken(token ? 1 : 0);
     *_aidl_return = token;
@@ -162,18 +164,8 @@
     *_aidl_return = token;
     return Status::ok();
   }
-  Status RepeatByteEnum(ByteEnum token, ByteEnum* _aidl_return) override {
-    ALOGI("Repeating ByteEnum token %d", static_cast<int8_t>(token));
-    *_aidl_return = token;
-    return Status::ok();
-  }
-  Status RepeatIntEnum(IntEnum token, IntEnum* _aidl_return) override {
-    ALOGI("Repeating IntEnum token %d", static_cast<int8_t>(token));
-    *_aidl_return = token;
-    return Status::ok();
-  }
-  Status RepeatLongEnum(LongEnum token, LongEnum* _aidl_return) override {
-    ALOGI("Repeating LongEnum token %d", static_cast<int8_t>(token));
+  Status RepeatMap(const Map& token, Map* _aidl_return) override {
+    LogRepeatedMapToken(token);
     *_aidl_return = token;
     return Status::ok();
   }
@@ -257,18 +249,6 @@
                        vector<String16>* _aidl_return) override {
     return ReverseArray(input, repeated, _aidl_return);
   }
-  Status ReverseByteEnum(const vector<ByteEnum>& input, vector<ByteEnum>* repeated,
-                         vector<ByteEnum>* _aidl_return) override {
-    return ReverseArray(input, repeated, _aidl_return);
-  }
-  Status ReverseIntEnum(const vector<IntEnum>& input, vector<IntEnum>* repeated,
-                        vector<IntEnum>* _aidl_return) override {
-    return ReverseArray(input, repeated, _aidl_return);
-  }
-  Status ReverseLongEnum(const vector<LongEnum>& input, vector<LongEnum>* repeated,
-                         vector<LongEnum>* _aidl_return) override {
-    return ReverseArray(input, repeated, _aidl_return);
-  }
   Status ReverseSimpleParcelables(
       const vector<SimpleParcelable>& input,
       vector<SimpleParcelable>* repeated,
@@ -366,21 +346,6 @@
     return RepeatNullable(input, _aidl_return);
   }
 
-  Status RepeatNullableByteEnumArray(const unique_ptr<vector<ByteEnum>>& input,
-                                     unique_ptr<vector<ByteEnum>>* _aidl_return) {
-    return RepeatNullable(input, _aidl_return);
-  }
-
-  Status RepeatNullableIntEnumArray(const unique_ptr<vector<IntEnum>>& input,
-                                    unique_ptr<vector<IntEnum>>* _aidl_return) {
-    return RepeatNullable(input, _aidl_return);
-  }
-
-  Status RepeatNullableLongEnumArray(const unique_ptr<vector<LongEnum>>& input,
-                                     unique_ptr<vector<LongEnum>>* _aidl_return) {
-    return RepeatNullable(input, _aidl_return);
-  }
-
   Status RepeatNullableStringList(
              const unique_ptr<vector<unique_ptr<String16>>>& input,
              unique_ptr<vector<unique_ptr<String16>>>* _aidl_return) {
@@ -499,24 +464,6 @@
       ::android::aidl::tests::StructuredParcelable* parcelable) {
     parcelable->shouldBeJerry = "Jerry";
     parcelable->shouldContainThreeFs = {parcelable->f, parcelable->f, parcelable->f};
-    parcelable->shouldBeByteBar = ByteEnum::BAR;
-    parcelable->shouldBeIntBar = IntEnum::BAR;
-    parcelable->shouldBeLongBar = LongEnum::BAR;
-    parcelable->shouldContainTwoByteFoos = {ByteEnum::FOO, ByteEnum::FOO};
-    parcelable->shouldContainTwoIntFoos = {IntEnum::FOO, IntEnum::FOO};
-    parcelable->shouldContainTwoLongFoos = {LongEnum::FOO, LongEnum::FOO};
-
-    parcelable->const_exprs_1 = ConstantExpressionEnum::decInt32_1;
-    parcelable->const_exprs_2 = ConstantExpressionEnum::decInt32_2;
-    parcelable->const_exprs_3 = ConstantExpressionEnum::decInt64_1;
-    parcelable->const_exprs_4 = ConstantExpressionEnum::decInt64_2;
-    parcelable->const_exprs_5 = ConstantExpressionEnum::decInt64_3;
-    parcelable->const_exprs_6 = ConstantExpressionEnum::decInt64_4;
-    parcelable->const_exprs_7 = ConstantExpressionEnum::hexInt32_1;
-    parcelable->const_exprs_8 = ConstantExpressionEnum::hexInt32_2;
-    parcelable->const_exprs_9 = ConstantExpressionEnum::hexInt32_3;
-    parcelable->const_exprs_10 = ConstantExpressionEnum::hexInt64_1;
-
     return Status::ok();
   }
 
@@ -526,7 +473,7 @@
 
   android::status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                uint32_t flags) override {
-    if (code == ::android::IBinder::FIRST_CALL_TRANSACTION + 53 /* UnimplementedMethod */) {
+    if (code == ::android::IBinder::FIRST_CALL_TRANSACTION + 45 /* UnimplementedMethod */) {
       // pretend that UnimplementedMethod isn't implemented by this service.
       return android::UNKNOWN_TRANSACTION;
     } else {
diff --git a/tests/android/aidl/loggable/ILoggableInterface.aidl b/tests/android/aidl/loggable/ILoggableInterface.aidl
index 0b62df3..eee39d6 100644
--- a/tests/android/aidl/loggable/ILoggableInterface.aidl
+++ b/tests/android/aidl/loggable/ILoggableInterface.aidl
@@ -10,6 +10,7 @@
                    double doubleValue, inout double[] doubleArray,
                    String stringValue, inout String[] stringArray,
                    inout List<String> listValue,
+                   inout Map mapValue,
                    IBinder binderValue,
                    inout ParcelFileDescriptor pfdValue, inout ParcelFileDescriptor[] pfdArray);
 }
diff --git a/tests/android/aidl/tests/ByteEnum.aidl b/tests/android/aidl/tests/ByteEnum.aidl
deleted file mode 100644
index 503ae8a..0000000
--- a/tests/android/aidl/tests/ByteEnum.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.aidl.tests;
-
-/*
- * Hello, world!
- */
-@Backing(type="byte")
-enum ByteEnum {
-  // Comment about FOO.
-  FOO = 1,
-  BAR = 2,
-  BAZ,
-}
-
diff --git a/tests/android/aidl/tests/ConstantExpressionEnum.aidl b/tests/android/aidl/tests/ConstantExpressionEnum.aidl
deleted file mode 100644
index 2fe4f61..0000000
--- a/tests/android/aidl/tests/ConstantExpressionEnum.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.aidl.tests;
-
-@Backing(type="int")
-enum ConstantExpressionEnum {
-  // Should be all true / ones.
-  // dec literals are either int or long
-  decInt32_1 = (~(-1)) == 0,
-  decInt32_2 = -(1 << 31) == (1 << 31),
-  decInt64_1 = (~(-1L)) == 0,
-  decInt64_2 = (~4294967295L) != 0,
-  decInt64_3 = (~4294967295) != 0,
-  decInt64_4 = -(1L << 63) == (1L << 63),
-
-  // hex literals could be int or long
-  // 0x7fffffff is int, hence can be negated
-  hexInt32_1 = -0x7fffffff < 0,
-
-  // 0x80000000 is int32_t max + 1
-  hexInt32_2 = -0x80000000 < 0,
-
-  // 0xFFFFFFFF is int32_t, not long; if it were long then ~(long)0xFFFFFFFF != 0
-  hexInt32_3 = ~0xFFFFFFFF == 0,
-
-  // 0x7FFFFFFFFFFFFFFF is long, hence can be negated
-  hexInt64_1 = -0x7FFFFFFFFFFFFFFF < 0
-}
-
diff --git a/tests/android/aidl/tests/ITestService.aidl b/tests/android/aidl/tests/ITestService.aidl
index 9b7f08c..4143ba7 100644
--- a/tests/android/aidl/tests/ITestService.aidl
+++ b/tests/android/aidl/tests/ITestService.aidl
@@ -16,10 +16,7 @@
 
 package android.aidl.tests;
 
-import android.aidl.tests.ByteEnum;
 import android.aidl.tests.INamedCallback;
-import android.aidl.tests.IntEnum;
-import android.aidl.tests.LongEnum;
 import android.aidl.tests.SimpleParcelable;
 import android.aidl.tests.StructuredParcelable;
 import android.os.PersistableBundle;
@@ -53,26 +50,21 @@
   float RepeatFloat(float token);
   double RepeatDouble(double token);
   String RepeatString(String token);
-  ByteEnum RepeatByteEnum(ByteEnum token);
-  IntEnum RepeatIntEnum(IntEnum token);
-  LongEnum RepeatLongEnum(LongEnum token);
+  Map RepeatMap(in Map token);
 
   SimpleParcelable RepeatSimpleParcelable(in SimpleParcelable input,
                                           out SimpleParcelable repeat);
   PersistableBundle RepeatPersistableBundle(in PersistableBundle input);
 
   // Test that arrays work as parameters and return types.
-  boolean[]   ReverseBoolean  (in boolean[]   input, out boolean[]   repeated);
-  byte[]      ReverseByte     (in byte[]      input, out byte[]      repeated);
-  char[]      ReverseChar     (in char[]      input, out char[]      repeated);
-  int[]       ReverseInt      (in int[]       input, out int[]       repeated);
-  long[]      ReverseLong     (in long[]      input, out long[]      repeated);
-  float[]     ReverseFloat    (in float[]     input, out float[]     repeated);
-  double[]    ReverseDouble   (in double[]    input, out double[]    repeated);
-  String[]    ReverseString   (in String[]    input, out String[]    repeated);
-  ByteEnum[]  ReverseByteEnum (in ByteEnum[]  input, out ByteEnum[]  repeated);
-  IntEnum[]   ReverseIntEnum  (in IntEnum[]   input, out IntEnum[]   repeated);
-  LongEnum[]  ReverseLongEnum (in LongEnum[]  input, out LongEnum[]  repeated);
+  boolean[] ReverseBoolean(in boolean[] input, out boolean[] repeated);
+  byte[]    ReverseByte   (in byte[]    input, out byte[]    repeated);
+  char[]    ReverseChar   (in char[]    input, out char[]    repeated);
+  int[]     ReverseInt    (in int[]     input, out int[]     repeated);
+  long[]    ReverseLong   (in long[]    input, out long[]    repeated);
+  float[]   ReverseFloat  (in float[]   input, out float[]   repeated);
+  double[]  ReverseDouble (in double[]  input, out double[]  repeated);
+  String[]  ReverseString (in String[]  input, out String[]  repeated);
 
   SimpleParcelable[]  ReverseSimpleParcelables(in SimpleParcelable[] input,
                                                out SimpleParcelable[] repeated);
@@ -102,9 +94,6 @@
 
   // Test nullability
   @nullable int[] RepeatNullableIntArray(in @nullable int[] input);
-  @nullable ByteEnum[] RepeatNullableByteEnumArray(in @nullable ByteEnum[] input);
-  @nullable IntEnum[] RepeatNullableIntEnumArray(in @nullable IntEnum[] input);
-  @nullable LongEnum[] RepeatNullableLongEnumArray(in @nullable LongEnum[] input);
   @nullable String RepeatNullableString(in @nullable String input);
   @nullable List<String> RepeatNullableStringList(in @nullable List<String> input);
   @nullable SimpleParcelable RepeatNullableParcelable(in @nullable SimpleParcelable input);
@@ -143,63 +132,4 @@
   // to actually implement this, but intercept the dispatch to the method
   // inside onTransact().
   int UnimplementedMethod(int arg);
-
-  // All these constant expressions should be equal to 1
-  const int A1 = (~(-1)) == 0;
-  const int A2 = -(1 << 31) == (1 << 31);
-  const int A3 = -0x7fffffff < 0;
-  const int A4 = -0x80000000 < 0;
-  const int A5 = (1 + 0x7fffffff) == -2147483648;
-  const int A6 = (1 << 31) == 0x80000000;
-  const int A7 = (1 + 2) == 3;
-  const int A8 = (8 - 9) == -1;
-  const int A9 = (9 * 9) == 81;
-  const int A10 = (29 / 3) == 9;
-  const int A11 = (29 % 3) == 2;
-  const int A12 = (0xC0010000 | 0xF00D) == (0xC001F00D);
-  const int A13 = (10 | 6) == 14;
-  const int A14 = (10 & 6) == 2;
-  const int A15 = (10 ^ 6) == 12;
-  const int A16 = 6 < 10;
-  const int A17 = (10 < 10) == 0;
-  const int A18 = (6 > 10) == 0;
-  const int A19 = (10 > 10) == 0;
-  const int A20 = 19 >= 10;
-  const int A21 = 10 >= 10;
-  const int A22 = 5 <= 10;
-  const int A23 = (19 <= 10) == 0;
-  const int A24 = 19 != 10;
-  const int A25 = (10 != 10) == 0;
-  const int A26 = (22 << 1) == 44;
-  const int A27 = (11 >> 1) == 5;
-  const int A28 = (1 || 0) == 1;
-  const int A29 = (1 || 1) == 1;
-  const int A30 = (0 || 0) == 0;
-  const int A31 = (0 || 1) == 1;
-  const int A32 = (1 && 0) == 0;
-  const int A33 = (1 && 1) == 1;
-  const int A34 = (0 && 0) == 0;
-  const int A35 = (0 && 1) == 0;
-  const int A36 = 4 == 4;
-  const int A37 = -4 < 0;
-  const int A38 = 0xffffffff == -1;
-  const int A39 = 4 + 1 == 5;
-  const int A40 = 2 + 3 - 4;
-  const int A41 = 2 - 3 + 4 == 3;
-  const int A42 = 1 == 4 == 0;
-  const int A43 = 1 && 1;
-  const int A44 = 1 || 1 && 0;  // && higher than ||
-  const int A45 = 1 < 2;
-  const int A46 = !!((3 != 4 || (2 < 3 <= 3 > 4)) >= 0);
-  const int A47 = !(1 == 7) && ((3 != 4 || (2 < 3 <= 3 > 4)) >= 0);
-  const int A48 = (1 << 2) >= 0;
-  const int A49 = (4 >> 1) == 2;
-  const int A50 = (8 << -1) == 4;
-  const int A51 = (1 << 31 >> 31) == -1;
-  const int A52 = (1 | 16 >> 2) == 5;
-  const int A53 = (0x0f ^ 0x33 & 0x99) == 0x1e; // & higher than ^
-  const int A54 = (~42 & (1 << 3 | 16 >> 2) ^ 7) == 3;
-  const int A55 = (2 + 3 - 4 * -7 / (10 % 3)) - 33 == 0;
-  const int A56 = (2 + (-3&4 / 7)) == 2;
-  const int A57 = (((((1 + 0)))));
 }
diff --git a/tests/android/aidl/tests/IntEnum.aidl b/tests/android/aidl/tests/IntEnum.aidl
deleted file mode 100644
index d3769ef..0000000
--- a/tests/android/aidl/tests/IntEnum.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.aidl.tests;
-
-@Backing(type="int")
-enum IntEnum {
-  FOO = 1000,
-  BAR = 2000,
-  BAZ,
-}
-
diff --git a/tests/android/aidl/tests/LongEnum.aidl b/tests/android/aidl/tests/LongEnum.aidl
deleted file mode 100644
index 9d7610b..0000000
--- a/tests/android/aidl/tests/LongEnum.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.aidl.tests;
-
-@Backing(type="long")
-enum LongEnum {
-  FOO = 100000000000,
-  BAR = 200000000000,
-  BAZ,
-}
-
diff --git a/tests/android/aidl/tests/StructuredParcelable.aidl b/tests/android/aidl/tests/StructuredParcelable.aidl
index 28046e2..2ced1e8 100644
--- a/tests/android/aidl/tests/StructuredParcelable.aidl
+++ b/tests/android/aidl/tests/StructuredParcelable.aidl
@@ -16,21 +16,10 @@
 
 package android.aidl.tests;
 
-import android.aidl.tests.ByteEnum;
-import android.aidl.tests.IntEnum;
-import android.aidl.tests.LongEnum;
-import android.aidl.tests.ConstantExpressionEnum;
-
 parcelable StructuredParcelable {
     int[] shouldContainThreeFs;
     int f;
     @utf8InCpp String shouldBeJerry;
-    ByteEnum shouldBeByteBar;
-    IntEnum shouldBeIntBar;
-    LongEnum shouldBeLongBar;
-    ByteEnum[] shouldContainTwoByteFoos;
-    IntEnum[] shouldContainTwoIntFoos;
-    LongEnum[] shouldContainTwoLongFoos;
 
     String stringDefaultsToFoo = "foo";
     byte byteDefaultsToFour = 4;
@@ -47,116 +36,4 @@
     double checkDoubleFromFloat = 3.14f;
     String[] checkStringArray1 = { "a", "b" };
     @utf8InCpp String[] checkStringArray2 = { "a", "b" };
-
-    // Add test to verify corner cases
-    int int32_min = -2147483648;
-    int int32_max =  2147483647;
-    long int64_max =  9223372036854775807;
-    int hexInt32_neg_1 = 0xffffffff;
-
-    @nullable IBinder ibinder;
-
-    // Constant expressions that evaluate to 1
-    int[] int32_1 = {
-      (~(-1)) == 0,
-      -(1 << 31) == (1 << 31),
-      -0x7fffffff < 0,
-      -0x80000000 < 0,
-
-      // both treated int32_t, sum = (int32_t)0x80000000 = -2147483648
-      (1 + 0x7fffffff) == -2147483648,
-
-      // Shifting for more than 31 bits are undefined. Not tested.
-      (1 << 31) == 0x80000000,
-
-      // Should be all true / ones.
-      (1 + 2) == 3,
-      (8 - 9) == -1,
-      (9 * 9) == 81,
-      (29 / 3) == 9,
-      (29 % 3) == 2,
-      (0xC0010000 | 0xF00D) == (0xC001F00D),
-      (10 | 6) == 14,
-      (10 & 6) == 2,
-      (10 ^ 6) == 12,
-      6 < 10,
-      (10 < 10) == 0,
-      (6 > 10) == 0,
-      (10 > 10) == 0,
-      19 >= 10,
-      10 >= 10,
-      5 <= 10,
-      (19 <= 10) == 0,
-      19 != 10,
-      (10 != 10) == 0,
-      (22 << 1) == 44,
-      (11 >> 1) == 5,
-      (1 || 0) == 1,
-      (1 || 1) == 1,
-      (0 || 0) == 0,
-      (0 || 1) == 1,
-      (1 && 0) == 0,
-      (1 && 1) == 1,
-      (0 && 0) == 0,
-      (0 && 1) == 0,
-
-      // precedence tests -- all 1s
-      4 == 4,
-      -4 < 0,
-      0xffffffff == -1,
-      4 + 1 == 5,
-      2 + 3 - 4,
-      2 - 3 + 4 == 3,
-      1 == 4 == 0,
-      1 && 1,
-      1 || 1 && 0,  // && higher than ||
-      1 < 2,
-      !!((3 != 4 || (2 < 3 <= 3 > 4)) >= 0),
-      !(1 == 7) && ((3 != 4 || (2 < 3 <= 3 > 4)) >= 0),
-      (1 << 2) >= 0,
-      (4 >> 1) == 2,
-      (8 << -1) == 4,
-      (1 << 31 >> 31) == -1,
-      (1 | 16 >> 2) == 5,
-      (0x0f ^ 0x33 & 0x99) == 0x1e, // & higher than ^
-      (~42 & (1 << 3 | 16 >> 2) ^ 7) == 3,
-      (2 + 3 - 4 * -7 / (10 % 3)) - 33 == 0,
-      (2 + (-3&4 / 7)) == 2,
-      (((((1 + 0)))))
-    };
-
-    long[] int64_1 = {
-      (~(-1)) == 0,
-      (~4294967295) != 0,
-      (~4294967295) != 0,
-      -(1 << 63) == (1 << 63),
-      -0x7FFFFFFFFFFFFFFF < 0,
-
-      // both treated int32_t, sum = (int64_t)(int32_t)0x80000000 = (int64_t)(-2147483648)
-      (1 + 0x7fffffff) == -2147483648,
-
-      // 0x80000000 is uint32_t, sum = (int64_t)(uint32_t)0x7fffffff = (int64_t)(2147483647)
-      (0x80000000 - 1) == 2147483647,
-      (0x80000000 + 1) == -2147483647,
-      (1L << 63)+1 == -9223372036854775807,
-      0xfffffffff == 68719476735
-    };
-    int hexInt32_pos_1 = -0xffffffff;
-    int hexInt64_pos_1 = -0xfffffffffff < 0;
-
-    ConstantExpressionEnum const_exprs_1;
-    ConstantExpressionEnum const_exprs_2;
-    ConstantExpressionEnum const_exprs_3;
-    ConstantExpressionEnum const_exprs_4;
-    ConstantExpressionEnum const_exprs_5;
-    ConstantExpressionEnum const_exprs_6;
-    ConstantExpressionEnum const_exprs_7;
-    ConstantExpressionEnum const_exprs_8;
-    ConstantExpressionEnum const_exprs_9;
-    ConstantExpressionEnum const_exprs_10;
-
-    // String expressions
-    @utf8InCpp String addString1 = "hello" + " world!";
-    @utf8InCpp String addString2 = "The quick brown fox jumps " + "over the lazy dog.";
 }
-
diff --git a/tests/end_to_end_tests.cpp b/tests/end_to_end_tests.cpp
index 601c76f..7602a86 100644
--- a/tests/end_to_end_tests.cpp
+++ b/tests/end_to_end_tests.cpp
@@ -325,5 +325,5 @@
   CheckFileContents(kJavaOutputPath, kExpectedJavaOutputWithVersion);
 }
 
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/tests/fake_io_delegate.cpp b/tests/fake_io_delegate.cpp
index dc35c4d..b63e1e3 100644
--- a/tests/fake_io_delegate.cpp
+++ b/tests/fake_io_delegate.cpp
@@ -151,14 +151,6 @@
   return true;
 }
 
-std::vector<std::string> FakeIoDelegate::ListOutputFiles() {
-  std::vector<std::string> out;
-  for (const auto& [file, contents] : written_file_contents_) {
-    out.push_back(file);
-  }
-  return out;
-}
-
 bool FakeIoDelegate::PathWasRemoved(const std::string& path) {
   if (removed_files_.count(path) > 0) {
     return true;
@@ -177,5 +169,5 @@
 }
 
 }  // namespace test
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/tests/fake_io_delegate.h b/tests/fake_io_delegate.h
index f077c0f..32ef2ed 100644
--- a/tests/fake_io_delegate.h
+++ b/tests/fake_io_delegate.h
@@ -60,7 +60,6 @@
   // Returns true iff we've previously written to |path|.
   // When we return true, we'll set *contents to the written string.
   bool GetWrittenContents(const std::string& path, std::string* content);
-  std::vector<std::string> ListOutputFiles();
 
   bool PathWasRemoved(const std::string& path);
 
@@ -83,7 +82,7 @@
 };  // class FakeIoDelegate
 
 }  // namespace test
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
 
 #endif // AIDL_TESTS_FAKE_IO_DELEGATE_H_
diff --git a/tests/integration-test.py b/tests/integration-test.py
index 32d1a8f..0079ba9 100755
--- a/tests/integration-test.py
+++ b/tests/integration-test.py
@@ -9,9 +9,9 @@
 import subprocess
 import shlex
 
-JAVA_OUTPUT_READER_FOR_BITNESS = '/data/nativetest%s/aidl_test_sentinel_searcher/aidl_test_sentinel_searcher'
-NATIVE_TEST_CLIENT_FOR_BITNESS = ' /data/nativetest%s/aidl_test_client/aidl_test_client'
-NATIVE_TEST_SERVICE_FOR_BITNESS = ' /data/nativetest%s/aidl_test_service/aidl_test_service'
+JAVA_OUTPUT_READER = 'aidl_test_sentinel_searcher'
+NATIVE_TEST_CLIENT = 'aidl_test_client'
+NATIVE_TEST_SERVICE = 'aidl_test_service'
 
 TEST_FILTER_ALL = 'all'
 TEST_FILTER_JAVA = 'java'
@@ -123,36 +123,28 @@
             raise subprocess.CalledProcessError(p.returncode, command)
         return ShellResult(p.returncode, stdout, stderr)
 
+
 def run_test(host, test_native, test_java):
     """Body of the test.
 
     Args:
         host: AdbHost object to run tests on
         test_native: True iff we should test native Binder clients.
-        test_java: True iff we should test Java Binder clients.
+        test_java: True iff we shoudl test Java Binder clients.
     """
 
     print('Starting aidl integration testing...')
 
-    if host.run('ls /data/nativetest64', ignore_status=True).exit_status:
-        bitness = ""
-    else:
-        bitness = "64"
-
-    JAVA_OUTPUT_READER = JAVA_OUTPUT_READER_FOR_BITNESS % bitness
-    NATIVE_TEST_CLIENT = NATIVE_TEST_CLIENT_FOR_BITNESS % bitness
-    NATIVE_TEST_SERVICE = NATIVE_TEST_SERVICE_FOR_BITNESS % bitness
-
     # Kill any previous test context
     host.run('rm -f %s' % JAVA_LOG_FILE, ignore_status=True)
-    host.run('killall %s' % NATIVE_TEST_SERVICE, ignore_status=True)
+    host.run('pkill %s' % NATIVE_TEST_SERVICE, ignore_status=True)
 
     # Start up a native server
     host.run(NATIVE_TEST_SERVICE, background=True)
 
     # Start up clients
     if test_native:
-        host.run('killall %s' % NATIVE_TEST_CLIENT, ignore_status=True)
+        host.run('pkill %s' % NATIVE_TEST_CLIENT, ignore_status=True)
         result = host.run(NATIVE_TEST_CLIENT, ignore_status=True)
         if result.exit_status:
             print(result.printable_string())
@@ -174,9 +166,6 @@
             print(result.printable_string())
             raise TestFail('Java client did not complete successfully.')
 
-    host.run('killall %s' % NATIVE_TEST_SERVICE, ignore_status=True)
-    host.run('killall android.aidl.tests', ignore_status=True)
-
     print('Success!')
 
 
diff --git a/tests/java_app/src/android/aidl/tests/TestServiceClient.java b/tests/java_app/src/android/aidl/tests/TestServiceClient.java
index ef5c651..697a3da 100644
--- a/tests/java_app/src/android/aidl/tests/TestServiceClient.java
+++ b/tests/java_app/src/android/aidl/tests/TestServiceClient.java
@@ -16,11 +16,6 @@
 
 package android.aidl.tests;
 
-import android.aidl.tests.ByteEnum;
-import android.aidl.tests.INamedCallback;
-import android.aidl.tests.ITestService;
-import android.aidl.tests.IntEnum;
-import android.aidl.tests.LongEnum;
 import android.aidl.tests.SimpleParcelable;
 import android.aidl.tests.StructuredParcelable;
 import android.aidl.tests.TestFailException;
@@ -28,13 +23,13 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.os.ServiceSpecificException;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.ServiceSpecificException;
 import android.util.Log;
 import java.io.File;
 import java.io.FileDescriptor;
@@ -44,9 +39,13 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.HashMap;
+
+// Generated
+import android.aidl.tests.INamedCallback;
+import android.aidl.tests.ITestService;
 
 public class TestServiceClient extends Activity {
     private static final String TAG = "TestServiceClient";
@@ -160,25 +159,15 @@
                 }
             }
             {
-              byte query = ByteEnum.FOO;
-              byte response = service.RepeatByteEnum(query);
-              if (query != response) {
-                mLog.logAndThrow("Repeat ByteEnum with " + query + " responded " + response);
-              }
-            }
-            {
-              int query = IntEnum.FOO;
-              int response = service.RepeatIntEnum(query);
-              if (query != response) {
-                mLog.logAndThrow("Repeat IntEnum with " + query + " responded " + response);
-              }
-            }
-            {
-              long query = LongEnum.FOO;
-              long response = service.RepeatLongEnum(query);
-              if (query != response) {
-                mLog.logAndThrow("Repeat LongEnum with " + query + " responded " + response);
-              }
+                Map<String, Object> query = new HashMap<String, Object>();
+                query.put("first_val", new Byte((byte)-128));
+                query.put("second_val", new Integer(1<<30));
+                query.put("third_val", "OHAI");
+                Object response = service.RepeatMap(query);
+                if (!query.equals(response)) {
+                    mLog.logAndThrow("Repeat with " + query +
+                                     " responded " + response);
+                }
             }
 
             List<String> queries = Arrays.asList(
@@ -754,9 +743,6 @@
       parcelable.shouldContainThreeFs = new int[0];
       parcelable.f = kDesiredFValue;
       parcelable.shouldBeJerry = "";
-      parcelable.shouldContainTwoByteFoos = new byte[2];
-      parcelable.shouldContainTwoIntFoos = new int[2];
-      parcelable.shouldContainTwoLongFoos = new long[2];
 
       if (!parcelable.stringDefaultsToFoo.equals("foo")) {
         mLog.logAndThrow(
@@ -810,117 +796,6 @@
       if (!parcelable.shouldBeJerry.equals("Jerry")) {
         mLog.logAndThrow("shouldBeJerry should be 'Jerry' but is " + parcelable.shouldBeJerry);
       }
-
-      if (parcelable.shouldBeByteBar != ByteEnum.BAR) {
-        mLog.logAndThrow(
-            "shouldBeByteBar should be ByteEnum.BAR but is " + parcelable.shouldBeByteBar);
-      }
-      if (parcelable.shouldBeIntBar != IntEnum.BAR) {
-        mLog.logAndThrow(
-            "shouldBeIntBar should be IntEnum.BAR but is " + parcelable.shouldBeIntBar);
-      }
-      if (parcelable.shouldBeLongBar != LongEnum.BAR) {
-        mLog.logAndThrow(
-            "shouldBeLongBar should be LongEnum.BAR but is " + parcelable.shouldBeLongBar);
-      }
-
-      if (!Arrays.equals(
-              parcelable.shouldContainTwoByteFoos, new byte[] {ByteEnum.FOO, ByteEnum.FOO})) {
-        mLog.logAndThrow(
-            "shouldContainTwoByteFoos is " + Arrays.toString(parcelable.shouldContainTwoByteFoos));
-      }
-      if (!Arrays.equals(
-              parcelable.shouldContainTwoIntFoos, new int[] {IntEnum.FOO, IntEnum.FOO})) {
-        mLog.logAndThrow(
-            "shouldContainTwoIntFoos is " + Arrays.toString(parcelable.shouldContainTwoIntFoos));
-      }
-      if (!Arrays.equals(
-              parcelable.shouldContainTwoLongFoos, new long[] {LongEnum.FOO, LongEnum.FOO})) {
-        mLog.logAndThrow(
-            "shouldContainTwoLongFoos is " + Arrays.toString(parcelable.shouldContainTwoLongFoos));
-      }
-
-      if (parcelable.int32_min != Integer.MIN_VALUE) {
-        mLog.logAndThrow(
-            "int32_min should be " + Integer.MIN_VALUE + "but is " + parcelable.int32_min);
-      }
-
-      if (parcelable.int32_max != Integer.MAX_VALUE) {
-        mLog.logAndThrow(
-            "int32_max should be " + Integer.MAX_VALUE + "but is " + parcelable.int32_max);
-      }
-
-      if (parcelable.int64_max != Long.MAX_VALUE) {
-        mLog.logAndThrow(
-            "int64_max should be " + Long.MAX_VALUE + "but is " + parcelable.int64_max);
-      }
-
-      if (parcelable.hexInt32_neg_1 != -1) {
-        mLog.logAndThrow("hexInt32_neg_1 should be -1 but is " + parcelable.hexInt32_neg_1);
-      }
-
-      boolean success = true;
-      for (int ndx = 0; ndx < parcelable.int32_1.length; ndx++) {
-        if (parcelable.int32_1[ndx] != 1) {
-          mLog.log("int32_1[" + ndx + "] should be 1 but is " + parcelable.int32_1[ndx]);
-          success = false;
-        }
-      }
-      if (!success) {
-        mLog.logAndThrow("Failed to parse int32_1 array");
-      }
-
-      for (int ndx = 0; ndx < parcelable.int64_1.length; ndx++) {
-        if (parcelable.int64_1[ndx] != 1) {
-          mLog.log("int64_1[" + ndx + "] should be 1 but is " + parcelable.int64_1[ndx]);
-          success = false;
-        }
-      }
-      if (!success) {
-        mLog.logAndThrow("Failed to parse int64_1 array");
-      }
-
-      if (parcelable.hexInt32_pos_1 != 1) {
-        mLog.logAndThrow("hexInt32_pos_1 should be 1 but is " + parcelable.hexInt32_pos_1);
-      }
-
-      if (parcelable.hexInt64_pos_1 != 1) {
-        mLog.logAndThrow("hexInt64_pos_1 should be 1 but is " + parcelable.hexInt64_pos_1);
-      }
-
-      if (parcelable.const_exprs_1 != 1) {
-        mLog.logAndThrow("parcelable.const_exprs_1 should be 1 but is " + parcelable.const_exprs_1);
-      }
-      if (parcelable.const_exprs_2 != 1) {
-        mLog.logAndThrow("parcelable.const_exprs_2 should be 1 but is " + parcelable.const_exprs_2);
-      }
-      if (parcelable.const_exprs_3 != 1) {
-        mLog.logAndThrow("parcelable.const_exprs_3 should be 1 but is " + parcelable.const_exprs_3);
-      }
-      if (parcelable.const_exprs_4 != 1) {
-        mLog.logAndThrow("parcelable.const_exprs_4 should be 1 but is " + parcelable.const_exprs_4);
-      }
-      if (parcelable.const_exprs_5 != 1) {
-        mLog.logAndThrow("parcelable.const_exprs_5 should be 1 but is " + parcelable.const_exprs_5);
-      }
-      if (parcelable.const_exprs_6 != 1) {
-        mLog.logAndThrow("parcelable.const_exprs_6 should be 1 but is " + parcelable.const_exprs_6);
-      }
-      if (parcelable.const_exprs_7 != 1) {
-        mLog.logAndThrow("parcelable.const_exprs_7 should be 1 but is " + parcelable.const_exprs_7);
-      }
-      if (parcelable.const_exprs_8 != 1) {
-        mLog.logAndThrow("parcelable.const_exprs_8 should be 1 but is " + parcelable.const_exprs_8);
-      }
-      if (parcelable.const_exprs_9 != 1) {
-        mLog.logAndThrow("parcelable.const_exprs_9 should be 1 but is " + parcelable.const_exprs_9);
-      }
-      if (parcelable.const_exprs_10 != 1) {
-        mLog.logAndThrow(
-            "parcelable.const_exprs_10 should be 1 but is " + parcelable.const_exprs_10);
-      }
-
-      mLog.log("Successfully verified the StructuredParcelable");
     }
 
     private void checkDefaultImpl(ITestService service) throws TestFailException {
diff --git a/tests/test_data_example_interface.cpp b/tests/test_data_example_interface.cpp
index 58a0426..24fee69 100644
--- a/tests/test_data_example_interface.cpp
+++ b/tests/test_data_example_interface.cpp
@@ -122,7 +122,7 @@
  * This file is auto-generated.  DO NOT MODIFY.
  */
 package android.test;
-@dalvik.annotation.compat.UnsupportedAppUsage
+@android.annotation.UnsupportedAppUsage
 @android.annotation.SystemApi
 public interface IExampleInterface extends android.os.IInterface
 {
@@ -564,7 +564,7 @@
   public int getState() throws android.os.RemoteException;
   public java.lang.String getAddress() throws android.os.RemoteException;
   /* Test long comment */
-  @dalvik.annotation.compat.UnsupportedAppUsage
+  @android.annotation.UnsupportedAppUsage
   @android.annotation.SystemApi
   public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
   // Test short comment
@@ -584,7 +584,7 @@
  * This file is auto-generated.  DO NOT MODIFY.
  */
 package android.test;
-@dalvik.annotation.compat.UnsupportedAppUsage
+@android.annotation.UnsupportedAppUsage
 @android.annotation.SystemApi
 public interface IExampleInterface extends android.os.IInterface
 {
@@ -1078,7 +1078,7 @@
   public int getState() throws android.os.RemoteException;
   public java.lang.String getAddress() throws android.os.RemoteException;
   /* Test long comment */
-  @dalvik.annotation.compat.UnsupportedAppUsage
+  @android.annotation.UnsupportedAppUsage
   @android.annotation.SystemApi
   public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
   // Test short comment
@@ -1098,7 +1098,7 @@
  * This file is auto-generated.  DO NOT MODIFY.
  */
 package android.test;
-@dalvik.annotation.compat.UnsupportedAppUsage
+@android.annotation.UnsupportedAppUsage
 @android.annotation.SystemApi
 public interface IExampleInterface extends android.os.IInterface
 {
@@ -1620,7 +1620,7 @@
   public int getState() throws android.os.RemoteException;
   public java.lang.String getAddress() throws android.os.RemoteException;
   /* Test long comment */
-  @dalvik.annotation.compat.UnsupportedAppUsage
+  @android.annotation.UnsupportedAppUsage
   @android.annotation.SystemApi
   public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
   // Test short comment
@@ -2517,12 +2517,7 @@
           android.os.Parcel reply = android.os.Parcel.obtain();
           try {
             data.writeInterfaceToken(DESCRIPTOR);
-            boolean _status = mRemote.transact(Stub.TRANSACTION_getInterfaceVersion, data, reply, 0);
-            if (!_status) {
-              if (getDefaultImpl() != null) {
-                return getDefaultImpl().getInterfaceVersion();
-              }
-            }
+            mRemote.transact(Stub.TRANSACTION_getInterfaceVersion, data, reply, 0);
             reply.readException();
             mCachedVersion = reply.readInt();
           } finally {
diff --git a/tests/test_data_ping_responder.cpp b/tests/test_data_ping_responder.cpp
index 130a225..9699d26 100644
--- a/tests/test_data_ping_responder.cpp
+++ b/tests/test_data_ping_responder.cpp
@@ -268,17 +268,11 @@
 }  // namespace android
 #include <android/os/BnPingResponder.h>
 #include <binder/Parcel.h>
-#include <binder/Stability.h>
 
 namespace android {
 
 namespace os {
 
-BnPingResponder::BnPingResponder()
-{
-  ::android::internal::Stability::markCompilationUnit(this);
-}
-
 ::android::status_t BnPingResponder::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
   ::android::status_t _aidl_ret_status = ::android::OK;
   switch (_aidl_code) {
@@ -476,7 +470,7 @@
 )";
 
 const char kExpectedBnHeaderOutput[] =
-    R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
 #define AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
 
 #include <binder/IInterface.h>
@@ -488,7 +482,6 @@
 
 class BnPingResponder : public ::android::BnInterface<IPingResponder> {
 public:
-  explicit BnPingResponder();
   ::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) override;
 };  // class BnPingResponder
 
@@ -714,17 +707,11 @@
 }  // namespace android
 #include <android/os/BnPingResponder.h>
 #include <binder/Parcel.h>
-#include <binder/Stability.h>
 
 namespace android {
 
 namespace os {
 
-BnPingResponder::BnPingResponder()
-{
-  ::android::internal::Stability::markCompilationUnit(this);
-}
-
 ::android::status_t BnPingResponder::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
   ::android::status_t _aidl_ret_status = ::android::OK;
   switch (_aidl_code) {
@@ -867,7 +854,6 @@
 #include <binder/IBinder.h>
 #include <binder/IInterface.h>
 #include <binder/Status.h>
-#include <cstdint>
 #include <memory>
 #include <string>
 #include <utils/String16.h>
@@ -940,7 +926,7 @@
 )";
 
 const char kExpectedBnHeaderOutputWithVersion[] =
-    R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
 #define AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
 
 #include <binder/IInterface.h>
@@ -952,7 +938,6 @@
 
 class BnPingResponder : public ::android::BnInterface<IPingResponder> {
 public:
-  explicit BnPingResponder();
   ::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) override;
   int32_t getInterfaceVersion() final override;
 };  // class BnPingResponder
diff --git a/tests/test_data_string_constants.cpp b/tests/test_data_string_constants.cpp
index d7b4bb5..2077880 100644
--- a/tests/test_data_string_constants.cpp
+++ b/tests/test_data_string_constants.cpp
@@ -197,17 +197,11 @@
 }  // namespace android
 #include <android/os/BnStringConstants.h>
 #include <binder/Parcel.h>
-#include <binder/Stability.h>
 
 namespace android {
 
 namespace os {
 
-BnStringConstants::BnStringConstants()
-{
-  ::android::internal::Stability::markCompilationUnit(this);
-}
-
 ::android::status_t BnStringConstants::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
   ::android::status_t _aidl_ret_status = ::android::OK;
   switch (_aidl_code) {
@@ -328,12 +322,7 @@
           android.os.Parcel reply = android.os.Parcel.obtain();
           try {
             data.writeInterfaceToken(DESCRIPTOR);
-            boolean _status = mRemote.transact(Stub.TRANSACTION_getInterfaceVersion, data, reply, 0);
-            if (!_status) {
-              if (getDefaultImpl() != null) {
-                return getDefaultImpl().getInterfaceVersion();
-              }
-            }
+            mRemote.transact(Stub.TRANSACTION_getInterfaceVersion, data, reply, 0);
             reply.readException();
             mCachedVersion = reply.readInt();
           } finally {
@@ -369,7 +358,6 @@
 #include <binder/IBinder.h>
 #include <binder/IInterface.h>
 #include <binder/Status.h>
-#include <cstdint>
 #include <utils/String16.h>
 #include <utils/StrongPointer.h>
 
@@ -459,17 +447,11 @@
 }  // namespace android
 #include <android/os/BnStringConstants.h>
 #include <binder/Parcel.h>
-#include <binder/Stability.h>
 
 namespace android {
 
 namespace os {
 
-BnStringConstants::BnStringConstants()
-{
-  ::android::internal::Stability::markCompilationUnit(this);
-}
-
 ::android::status_t BnStringConstants::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
   ::android::status_t _aidl_ret_status = ::android::OK;
   switch (_aidl_code) {
diff --git a/tests/test_util.cpp b/tests/test_util.cpp
index 6d4750a..9cb52f3 100644
--- a/tests/test_util.cpp
+++ b/tests/test_util.cpp
@@ -164,5 +164,5 @@
 }
 
 }  // namespace test
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
diff --git a/tests/test_util.h b/tests/test_util.h
index 6c4389c..34b9e5d 100644
--- a/tests/test_util.h
+++ b/tests/test_util.h
@@ -34,7 +34,7 @@
 void PrintDiff(const std::string& a, const std::string& b);
 
 }  // namespace test
-}  // namespace aidl
 }  // namespace android
+}  // namespace aidl
 
 #endif // AIDL_TESTS_TEST_UTIL_H_
diff --git a/type_cpp.cpp b/type_cpp.cpp
new file mode 100644
index 0000000..c3cab98
--- /dev/null
+++ b/type_cpp.cpp
@@ -0,0 +1,527 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "type_cpp.h"
+
+#include <algorithm>
+#include <iostream>
+#include <memory>
+#include <vector>
+
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+#include "logging.h"
+
+using std::string;
+using std::vector;
+
+using android::base::Join;
+using android::base::StringPrintf;
+
+namespace android {
+namespace aidl {
+namespace cpp {
+namespace {
+
+const char kNoPackage[] = "";
+const char kNoHeader[] = "";
+const char kNoValidMethod[] = "";
+Type* const kNoArrayType = nullptr;
+Type* const kNoNullableType = nullptr;
+
+class VoidType : public Type {
+ public:
+  VoidType() : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "void",
+                    {}, "void", kNoValidMethod, kNoValidMethod) {}
+  ~VoidType() override = default;
+  bool CanWriteToParcel() const override { return false; }
+};  // class VoidType
+
+class CppArrayType : public Type {
+ public:
+  CppArrayType(int kind,  // from ValidatableType
+            const std::string& package,
+            const string& underlying_aidl_type,
+            const string& cpp_header,
+            const string& underlying_cpp_type,
+            const string& underlying_cpp_type_nulllable,
+            const string& read_method,
+            const string& write_method,
+            bool is_nullable,
+            const string& src_file_name = "")
+      : Type(kind, package,
+             underlying_aidl_type + "[]",
+             GetHeaders(is_nullable, cpp_header),
+             GetCppType(is_nullable, underlying_cpp_type),
+             read_method, write_method, kNoArrayType,
+             (is_nullable)
+                 ? kNoNullableType
+                 // All arrays are nullable.
+                 : new CppArrayType(kind, package, underlying_aidl_type,
+                                    cpp_header, underlying_cpp_type_nulllable,
+                                    underlying_cpp_type_nulllable,
+                                    read_method, write_method, true),
+             src_file_name) {}
+
+ private:
+  static vector<string> GetHeaders(bool is_nullable, const string& cpp_header) {
+    vector<string> result = {"vector"};
+    if (is_nullable) {
+      result.push_back("memory");
+    }
+    if (!cpp_header.empty()) {
+      result.push_back(cpp_header);
+    }
+    return result;
+  }
+
+  static string GetCppType(bool is_nullable,
+                           const string& underlying_cpp_type) {
+    if (is_nullable)
+      return StringPrintf("::std::unique_ptr<::std::vector<%s>>",
+                          underlying_cpp_type.c_str());
+    return StringPrintf("::std::vector<%s>",
+                        underlying_cpp_type.c_str());
+  }
+
+  DISALLOW_COPY_AND_ASSIGN(CppArrayType);
+};  // class CppArrayType
+
+class PrimitiveType : public Type {
+ public:
+  PrimitiveType(const std::string& aidl_type,
+                const std::string& header,
+                const std::string& cpp_type,
+                const std::string& read_method,
+                const std::string& write_method,
+                const std::string& read_array_method,
+                const std::string& write_array_method)
+      : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, aidl_type, {header},
+             cpp_type, read_method, write_method,
+             new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
+                              aidl_type, header, cpp_type, cpp_type,
+                              read_array_method, write_array_method,
+                              false)) {}
+
+  ~PrimitiveType() override = default;
+  bool IsCppPrimitive() const override { return true; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(PrimitiveType);
+};  // class PrimitiveType
+
+// Unfortunately, bytes in Java are signed.  However, most C authors would
+// say that a byte is not in fact signed.  Compromise: customize this otherwise
+// normal primitive to use signed single bytes, but unsigned byte arrays.
+class ByteType : public Type {
+ public:
+  ByteType()
+      : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "byte",
+             {"cstdint"}, "int8_t", "readByte", "writeByte",
+             new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
+                              "byte", "cstdint", "uint8_t", "uint8_t",
+                              "readByteVector", "writeByteVector",
+                              false)) {}
+
+  ~ByteType() override = default;
+  bool IsCppPrimitive() const override { return true; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ByteType);
+};  // class PrimitiveType
+
+static string GetCppHeader(const AidlDefinedType& defined_type) {
+  vector<string> name = defined_type.GetSplitPackage();
+  name.push_back(defined_type.GetName());
+  return Join(name, '/') + ".h";
+}
+
+class BinderType : public Type {
+ public:
+  BinderType(const AidlInterface& interface, const std::string& src_file_name)
+      : BinderType(interface, src_file_name,
+                   new BinderType(interface, src_file_name, kNoNullableType,
+                                  "readNullableStrongBinder"),
+                   "readStrongBinder") {}
+  ~BinderType() override = default;
+
+  string WriteCast(const string& val) const override {
+    return write_cast_ + "(" + val + ")";
+  }
+
+ private:
+  BinderType(const AidlInterface& interface, const std::string& src_file_name, Type* nullable_type,
+             const std::string& read)
+      : Type(ValidatableType::KIND_GENERATED, interface.GetPackage(), interface.GetName(),
+             {GetCppHeader(interface)}, GetCppName(interface), read, "writeStrongBinder",
+             kNoArrayType, nullable_type, src_file_name),
+        write_cast_(GetRawCppName(interface) + "::asBinder") {}
+
+  static string GetCppName(const AidlInterface& interface) {
+    return "::android::sp<" + GetRawCppName(interface) + ">";
+  }
+
+  static string GetRawCppName(const AidlInterface& interface) {
+    vector<string> name = interface.GetSplitPackage();
+    string ret;
+
+    name.push_back(interface.GetName());
+
+    for (const auto& term : name) {
+      ret += "::" + term;
+    }
+
+    return ret;
+  }
+
+  std::string write_cast_;
+};
+
+class NullableParcelableType : public Type {
+ public:
+  NullableParcelableType(const AidlParcelable& parcelable, const std::string& cpp_header,
+                         const std::string& src_file_name)
+      : Type(ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(), parcelable.GetName(),
+             {cpp_header}, GetCppName(parcelable), "readParcelable", "writeNullableParcelable",
+             kNoArrayType, kNoNullableType, src_file_name) {}
+  ~NullableParcelableType() override = default;
+
+ private:
+  static string GetCppName(const AidlParcelable& parcelable) {
+    return "::std::unique_ptr<::" + Join(parcelable.GetSplitPackage(), "::") +
+        "::" + parcelable.GetCppName() + ">";
+  }
+};
+
+class ParcelableType : public Type {
+ public:
+  ParcelableType(const AidlParcelable& parcelable, const std::string& cpp_header,
+                 const std::string& src_file_name)
+      : Type(ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(), parcelable.GetName(),
+             {cpp_header}, GetCppName(parcelable), "readParcelable", "writeParcelable",
+             new CppArrayType(ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(),
+                              parcelable.GetName(), cpp_header, GetCppName(parcelable),
+                              GetCppName(parcelable), "readParcelableVector",
+                              "writeParcelableVector", false, src_file_name),
+             new NullableParcelableType(parcelable, cpp_header, src_file_name), src_file_name) {}
+  ~ParcelableType() override = default;
+
+ private:
+  static string GetCppName(const AidlParcelable& parcelable) {
+    return "::" + Join(parcelable.GetSplitPackage(), "::") +
+        "::" + parcelable.GetCppName();
+  }
+};
+
+class NullableMap : public Type {
+ public:
+  NullableMap()
+      : Type(ValidatableType::KIND_BUILT_IN,
+             "java.util", "Map",
+             {"binder/Map.h", "binder/Value.h"},
+             "::std::unique_ptr<::android::binder::Map>",
+             "readNullableMap", "writeNullableMap") {}
+  ~NullableMap() override = default;
+};
+
+
+class MapType : public Type {
+ public:
+  MapType()
+      : Type(ValidatableType::KIND_BUILT_IN,
+             "java.util", "Map",
+             {"binder/Map.h","binder/Value.h"},
+             "::android::binder::Map",
+             "readMap", "writeMap",
+             kNoArrayType,
+             new NullableMap() ) {}
+  ~MapType() override = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MapType);
+};  // class MapType
+
+class NullableStringListType : public Type {
+ public:
+  NullableStringListType()
+      : Type(ValidatableType::KIND_BUILT_IN,
+             "java.util", "List<" + string(kStringCanonicalName) + ">",
+             {"utils/String16.h", "memory", "vector"},
+             "::std::unique_ptr<::std::vector<std::unique_ptr<::android::String16>>>",
+             "readString16Vector", "writeString16Vector") {}
+  ~NullableStringListType() override = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NullableStringListType);
+};  // class NullableStringListType
+
+class StringListType : public Type {
+ public:
+  StringListType()
+      : Type(ValidatableType::KIND_BUILT_IN,
+             "java.util", "List<" + string(kStringCanonicalName) + ">",
+             {"utils/String16.h", "vector"},
+             "::std::vector<::android::String16>",
+             "readString16Vector", "writeString16Vector",
+             kNoArrayType, new NullableStringListType()) {}
+  ~StringListType() override = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(StringListType);
+};  // class StringListType
+
+class NullableUtf8InCppStringListType : public Type {
+ public:
+  NullableUtf8InCppStringListType()
+      : Type(ValidatableType::KIND_BUILT_IN,
+             "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
+             {"memory", "string", "vector"},
+             "::std::unique_ptr<::std::vector<std::unique_ptr<::std::string>>>",
+             "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector") {}
+  ~NullableUtf8InCppStringListType() override = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NullableUtf8InCppStringListType);
+};  // class NullableUtf8InCppStringListType
+
+class Utf8InCppStringListType : public Type {
+ public:
+  Utf8InCppStringListType()
+      : Type(ValidatableType::KIND_BUILT_IN,
+             "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
+             {"string", "vector"},
+             "::std::vector<::std::string>",
+             "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
+             kNoArrayType, new NullableUtf8InCppStringListType()) {}
+  ~Utf8InCppStringListType() override = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Utf8InCppStringListType);
+};  // class Utf8InCppStringListType
+
+class NullableBinderListType : public Type {
+ public:
+  NullableBinderListType()
+      : Type(ValidatableType::KIND_BUILT_IN, "java.util",
+             "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
+             "::std::unique_ptr<::std::vector<::android::sp<::android::IBinder>>>",
+             "readStrongBinderVector", "writeStrongBinderVector") {}
+  ~NullableBinderListType() override = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(NullableBinderListType);
+};  // class NullableBinderListType
+
+class BinderListType : public Type {
+ public:
+  BinderListType()
+      : Type(ValidatableType::KIND_BUILT_IN, "java.util",
+             "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
+             "::std::vector<::android::sp<::android::IBinder>>",
+             "readStrongBinderVector", "writeStrongBinderVector",
+             kNoArrayType, new NullableBinderListType()) {}
+  ~BinderListType() override = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(BinderListType);
+};  // class BinderListType
+
+}  // namespace
+
+Type::Type(int kind,
+           const std::string& package,
+           const std::string& aidl_type,
+           const vector<string>& headers,
+           const string& cpp_type,
+           const string& read_method,
+           const string& write_method,
+           Type* array_type,
+           Type* nullable_type,
+           const string& src_file_name,
+           int line)
+    : ValidatableType(kind, package, aidl_type, src_file_name, line),
+      headers_(headers),
+      aidl_type_(aidl_type),
+      cpp_type_(cpp_type),
+      parcel_read_method_(read_method),
+      parcel_write_method_(write_method),
+      array_type_(array_type),
+      nullable_type_(nullable_type) {}
+
+bool Type::CanWriteToParcel() const { return true; }
+
+void TypeNamespace::Init() {
+  Add(std::make_unique<ByteType>());
+  Add(std::make_unique<PrimitiveType>("int", "cstdint", "int32_t", "readInt32", "writeInt32",
+                                      "readInt32Vector", "writeInt32Vector"));
+  Add(std::make_unique<PrimitiveType>("long", "cstdint", "int64_t", "readInt64", "writeInt64",
+                                      "readInt64Vector", "writeInt64Vector"));
+  Add(std::make_unique<PrimitiveType>("float", kNoHeader, "float", "readFloat", "writeFloat",
+                                      "readFloatVector", "writeFloatVector"));
+  Add(std::make_unique<PrimitiveType>("double", kNoHeader, "double", "readDouble", "writeDouble",
+                                      "readDoubleVector", "writeDoubleVector"));
+  Add(std::make_unique<PrimitiveType>("boolean", kNoHeader, "bool", "readBool", "writeBool",
+                                      "readBoolVector", "writeBoolVector"));
+  // C++11 defines the char16_t type as a built in for Unicode characters.
+  Add(std::make_unique<PrimitiveType>("char", kNoHeader, "char16_t", "readChar", "writeChar",
+                                      "readCharVector", "writeCharVector"));
+
+  Type* string_array_type = new CppArrayType(
+      ValidatableType::KIND_BUILT_IN, "java.lang", "String",
+      "utils/String16.h", "::android::String16",
+      "::std::unique_ptr<::android::String16>", "readString16Vector",
+      "writeString16Vector", false);
+
+  Type* nullable_string_type =
+      new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
+               {"memory", "utils/String16.h"}, "::std::unique_ptr<::android::String16>",
+               "readString16", "writeString16");
+
+  AddAndSetMember(&string_type_,
+                  std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
+                                         std::vector<std::string>{"utils/String16.h"},
+                                         "::android::String16", "readString16", "writeString16",
+                                         string_array_type, nullable_string_type));
+
+  using ::android::aidl::kAidlReservedTypePackage;
+  using ::android::aidl::kUtf8InCppStringClass;
+
+  // This type is a Utf16 string in the parcel, but deserializes to
+  // a std::string in Utf8 format when we use it in C++.
+  Type* cpp_utf8_string_array = new CppArrayType(
+      ValidatableType::KIND_BUILT_IN,
+      kAidlReservedTypePackage, kUtf8InCppStringClass,
+      "string", "::std::string", "::std::unique_ptr<::std::string>",
+      "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
+      false);
+  Type* nullable_cpp_utf8_string_type =
+      new Type(ValidatableType::KIND_BUILT_IN, kAidlReservedTypePackage, kUtf8InCppStringClass,
+               std::vector<std::string>{"string", "memory"}, "::std::unique_ptr<::std::string>",
+               "readUtf8FromUtf16", "writeUtf8AsUtf16");
+  Add(std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, kAidlReservedTypePackage,
+                             kUtf8InCppStringClass, std::vector<std::string>{"string"},
+                             "::std::string", "readUtf8FromUtf16", "writeUtf8AsUtf16",
+                             cpp_utf8_string_array, nullable_cpp_utf8_string_type));
+
+  Type* nullable_ibinder = new Type(
+      ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
+      {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
+      "readNullableStrongBinder", "writeStrongBinder");
+
+  AddAndSetMember(&ibinder_type_,
+                  std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
+                                         std::vector<std::string>{"binder/IBinder.h"},
+                                         "::android::sp<::android::IBinder>", "readStrongBinder",
+                                         "writeStrongBinder", kNoArrayType, nullable_ibinder));
+
+  Add(std::make_unique<MapType>());
+
+  Add(std::make_unique<BinderListType>());
+  Add(std::make_unique<StringListType>());
+  Add(std::make_unique<Utf8InCppStringListType>());
+
+  Type* fd_vector_type = new CppArrayType(
+      ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
+      "android-base/unique_fd.h",
+      "::android::base::unique_fd", "::android::base::unique_fd",
+      "readUniqueFileDescriptorVector", "writeUniqueFileDescriptorVector",
+      false);
+
+  Add(std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
+                             std::vector<std::string>{"android-base/unique_fd.h"},
+                             "::android::base::unique_fd", "readUniqueFileDescriptor",
+                             "writeUniqueFileDescriptor", fd_vector_type));
+
+  Type* pfd_vector_type =
+      new CppArrayType(ValidatableType::KIND_BUILT_IN, "android.os", "ParcelFileDescriptor",
+                       "binder/ParcelFileDescriptor.h", "::android::os::ParcelFileDescriptor",
+                       "::android::os::ParcelFileDescriptor", "readParcelableVector",
+                       "writeParcelableVector", false);
+
+  Type* nullable_pfd_type =
+      new Type(ValidatableType::KIND_BUILT_IN, "android.os", "ParcelFileDescriptor",
+               std::vector<std::string>{"memory", "binder/ParcelFileDescriptor.h"},
+               "::std::unique_ptr<::android::os::ParcelFileDescriptor>", "readParcelable",
+               "writeNullableParcelable");
+
+  Add(std::make_unique<Type>(ValidatableType::KIND_BUILT_IN, "android.os", "ParcelFileDescriptor",
+                             std::vector<std::string>{"binder/ParcelFileDescriptor.h"},
+                             "::android::os::ParcelFileDescriptor", "readParcelable",
+                             "writeParcelable", pfd_vector_type, nullable_pfd_type));
+
+  // Qualify VoidType so we don't get collisions with the VoidType method
+  AddAndSetMember(&void_type_, std::make_unique<class VoidType>());
+}
+
+bool TypeNamespace::AddParcelableType(const AidlParcelable& p, const std::string& filename) {
+  const std::string cpp_header = p.AsStructuredParcelable() ? GetCppHeader(p) : p.GetCppHeader();
+
+  if (cpp_header.empty()) {
+    AIDL_ERROR(p) << "Parcelable " << p.GetCanonicalName() << " has no C++ header defined.";
+    return false;
+  }
+
+  Add(std::make_unique<ParcelableType>(p, cpp_header, filename));
+  return true;
+}
+
+bool TypeNamespace::AddBinderType(const AidlInterface& b, const std::string& filename) {
+  Add(std::make_unique<BinderType>(b, filename));
+  return true;
+}
+
+bool TypeNamespace::AddListType(const std::string& type_name) {
+  const Type* contained_type = FindTypeByCanonicalName(type_name);
+  if (!contained_type) {
+    LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
+                  "type cannot be found or is invalid.";
+    return false;
+  }
+  if (contained_type->IsCppPrimitive()) {
+    LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
+                  "type is a primitive in Java and Java List cannot hold "
+                  "primitives.";
+    return false;
+  }
+
+  if (contained_type->CanonicalName() == kStringCanonicalName ||
+      contained_type->CanonicalName() == kUtf8InCppStringCanonicalName ||
+      contained_type == IBinderType()) {
+    return true;
+  }
+
+  // TODO Support lists of parcelables b/23600712
+
+  LOG(ERROR) << "aidl-cpp does not yet support List<" << type_name << ">";
+  return false;
+}
+
+bool TypeNamespace::AddMapType(const std::string& /* key_type_name */,
+                               const std::string& /* value_type_name */) {
+  // TODO Support list types b/25242025
+  LOG(ERROR) << "aidl does not implement support for typed maps!";
+  return false;
+}
+
+const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a, int arg_index,
+                                                 const AidlDefinedType& context) const {
+  return ::android::aidl::TypeNamespace::GetArgType(a, arg_index, context);
+}
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
diff --git a/type_cpp.h b/type_cpp.h
new file mode 100644
index 0000000..a27132b
--- /dev/null
+++ b/type_cpp.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <set>
+#include <vector>
+
+#include <android-base/macros.h>
+
+#include "type_namespace.h"
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+class Type : public ValidatableType {
+ public:
+  Type(int kind,  // from ValidatableType
+       const std::string& package,
+       const std::string& aidl_type,
+       const std::vector<std::string>& header,
+       const std::string& cpp_type,
+       const std::string& read_method,
+       const std::string& write_method,
+       Type* array_type = nullptr,
+       Type* nullable_type = nullptr,
+       const std::string& src_file_name = "",
+       int line = -1);
+  virtual ~Type() = default;
+
+  // overrides of ValidatableType
+  bool CanWriteToParcel() const override;
+
+  const Type* ArrayType() const override { return array_type_.get(); }
+  const Type* NullableType() const override { return nullable_type_.get(); }
+  std::string CppType() const { return cpp_type_; }
+  const std::string& ReadFromParcelMethod() const {
+    return parcel_read_method_;
+  }
+  const std::string& WriteToParcelMethod() const {
+    return parcel_write_method_;
+  }
+
+  void GetHeaders(std::set<std::string>* headers) const {
+    for (const std::string& header : headers_) {
+      if (!header.empty()) {
+        headers->insert(header);
+      }
+    }
+  }
+  virtual bool IsCppPrimitive() const { return false; }
+  virtual std::string WriteCast(const std::string& value) const {
+    return value;
+  }
+
+ private:
+  // |headers| are the headers we must include to use this type
+  const std::vector<std::string> headers_;
+  // |aidl_type| is what we find in the yacc generated AST (e.g. "int").
+  const std::string aidl_type_;
+  // |cpp_type| is what we use in the generated C++ code (e.g. "int32_t").
+  const std::string cpp_type_;
+  const std::string parcel_read_method_;
+  const std::string parcel_write_method_;
+
+  const std::unique_ptr<Type> array_type_;
+  const std::unique_ptr<Type> nullable_type_;
+
+  DISALLOW_COPY_AND_ASSIGN(Type);
+};  // class Type
+
+class TypeNamespace : public ::android::aidl::LanguageTypeNamespace<Type> {
+ public:
+  TypeNamespace() = default;
+  virtual ~TypeNamespace() = default;
+
+  void Init() override;
+  bool AddParcelableType(const AidlParcelable& p,
+                         const std::string& filename) override;
+  bool AddBinderType(const AidlInterface& b,
+                     const std::string& filename) override;
+  bool AddListType(const std::string& type_name) override;
+  bool AddMapType(const std::string& key_type_name,
+                  const std::string& value_type_name) override;
+
+  const ValidatableType* GetArgType(const AidlArgument& a, int arg_index,
+                                    const AidlDefinedType& context) const override;
+
+  const Type* VoidType() const { return void_type_; }
+  const Type* IBinderType() const { return ibinder_type_; }
+
+ private:
+  const Type* void_type_ = nullptr;
+  const Type* string_type_ = nullptr;
+  const Type* ibinder_type_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(TypeNamespace);
+};  // class TypeNamespace
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
diff --git a/type_cpp_unittest.cpp b/type_cpp_unittest.cpp
new file mode 100644
index 0000000..79b47a9
--- /dev/null
+++ b/type_cpp_unittest.cpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+#include <string>
+
+#include <gtest/gtest.h>
+
+#include "type_cpp.h"
+
+using std::string;
+using std::unique_ptr;
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+namespace {
+
+string kParcelableDotName = "Outer.Inner";
+string kParcelableColonName = "Outer::Inner";
+
+}  // namespace
+
+class CppTypeNamespaceTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    types_.Init();
+  }
+  TypeNamespace types_;
+};
+
+TEST_F(CppTypeNamespaceTest, HasSomeBasicTypes) {
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("byte"));
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("int"));
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("long"));
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("float"));
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("double"));
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("boolean"));
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("char"));
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("String"));
+}
+
+TEST_F(CppTypeNamespaceTest, SupportsListString) {
+  EXPECT_TRUE(
+      types_.HasTypeByCanonicalName("java.util.List<java.lang.String>"));
+}
+
+TEST_F(CppTypeNamespaceTest, SupportsNestedParcelableClass) {
+  unique_ptr<AidlParcelable> parcelable(new AidlParcelable(
+      AIDL_LOCATION_HERE, new AidlQualifiedName(AIDL_LOCATION_HERE, kParcelableDotName, ""),
+      {"a", "goog"}, ""));
+  EXPECT_EQ(parcelable->GetCppName(), kParcelableColonName);
+}
+
+}  // namespace cpp
+}  // namespace android
+}  // namespace aidl
diff --git a/type_java.cpp b/type_java.cpp
new file mode 100644
index 0000000..1298eac
--- /dev/null
+++ b/type_java.cpp
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "type_java.h"
+
+#include <sys/types.h>
+#include <memory>
+
+#include <android-base/strings.h>
+
+#include "aidl_language.h"
+#include "logging.h"
+
+using std::string;
+
+namespace android {
+namespace aidl {
+namespace java {
+
+Expression* NULL_VALUE;
+Expression* THIS_VALUE;
+Expression* SUPER_VALUE;
+Expression* TRUE_VALUE;
+Expression* FALSE_VALUE;
+
+// ================================================================
+
+Type::Type(const JavaTypeNamespace* types, const string& name, int kind, bool canWriteToParcel)
+    : Type(types, "", name, kind, canWriteToParcel, "", -1) {}
+
+Type::Type(const JavaTypeNamespace* types, const string& package, const string& name, int kind,
+           bool canWriteToParcel, const string& declFile, int declLine)
+    : ValidatableType(kind, package, name, declFile, declLine),
+      m_types(types),
+      m_javaType((package.empty()) ? name : package + "." + name),
+      m_canWriteToParcel(canWriteToParcel) {}
+
+string Type::InstantiableName() const { return JavaType(); }
+
+Expression* Type::BuildWriteToParcelFlags(int flags) const {
+  if (flags == 0) {
+    return new LiteralExpression("0");
+  }
+  if ((flags & PARCELABLE_WRITE_RETURN_VALUE) != 0) {
+    return new FieldVariable(m_types->ParcelableInterfaceType()->JavaType(),
+                             "PARCELABLE_WRITE_RETURN_VALUE");
+  }
+  return new LiteralExpression("0");
+}
+
+// ================================================================
+
+BasicType::BasicType(const JavaTypeNamespace* types, const string& name,
+                     const string& marshallParcel, const string& unmarshallParcel,
+                     const string& writeArrayParcel, const string& createArrayParcel,
+                     const string& readArrayParcel)
+    : Type(types, name, ValidatableType::KIND_BUILT_IN, true),
+      m_marshallParcel(marshallParcel),
+      m_unmarshallParcel(unmarshallParcel) {
+  m_array_type.reset(new BasicArrayType(types, name, writeArrayParcel,
+                                        createArrayParcel, readArrayParcel));
+}
+
+BasicArrayType::BasicArrayType(const JavaTypeNamespace* types, const string& name,
+                               const string& writeArrayParcel, const string& createArrayParcel,
+                               const string& readArrayParcel)
+    : Type(types, name, ValidatableType::KIND_BUILT_IN, true),
+      m_writeArrayParcel(writeArrayParcel),
+      m_createArrayParcel(createArrayParcel),
+      m_readArrayParcel(readArrayParcel) {}
+
+// ================================================================
+
+FileDescriptorType::FileDescriptorType(const JavaTypeNamespace* types)
+    : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN, true) {
+  m_array_type.reset(new FileDescriptorArrayType(types));
+}
+
+FileDescriptorArrayType::FileDescriptorArrayType(const JavaTypeNamespace* types)
+    : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+ParcelFileDescriptorType::ParcelFileDescriptorType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "ParcelFileDescriptor", ValidatableType::KIND_BUILT_IN, true) {
+  m_array_type.reset(new ParcelFileDescriptorArrayType(types));
+}
+
+ParcelFileDescriptorArrayType::ParcelFileDescriptorArrayType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "ParcelFileDescriptor", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+BooleanType::BooleanType(const JavaTypeNamespace* types)
+    : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true) {
+  m_array_type.reset(new BooleanArrayType(types));
+}
+
+BooleanArrayType::BooleanArrayType(const JavaTypeNamespace* types)
+    : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+CharType::CharType(const JavaTypeNamespace* types)
+    : Type(types, "char", ValidatableType::KIND_BUILT_IN, true) {
+  m_array_type.reset(new CharArrayType(types));
+}
+
+CharArrayType::CharArrayType(const JavaTypeNamespace* types)
+    : Type(types, "char", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+StringType::StringType(const JavaTypeNamespace* types, const std::string& package,
+                       const std::string& class_name)
+    : Type(types, package, class_name, ValidatableType::KIND_BUILT_IN, true) {
+  m_array_type.reset(new StringArrayType(types));
+}
+
+StringArrayType::StringArrayType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "String", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+CharSequenceType::CharSequenceType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "CharSequence", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+RemoteExceptionType::RemoteExceptionType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "RemoteException", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+RuntimeExceptionType::RuntimeExceptionType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "RuntimeException", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+IBinderType::IBinderType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN, true) {
+  m_array_type.reset(new IBinderArrayType(types));
+}
+
+IBinderArrayType::IBinderArrayType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+IInterfaceType::IInterfaceType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "IInterface", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+BinderType::BinderType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "Binder", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+BinderProxyType::BinderProxyType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "BinderProxy", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+ParcelType::ParcelType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "Parcel", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+ParcelableInterfaceType::ParcelableInterfaceType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "Parcelable", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+MapType::MapType(const JavaTypeNamespace* types)
+    : Type(types, "java.util", "Map", ValidatableType::KIND_BUILT_IN, true) {}
+
+// ================================================================
+
+ListType::ListType(const JavaTypeNamespace* types)
+    : Type(types, "java.util", "List", ValidatableType::KIND_BUILT_IN, true) {}
+
+string ListType::InstantiableName() const { return "java.util.ArrayList"; }
+
+// ================================================================
+
+UserDataType::UserDataType(const JavaTypeNamespace* types, const string& package,
+                           const string& name, bool builtIn, bool canWriteToParcel,
+                           const string& declFile, int declLine)
+    : Type(types, package, name,
+           builtIn ? ValidatableType::KIND_BUILT_IN : ValidatableType::KIND_PARCELABLE,
+           canWriteToParcel, declFile, declLine) {
+  m_array_type.reset(new UserDataArrayType(types, package, name, builtIn,
+                                           canWriteToParcel, declFile,
+                                           declLine));
+}
+
+UserDataArrayType::UserDataArrayType(const JavaTypeNamespace* types, const string& package,
+                                     const string& name, bool builtIn, bool canWriteToParcel,
+                                     const string& declFile, int declLine)
+    : Type(types, package, name,
+           builtIn ? ValidatableType::KIND_BUILT_IN : ValidatableType::KIND_PARCELABLE,
+           canWriteToParcel, declFile, declLine) {}
+
+// ================================================================
+
+InterfaceType::InterfaceType(const JavaTypeNamespace* types, const string& package,
+                             const string& name, bool builtIn, const string& declFile, int declLine,
+                             const Type* stub, const Type* proxy, const Type* defaultImpl)
+    : Type(types, package, name,
+           builtIn ? ValidatableType::KIND_BUILT_IN : ValidatableType::KIND_INTERFACE, true,
+           declFile, declLine),
+      stub_(stub),
+      proxy_(proxy),
+      defaultImpl_(defaultImpl) {}
+
+// ================================================================
+
+GenericListType::GenericListType(const JavaTypeNamespace* types, const Type* contained_type)
+    : Type(types, "java.util", "List<" + contained_type->CanonicalName() + ">",
+           ValidatableType::KIND_BUILT_IN, true),
+      m_contained_type(contained_type) {}
+
+string GenericListType::InstantiableName() const {
+  return "java.util.ArrayList<" + m_contained_type->JavaType() + ">";
+}
+
+// ================================================================
+
+ClassLoaderType::ClassLoaderType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "ClassLoader", ValidatableType::KIND_BUILT_IN, false) {}
+
+// ================================================================
+
+void JavaTypeNamespace::Init() {
+  Add(std::make_unique<BasicType>(this, "void", "XXX", "XXX", "XXX", "XXX", "XXX"));
+
+  AddAndSetMember(&m_bool_type, std::make_unique<BooleanType>(this));
+
+  Add(std::make_unique<BasicType>(this, "byte", "writeByte", "readByte", "writeByteArray",
+                                  "createByteArray", "readByteArray"));
+
+  Add(std::make_unique<CharType>(this));
+
+  AddAndSetMember(&m_int_type,
+                  std::make_unique<BasicType>(this, "int", "writeInt", "readInt", "writeIntArray",
+                                              "createIntArray", "readIntArray"));
+
+  Add(std::make_unique<BasicType>(this, "long", "writeLong", "readLong", "writeLongArray",
+                                  "createLongArray", "readLongArray"));
+
+  Add(std::make_unique<BasicType>(this, "float", "writeFloat", "readFloat", "writeFloatArray",
+                                  "createFloatArray", "readFloatArray"));
+
+  Add(std::make_unique<BasicType>(this, "double", "writeDouble", "readDouble", "writeDoubleArray",
+                                  "createDoubleArray", "readDoubleArray"));
+
+  AddAndSetMember(&m_string_type, std::make_unique<class StringType>(this, "java.lang", "String"));
+  Add(std::make_unique<class StringType>(this, ::android::aidl::kAidlReservedTypePackage,
+                                         ::android::aidl::kUtf8InCppStringClass));
+
+  Add(std::make_unique<Type>(this, "java.lang", "Object", ValidatableType::KIND_BUILT_IN, false));
+
+  Add(std::make_unique<FileDescriptorType>(this));
+
+  Add(std::make_unique<ParcelFileDescriptorType>(this));
+
+  Add(std::make_unique<CharSequenceType>(this));
+
+  Add(std::make_unique<MapType>(this));
+
+  Add(std::make_unique<ListType>(this));
+
+  AddAndSetMember(&m_text_utils_type,
+                  std::make_unique<Type>(this, "android.text", "TextUtils",
+                                         ValidatableType::KIND_BUILT_IN, false));
+
+  AddAndSetMember(&m_remote_exception_type, std::make_unique<class RemoteExceptionType>(this));
+
+  AddAndSetMember(&m_runtime_exception_type, std::make_unique<class RuntimeExceptionType>(this));
+
+  AddAndSetMember(&m_ibinder_type, std::make_unique<class IBinderType>(this));
+
+  AddAndSetMember(&m_iinterface_type, std::make_unique<class IInterfaceType>(this));
+
+  AddAndSetMember(&m_binder_native_type, std::make_unique<BinderType>(this));
+
+  AddAndSetMember(&m_binder_proxy_type, std::make_unique<class BinderProxyType>(this));
+
+  AddAndSetMember(&m_parcel_type, std::make_unique<class ParcelType>(this));
+
+  AddAndSetMember(&m_parcelable_interface_type,
+                  std::make_unique<class ParcelableInterfaceType>(this));
+
+  AddAndSetMember(&m_context_type, std::make_unique<Type>(this, "android.content", "Context",
+                                                          ValidatableType::KIND_BUILT_IN, false));
+
+  AddAndSetMember(&m_classloader_type, std::make_unique<class ClassLoaderType>(this));
+
+  NULL_VALUE = new LiteralExpression("null");
+  THIS_VALUE = new LiteralExpression("this");
+  SUPER_VALUE = new LiteralExpression("super");
+  TRUE_VALUE = new LiteralExpression("true");
+  FALSE_VALUE = new LiteralExpression("false");
+}
+
+bool JavaTypeNamespace::AddParcelableType(const AidlParcelable& p,
+                                          const std::string& filename) {
+  return Add(
+      std::make_unique<UserDataType>(this, p.GetPackage(), p.GetName(), false, true, filename));
+}
+
+bool JavaTypeNamespace::AddBinderType(const AidlInterface& b,
+                                      const std::string& filename) {
+  // for interfaces, add the stub, proxy, and interface types.
+  auto stub = std::make_unique<Type>(this, b.GetPackage(), b.GetName() + ".Stub",
+                                     ValidatableType::KIND_GENERATED, false, filename);
+  auto proxy = std::make_unique<Type>(this, b.GetPackage(), b.GetName() + ".Stub.Proxy",
+                                      ValidatableType::KIND_GENERATED, false, filename);
+  auto defaultImpl = std::make_unique<Type>(this, b.GetPackage(), b.GetName() + ".Default",
+                                            ValidatableType::KIND_GENERATED, false, filename);
+  auto type = std::make_unique<InterfaceType>(this, b.GetPackage(), b.GetName(), false, filename,
+                                              -1, stub.get(), proxy.get(), defaultImpl.get());
+
+  bool success = true;
+  success &= Add(std::move(type));
+  success &= Add(std::move(stub));
+  success &= Add(std::move(proxy));
+  success &= Add(std::move(defaultImpl));
+  return success;
+}
+
+bool JavaTypeNamespace::AddListType(const std::string& contained_type_name) {
+  const Type* contained_type = FindTypeByCanonicalName(contained_type_name);
+  if (!contained_type) {
+    return false;
+  }
+  Add(std::make_unique<GenericListType>(this, contained_type));
+  return true;
+}
+
+bool JavaTypeNamespace::AddMapType(const string& /*key_type_name*/,
+                                   const string& /*value_type_name*/) {
+  LOG(ERROR) << "Don't know how to create a Map<K,V> container.";
+  return false;
+}
+
+}  // namespace java
+}  // namespace aidl
+}  // namespace android
diff --git a/type_java.h b/type_java.h
new file mode 100644
index 0000000..a5c1ff8
--- /dev/null
+++ b/type_java.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "ast_java.h"
+#include "type_namespace.h"
+
+namespace android {
+namespace aidl {
+namespace java {
+
+class JavaTypeNamespace;
+
+class Type : public ValidatableType {
+ public:
+  // WriteToParcel flags
+  enum { PARCELABLE_WRITE_RETURN_VALUE = 0x0001 };
+
+  // defaultValue is by default set to "null" because that is the default value
+  // for most of the types like class and array. default values for built-in
+  // types like int, double, boolean, etc. are explicitly set via BasicType
+  Type(const JavaTypeNamespace* types, const std::string& name, int kind, bool canWriteToParcel);
+  Type(const JavaTypeNamespace* types, const std::string& package, const std::string& name,
+       int kind, bool canWriteToParcel, const std::string& declFile = "", int declLine = -1);
+  virtual ~Type() = default;
+
+  bool CanWriteToParcel() const override { return m_canWriteToParcel; }
+
+  const ValidatableType* ArrayType() const override { return m_array_type.get(); }
+  const ValidatableType* NullableType() const override { return nullptr; }
+
+  virtual std::string JavaType() const { return m_javaType; }
+  virtual std::string InstantiableName() const;
+
+  // The namespace where this type is defined in
+  const JavaTypeNamespace* GetTypeNamespace() const { return m_types; }
+
+ protected:
+  Expression* BuildWriteToParcelFlags(int flags) const;
+
+  const JavaTypeNamespace* m_types;
+
+  std::unique_ptr<Type> m_array_type;
+
+ private:
+  Type();
+  Type(const Type&);
+
+  std::string m_javaType;
+  std::string m_declFile;
+  bool m_canWriteToParcel;
+};
+
+class BasicArrayType : public Type {
+ public:
+  BasicArrayType(const JavaTypeNamespace* types, const std::string& name,
+                 const std::string& writeArrayParcel,
+                 const std::string& createArrayParcel,
+                 const std::string& readArrayParcel);
+
+  const ValidatableType* NullableType() const override { return this; }
+
+ private:
+  std::string m_writeArrayParcel;
+  std::string m_createArrayParcel;
+  std::string m_readArrayParcel;
+};
+
+class BasicType : public Type {
+ public:
+  BasicType(const JavaTypeNamespace* types, const std::string& name,
+            const std::string& marshallParcel, const std::string& unmarshallParcel,
+            const std::string& writeArrayParcel, const std::string& createArrayParcel,
+            const std::string& readArrayParcel);
+
+ private:
+  std::string m_marshallParcel;
+  std::string m_unmarshallParcel;
+};
+
+class FileDescriptorArrayType : public Type {
+ public:
+  explicit FileDescriptorArrayType(const JavaTypeNamespace* types);
+
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class FileDescriptorType : public Type {
+ public:
+  explicit FileDescriptorType(const JavaTypeNamespace* types);
+};
+
+class ParcelFileDescriptorArrayType : public Type {
+ public:
+  explicit ParcelFileDescriptorArrayType(const JavaTypeNamespace* types);
+
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class ParcelFileDescriptorType : public Type {
+ public:
+  explicit ParcelFileDescriptorType(const JavaTypeNamespace* types);
+
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class BooleanArrayType : public Type {
+ public:
+  explicit BooleanArrayType(const JavaTypeNamespace* types);
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class BooleanType : public Type {
+ public:
+  explicit BooleanType(const JavaTypeNamespace* types);
+};
+
+class CharArrayType : public Type {
+ public:
+  explicit CharArrayType(const JavaTypeNamespace* types);
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class CharType : public Type {
+ public:
+  explicit CharType(const JavaTypeNamespace* types);
+};
+
+class StringArrayType : public Type {
+ public:
+  explicit StringArrayType(const JavaTypeNamespace* types);
+
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class StringType : public Type {
+ public:
+  StringType(const JavaTypeNamespace* types, const std::string& package,
+             const std::string& class_name);
+
+  std::string JavaType() const override { return "java.lang.String"; }
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class CharSequenceType : public Type {
+ public:
+  explicit CharSequenceType(const JavaTypeNamespace* types);
+};
+
+class RemoteExceptionType : public Type {
+ public:
+  explicit RemoteExceptionType(const JavaTypeNamespace* types);
+};
+
+class RuntimeExceptionType : public Type {
+ public:
+  explicit RuntimeExceptionType(const JavaTypeNamespace* types);
+};
+
+class IBinderArrayType : public Type {
+ public:
+  explicit IBinderArrayType(const JavaTypeNamespace* types);
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class IBinderType : public Type {
+ public:
+  explicit IBinderType(const JavaTypeNamespace* types);
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class IInterfaceType : public Type {
+ public:
+  explicit IInterfaceType(const JavaTypeNamespace* types);
+};
+
+class BinderType : public Type {
+ public:
+  explicit BinderType(const JavaTypeNamespace* types);
+};
+
+class BinderProxyType : public Type {
+ public:
+  explicit BinderProxyType(const JavaTypeNamespace* types);
+};
+
+class ParcelType : public Type {
+ public:
+  explicit ParcelType(const JavaTypeNamespace* types);
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class ParcelableInterfaceType : public Type {
+ public:
+  explicit ParcelableInterfaceType(const JavaTypeNamespace* types);
+};
+
+class MapType : public Type {
+ public:
+  explicit MapType(const JavaTypeNamespace* types);
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class ListType : public Type {
+ public:
+  explicit ListType(const JavaTypeNamespace* types);
+
+  std::string InstantiableName() const override;
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class UserDataArrayType : public Type {
+ public:
+  UserDataArrayType(const JavaTypeNamespace* types, const std::string& package,
+                    const std::string& name, bool builtIn,
+                    bool canWriteToParcel, const std::string& declFile = "",
+                    int declLine = -1);
+
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class UserDataType : public Type {
+ public:
+  UserDataType(const JavaTypeNamespace* types, const std::string& package,
+               const std::string& name, bool builtIn, bool canWriteToParcel,
+               const std::string& declFile = "", int declLine = -1);
+
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class InterfaceType : public Type {
+ public:
+  InterfaceType(const JavaTypeNamespace* types, const std::string& package, const std::string& name,
+                bool builtIn, const std::string& declFile, int declLine, const Type* stub,
+                const Type* proxy, const Type* defaultImpl);
+
+  const ValidatableType* NullableType() const override { return this; }
+  const Type* GetStub() const { return stub_; }
+  const Type* GetProxy() const { return proxy_; }
+  const Type* GetDefaultImpl() const { return defaultImpl_; }
+
+ private:
+  const Type* stub_;
+  const Type* proxy_;
+  const Type* defaultImpl_;
+};
+
+class ClassLoaderType : public Type {
+ public:
+  explicit ClassLoaderType(const JavaTypeNamespace* types);
+};
+
+class GenericListType : public Type {
+ public:
+  GenericListType(const JavaTypeNamespace* types, const Type* arg);
+
+  std::string InstantiableName() const override;
+  std::string JavaType() const override {
+    return "java.util.List<" + m_contained_type->JavaType() + ">";
+  }
+
+  const ValidatableType* NullableType() const override { return this; }
+
+ private:
+  const Type* m_contained_type;
+};
+
+class JavaTypeNamespace : public LanguageTypeNamespace<Type> {
+ public:
+  JavaTypeNamespace() = default;
+  virtual ~JavaTypeNamespace() = default;
+
+  void Init() override;
+  bool AddParcelableType(const AidlParcelable& p,
+                         const std::string& filename) override;
+  bool AddBinderType(const AidlInterface& b,
+                     const std::string& filename) override;
+  bool AddListType(const std::string& contained_type_name) override;
+  bool AddMapType(const std::string& key_type_name,
+                  const std::string& value_type_name) override;
+
+  const Type* BoolType() const { return m_bool_type; }
+  const Type* IntType() const { return m_int_type; }
+  const Type* StringType() const { return m_string_type; }
+  const Type* TextUtilsType() const { return m_text_utils_type; }
+  const Type* RemoteExceptionType() const { return m_remote_exception_type; }
+  const Type* RuntimeExceptionType() const { return m_runtime_exception_type; }
+  const Type* IBinderType() const { return m_ibinder_type; }
+  const Type* IInterfaceType() const { return m_iinterface_type; }
+  const Type* BinderNativeType() const { return m_binder_native_type; }
+  const Type* BinderProxyType() const { return m_binder_proxy_type; }
+  const Type* ParcelType() const { return m_parcel_type; }
+  const Type* ParcelableInterfaceType() const {
+    return m_parcelable_interface_type;
+  }
+  const Type* ContextType() const { return m_context_type; }
+  const Type* ClassLoaderType() const { return m_classloader_type; }
+
+ private:
+  const Type* m_bool_type{nullptr};
+  const Type* m_int_type{nullptr};
+  const Type* m_string_type{nullptr};
+  const Type* m_text_utils_type{nullptr};
+  const Type* m_remote_exception_type{nullptr};
+  const Type* m_runtime_exception_type{nullptr};
+  const Type* m_ibinder_type{nullptr};
+  const Type* m_iinterface_type{nullptr};
+  const Type* m_binder_native_type{nullptr};
+  const Type* m_binder_proxy_type{nullptr};
+  const Type* m_parcel_type{nullptr};
+  const Type* m_parcelable_interface_type{nullptr};
+  const Type* m_context_type{nullptr};
+  const Type* m_classloader_type{nullptr};
+
+  DISALLOW_COPY_AND_ASSIGN(JavaTypeNamespace);
+};
+
+extern Expression* NULL_VALUE;
+extern Expression* THIS_VALUE;
+extern Expression* SUPER_VALUE;
+extern Expression* TRUE_VALUE;
+extern Expression* FALSE_VALUE;
+
+}  // namespace java
+}  // namespace aidl
+}  // namespace android
diff --git a/type_java_unittest.cpp b/type_java_unittest.cpp
new file mode 100644
index 0000000..098a7a5
--- /dev/null
+++ b/type_java_unittest.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+
+#include <gtest/gtest.h>
+
+#include "aidl_language.h"
+#include "type_java.h"
+
+using std::unique_ptr;
+
+namespace android {
+namespace aidl {
+namespace java {
+
+class JavaTypeNamespaceTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    types_.Init();
+  }
+  JavaTypeNamespace types_;
+};
+
+TEST_F(JavaTypeNamespaceTest, HasSomeBasicTypes) {
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("void"));
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("int"));
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("java.lang.String"));
+}
+
+TEST_F(JavaTypeNamespaceTest, ContainerTypeCreation) {
+  // We start with no knowledge of parcelables or lists of them.
+  EXPECT_FALSE(types_.HasTypeByCanonicalName("Foo"));
+  EXPECT_FALSE(types_.HasTypeByCanonicalName("java.util.List<a.goog.Foo>"));
+  unique_ptr<AidlParcelable> parcelable(new AidlParcelable(
+      AIDL_LOCATION_HERE, new AidlQualifiedName(AIDL_LOCATION_HERE, "Foo", ""), {"a", "goog"}, ""));
+  // Add the parcelable type we care about.
+  EXPECT_TRUE(types_.AddParcelableType(*parcelable.get(), __FILE__));
+  // Now we can find the parcelable type, but not the List of them.
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("a.goog.Foo"));
+  EXPECT_FALSE(types_.HasTypeByCanonicalName("java.util.List<a.goog.Foo>"));
+  // But after we add the list explicitly...
+  std::vector<std::unique_ptr<AidlTypeSpecifier>>* type_args =
+      new std::vector<std::unique_ptr<AidlTypeSpecifier>>();
+  type_args->emplace_back(new AidlTypeSpecifier(AIDL_LOCATION_HERE, "Foo", false, nullptr, ""));
+  AidlTypeSpecifier container_type(AIDL_LOCATION_HERE, "List", false, type_args, "");
+  EXPECT_TRUE(types_.MaybeAddContainerType(container_type));
+  // This should work.
+  EXPECT_TRUE(types_.HasTypeByCanonicalName("java.util.List<a.goog.Foo>"));
+}
+
+}  // namespace java
+}  // namespace android
+}  // namespace aidl
diff --git a/type_namespace.cpp b/type_namespace.cpp
new file mode 100644
index 0000000..e8e5a29
--- /dev/null
+++ b/type_namespace.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "type_namespace.h"
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "aidl_language.h"
+#include "logging.h"
+
+using android::base::StringPrintf;
+using std::string;
+using std::vector;
+
+namespace android {
+namespace aidl {
+
+// Since packages cannot contain '-' normally, we cannot be asked
+// to create a type that conflicts with these strings.
+const char kAidlReservedTypePackage[] = "aidl-internal";
+const char kUtf8InCppStringClass[] = "Utf8InCppString";
+
+// These *must* match the package and class names above.
+const char kUtf8InCppStringCanonicalName[] = "aidl-internal.Utf8InCppString";
+
+const char kStringCanonicalName[] = "java.lang.String";
+
+const char kUtf8InCppAnnotation[] = "@utfInCpp";
+
+namespace {
+
+bool is_java_keyword(const char* str) {
+  static const std::vector<std::string> kJavaKeywords{
+      "abstract",   "assert",       "boolean",   "break",      "byte",
+      "case",       "catch",        "char",      "class",      "const",
+      "continue",   "default",      "do",        "double",     "else",
+      "enum",       "extends",      "final",     "finally",    "float",
+      "for",        "goto",         "if",        "implements", "import",
+      "instanceof", "int",          "interface", "long",       "native",
+      "new",        "package",      "private",   "protected",  "public",
+      "return",     "short",        "static",    "strictfp",   "super",
+      "switch",     "synchronized", "this",      "throw",      "throws",
+      "transient",  "try",          "void",      "volatile",   "while",
+      "true",       "false",        "null",
+  };
+  return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) !=
+      kJavaKeywords.end();
+}
+
+} // namespace
+
+ValidatableType::ValidatableType(
+    int kind, const string& package, const string& type_name,
+    const string& decl_file, int decl_line)
+    : kind_(kind),
+      type_name_(type_name),
+      canonical_name_((package.empty()) ? type_name
+                                        : package + "." + type_name),
+      origin_file_(decl_file),
+      origin_line_(decl_line) {}
+
+string ValidatableType::HumanReadableKind() const {
+  switch (Kind()) {
+    case ValidatableType::KIND_BUILT_IN:
+      return "a built in";
+    case ValidatableType::KIND_PARCELABLE:
+      return "a parcelable";
+    case ValidatableType::KIND_INTERFACE:
+      return "an interface";
+    case ValidatableType::KIND_GENERATED:
+      return "a generated";
+  }
+  return "unknown";
+}
+
+const ValidatableType* TypeNamespace::GetReturnType(const AidlTypeSpecifier& raw_type,
+                                                    const AidlDefinedType& context) const {
+  string error_msg;
+  const ValidatableType* return_type = GetValidatableType(raw_type, &error_msg, context);
+  if (return_type == nullptr) {
+    AIDL_ERROR(raw_type) << "Return type " << raw_type.ToString() << ": " << error_msg;
+    return nullptr;
+  }
+
+  return return_type;
+}
+
+bool TypeNamespace::AddDefinedTypes(vector<AidlDefinedType*>& types, const string& filename) {
+  bool success = true;
+  for (const auto type : types) {
+    const AidlInterface* interface = type->AsInterface();
+    if (interface != nullptr) {
+      success &= AddBinderType(*interface, filename);
+      continue;
+    }
+
+    const AidlParcelable* parcelable = type->AsParcelable();
+    if (parcelable != nullptr) {
+      success &= AddParcelableType(*parcelable, filename);
+      continue;
+    }
+
+    CHECK(false) << "aidl internal error: unrecognized type";
+  }
+  return success;
+}
+
+const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a, int arg_index,
+                                                 const AidlDefinedType& context) const {
+  string error_prefix =
+      StringPrintf("parameter %s (argument %d): ", a.GetName().c_str(), arg_index);
+
+  // check the arg type
+  string error_msg;
+  const ValidatableType* t = GetValidatableType(a.GetType(), &error_msg, context);
+  if (t == nullptr) {
+    AIDL_ERROR(a) << error_prefix << error_msg;
+    return nullptr;
+  }
+
+  const bool can_be_out = typenames_.CanBeOutParameter(a.GetType());
+  if (!a.DirectionWasSpecified() && can_be_out) {
+    AIDL_ERROR(a) << error_prefix << "'" << a.GetType().ToString()
+                  << "' can be an out type, so you must declare it as in, out, or inout.";
+    return nullptr;
+  }
+
+  if (a.GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
+    AIDL_ERROR(a) << error_prefix << "'" << a.ToString() << "' can only be an in parameter.";
+    return nullptr;
+  }
+
+  // check that the name doesn't match a keyword
+  if (is_java_keyword(a.GetName().c_str())) {
+    AIDL_ERROR(a) << error_prefix << "Argument name is a Java or aidl keyword";
+    return nullptr;
+  }
+
+  // Reserve a namespace for internal use
+  if (a.GetName().substr(0, 5)  == "_aidl") {
+    AIDL_ERROR(a) << error_prefix << "Argument name cannot begin with '_aidl'";
+    return nullptr;
+  }
+
+  return t;
+}
+
+}  // namespace aidl
+}  // namespace android
diff --git a/type_namespace.h b/type_namespace.h
new file mode 100644
index 0000000..a7952fb
--- /dev/null
+++ b/type_namespace.h
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2015, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include <android-base/macros.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+#include "aidl_language.h"
+#include "logging.h"
+
+namespace android {
+namespace aidl {
+
+// Special reserved type names.
+extern const char kAidlReservedTypePackage[];
+extern const char kUtf8InCppStringClass[];  // UTF16 wire format, UTF8 in C++
+
+// Helpful aliases defined to be <kAidlReservedTypePackage>.<class name>
+extern const char kUtf8InCppStringCanonicalName[];
+
+// We sometimes special case this class.
+extern const char kStringCanonicalName[];
+
+// Note that these aren't the strings recognized by the parser, we just keep
+// here for the sake of logging a common string constant.
+extern const char kUtf8InCppAnnotation[];
+
+class ValidatableType {
+ public:
+  enum {
+    KIND_BUILT_IN,
+    KIND_PARCELABLE,
+    KIND_INTERFACE,
+    KIND_GENERATED,
+  };
+
+  ValidatableType(int kind,
+                  const std::string& package, const std::string& type_name,
+                  const std::string& decl_file, int decl_line);
+  virtual ~ValidatableType() = default;
+
+  virtual bool CanBeArray() const { return ArrayType() != nullptr; }
+  virtual bool CanWriteToParcel() const = 0;
+
+  virtual const ValidatableType* ArrayType() const = 0;
+  virtual const ValidatableType* NullableType() const = 0;
+
+  // ShortName() is the class name without a package.
+  std::string ShortName() const { return type_name_; }
+  // CanonicalName() returns the canonical AIDL type, with packages.
+  std::string CanonicalName() const { return canonical_name_; }
+
+  int Kind() const { return kind_; }
+  std::string HumanReadableKind() const;
+  std::string DeclFile() const { return origin_file_; }
+  int DeclLine() const { return origin_line_; }
+
+ private:
+  const int kind_;
+  const std::string type_name_;
+  const std::string canonical_name_;
+  const std::string origin_file_;
+  const int origin_line_;
+
+  DISALLOW_COPY_AND_ASSIGN(ValidatableType);
+};
+
+class TypeNamespace {
+ public:
+  // Load the TypeNamespace with built in types.  Don't do work in the
+  // constructor because many of the useful methods are virtual.
+  virtual void Init() = 0;
+
+  bool AddDefinedTypes(vector<AidlDefinedType*>& types, const string& filename);
+
+  // Load this TypeNamespace with user defined types.
+  virtual bool AddParcelableType(const AidlParcelable& p,
+                                 const std::string& filename) = 0;
+
+  virtual bool AddBinderType(const AidlInterface& b,
+                             const std::string& filename) = 0;
+  // Add a container type to this namespace.  Returns false only
+  // on error. Silently discards requests to add non-container types.
+  virtual bool MaybeAddContainerType(const AidlTypeSpecifier& aidl_type) = 0;
+
+  // Returns true iff this has a type for |import|.
+  virtual bool HasImportType(const std::string& import) const = 0;
+
+  // Returns a pointer to a type corresponding to |raw_type| or nullptr
+  // if this is an invalid return type.
+  virtual const ValidatableType* GetReturnType(const AidlTypeSpecifier& raw_type,
+                                               const AidlDefinedType& context) const;
+
+  // Returns a pointer to a type corresponding to |a| or nullptr if |a|
+  // has an invalid argument type.
+  virtual const ValidatableType* GetArgType(const AidlArgument& a, int arg_index,
+                                            const AidlDefinedType& context) const;
+
+  // Returns a pointer to a type corresponding to |defined_type|.
+  virtual const ValidatableType* GetDefinedType(const AidlDefinedType& defined_type) const = 0;
+
+  AidlTypenames typenames_;
+
+ protected:
+  TypeNamespace() = default;
+  virtual ~TypeNamespace() = default;
+
+  virtual const ValidatableType* GetValidatableType(const AidlTypeSpecifier& type,
+                                                    std::string* error_msg,
+                                                    const AidlDefinedType& context) const = 0;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TypeNamespace);
+};
+
+template<typename T>
+class LanguageTypeNamespace : public TypeNamespace {
+ public:
+  LanguageTypeNamespace() = default;
+  virtual ~LanguageTypeNamespace() = default;
+
+  // Get a pointer to an existing type.  Searches first by fully-qualified
+  // name, and then class name (dropping package qualifiers).
+  const T* Find(const AidlTypeSpecifier& aidl_type) const;
+
+  // Find a type by its |name|.  If |name| refers to a container type (e.g.
+  // List<String>) you must turn it into a canonical name first (e.g.
+  // java.util.List<java.lang.String>).
+  const T* FindTypeByCanonicalName(const std::string& name) const;
+  bool HasTypeByCanonicalName(const std::string& type_name) const {
+    return FindTypeByCanonicalName(type_name) != nullptr;
+  }
+  bool HasImportType(const std::string& import) const override {
+    return HasTypeByCanonicalName(import);
+  }
+  const ValidatableType* GetDefinedType(const AidlDefinedType& defined_type) const override {
+    return FindTypeByCanonicalName(defined_type.GetCanonicalName());
+  }
+
+  bool MaybeAddContainerType(const AidlTypeSpecifier& aidl_type) override;
+  // We dynamically create container types as we discover them in the parse
+  // tree.  Returns false if the contained types cannot be canonicalized.
+  virtual bool AddListType(const std::string& contained_type_name) = 0;
+  virtual bool AddMapType(const std::string& key_type_name,
+                          const std::string& value_type_name) = 0;
+
+ protected:
+  bool Add(std::unique_ptr<const T> type);
+  void AddAndSetMember(const T** member, std::unique_ptr<const T> type) {
+    const T* ptr_value = type.get();
+    CHECK(Add(std::move(type)));
+    *member = ptr_value;
+  }
+
+ private:
+  // Returns true iff the name can be canonicalized to a container type.
+  virtual bool CanonicalizeContainerType(const AidlTypeSpecifier& aidl_type,
+                                         std::vector<std::string>* container_class,
+                                         std::vector<std::string>* contained_type_names) const;
+
+  // Returns true if this is a container type, rather than a normal type.
+  bool IsContainerType(const std::string& type_name) const;
+
+  const ValidatableType* GetValidatableType(const AidlTypeSpecifier& type, std::string* error_msg,
+                                            const AidlDefinedType& context) const override;
+
+  std::vector<std::unique_ptr<const T>> types_;
+
+  DISALLOW_COPY_AND_ASSIGN(LanguageTypeNamespace);
+};  // class LanguageTypeNamespace
+
+template <typename T>
+bool LanguageTypeNamespace<T>::Add(std::unique_ptr<const T> type) {
+  const T* existing = FindTypeByCanonicalName(type->CanonicalName());
+  if (!existing) {
+    types_.push_back(std::move(type));
+    return true;
+  }
+
+  if (existing->Kind() == ValidatableType::KIND_BUILT_IN) {
+    LOG(ERROR) << type->DeclFile() << ":" << type->DeclLine()
+               << " attempt to redefine built in class "
+               << type->CanonicalName();
+    return false;
+  }
+
+  if (type->Kind() != existing->Kind()) {
+    LOG(ERROR) << type->DeclFile() << ":" << type->DeclLine()
+               << " attempt to redefine " << type->CanonicalName()
+               << " as " << type->HumanReadableKind();
+    LOG(ERROR) << existing->DeclFile() << ":" << existing->DeclLine()
+               << " previously defined here as "
+               << existing->HumanReadableKind();
+    return false;
+  }
+
+  return true;
+}
+
+template <typename T>
+const T* LanguageTypeNamespace<T>::Find(const AidlTypeSpecifier& aidl_type) const {
+  using std::string;
+  using std::vector;
+  using android::base::Join;
+  using android::base::Trim;
+
+  string name = Trim(aidl_type.IsArray() ? aidl_type.GetName() : aidl_type.ToString());
+  if (IsContainerType(name)) {
+    vector<string> container_class;
+    vector<string> contained_type_names;
+    if (!CanonicalizeContainerType(aidl_type, &container_class,
+                                   &contained_type_names)) {
+      return nullptr;
+    }
+    name = Join(container_class, '.') +
+           "<" + Join(contained_type_names, ',') + ">";
+  }
+  // Here, we know that we have the canonical name for this container.
+  return FindTypeByCanonicalName(name);
+}
+
+template<typename T>
+const T* LanguageTypeNamespace<T>::FindTypeByCanonicalName(
+    const std::string& raw_name) const {
+  using android::base::Trim;
+
+  std::string name = Trim(raw_name);
+  const T* ret = nullptr;
+  for (const auto& type : types_) {
+    // Always prefer a exact match if possible.
+    // This works for primitives and class names qualified with a package.
+    if (type->CanonicalName() == name) {
+      ret = type.get();
+      break;
+    }
+    // We allow authors to drop packages when refering to a class name.
+    if (type->ShortName() == name) {
+      ret = type.get();
+    }
+  }
+
+  return ret;
+}
+
+template <typename T>
+bool LanguageTypeNamespace<T>::MaybeAddContainerType(const AidlTypeSpecifier& aidl_type) {
+  using android::base::Join;
+
+  const std::string& type_name = aidl_type.ToString();
+  if (!IsContainerType(type_name)) {
+    return true;
+  }
+
+  std::vector<std::string> container_class;
+  std::vector<std::string> contained_type_names;
+  if (!CanonicalizeContainerType(aidl_type, &container_class,
+                                 &contained_type_names)) {
+    return false;
+  }
+
+  const std::string canonical_name = Join(container_class, ".") +
+      "<" + Join(contained_type_names, ",") + ">";
+  if (HasTypeByCanonicalName(canonical_name)) {
+    return true;
+  }
+
+
+  // We only support two types right now and this type is one of them.
+  switch (contained_type_names.size()) {
+    case 1:
+      return AddListType(contained_type_names[0]);
+    case 2:
+      return AddMapType(contained_type_names[0], contained_type_names[1]);
+    default:
+      break;  // Should never get here, will FATAL below.
+  }
+
+  LOG(FATAL) << "aidl internal error";
+  return false;
+}
+
+template<typename T>
+bool LanguageTypeNamespace<T>::IsContainerType(
+    const std::string& type_name) const {
+  const size_t opening_brace = type_name.find('<');
+  const size_t closing_brace = type_name.find('>');
+  if (opening_brace != std::string::npos ||
+      closing_brace != std::string::npos) {
+    return true;  // Neither < nor > appear in normal AIDL types.
+  }
+  return false;
+}
+
+template <typename T>
+bool LanguageTypeNamespace<T>::CanonicalizeContainerType(
+    const AidlTypeSpecifier& aidl_type, std::vector<std::string>* container_class,
+    std::vector<std::string>* contained_type_names) const {
+  std::string container = aidl_type.GetName();
+  std::vector<std::string> args;
+  for (auto& type_arg : aidl_type.GetTypeParameters()) {
+    if (type_arg->IsGeneric()) {
+      // nesting is not allowed yet.
+      LOG(ERROR) << "Nested template type '" << aidl_type.ToString() << "'";
+    }
+
+    std::string type_name = type_arg->ToString();
+    // Here, we are relying on FindTypeByCanonicalName to do its best when
+    // given a non-canonical name for non-compound type (i.e. not another
+    // container).
+    const T* arg_type = FindTypeByCanonicalName(type_name);
+    if (!arg_type) {
+      return false;
+    }
+
+    // Now get the canonical names for these contained types, remapping them if
+    // necessary.
+    type_name = arg_type->CanonicalName();
+    if (aidl_type.IsUtf8InCpp() && type_name == "java.lang.String") {
+      type_name = kUtf8InCppStringCanonicalName;
+    }
+    args.emplace_back(type_name);
+  }
+
+  // Map the container name to its canonical form for supported containers.
+  if ((container == "List" || container == "java.util.List") &&
+      args.size() == 1) {
+    *container_class = {"java", "util", "List"};
+    *contained_type_names = args;
+    return true;
+  }
+  if ((container == "Map" || container == "java.util.Map") &&
+      args.size() == 2) {
+    *container_class = {"java", "util", "Map"};
+    *contained_type_names = args;
+    return true;
+  }
+
+  LOG(ERROR) << "Unknown find container with name " << container << " and " << args.size()
+             << " contained types.";
+  return false;
+}
+
+template <typename T>
+const ValidatableType* LanguageTypeNamespace<T>::GetValidatableType(
+    const AidlTypeSpecifier& aidl_type, std::string* error_msg,
+    const AidlDefinedType& context) const {
+  using android::base::StringPrintf;
+
+  const ValidatableType* type = Find(aidl_type);
+  if (type == nullptr) {
+    *error_msg = "unknown type";
+    return nullptr;
+  }
+
+  if (aidl_type.GetName() == "void") {
+    if (aidl_type.IsArray()) {
+      *error_msg = "void type cannot be an array";
+      return nullptr;
+    }
+    if (aidl_type.IsNullable() || aidl_type.IsUtf8InCpp()) {
+      *error_msg = "void type cannot be annotated";
+      return nullptr;
+    }
+    // We have no more special handling for void.
+    return type;
+  }
+
+  bool utf8InCpp = aidl_type.IsUtf8InCpp();
+
+  // Strings inside containers get remapped to appropriate utf8 versions when
+  // we convert the container name to its canonical form and the look up the
+  // type.  However, for non-compound types (i.e. those not in a container) we
+  // must patch them up here.
+  if (IsContainerType(type->CanonicalName())) {
+    utf8InCpp = false;
+  } else if (aidl_type.GetName() == "String" ||
+             aidl_type.GetName() == "java.lang.String") {
+    utf8InCpp = utf8InCpp || context.IsUtf8InCpp();
+  } else if (utf8InCpp) {
+    *error_msg = StringPrintf("type '%s' may not be annotated as %s.", aidl_type.GetName().c_str(),
+                              kUtf8InCppAnnotation);
+    return nullptr;
+  }
+
+  if (utf8InCpp) {
+    type = FindTypeByCanonicalName(kUtf8InCppStringCanonicalName);
+  }
+
+  // One of our UTF8 transforms made type null
+  if (type == nullptr) {
+    *error_msg = StringPrintf("%s is unsupported when generating code for this language.",
+                              kUtf8InCppAnnotation);
+    return nullptr;
+  }
+
+  if (!type->CanWriteToParcel()) {
+    *error_msg = "type cannot be marshalled";
+    return nullptr;
+  }
+
+  if (aidl_type.IsArray()) {
+    type = type->ArrayType();
+    if (!type) {
+      *error_msg = StringPrintf("type '%s' cannot be an array",
+                                aidl_type.GetName().c_str());
+      return nullptr;
+    }
+  }
+
+  if (context.IsNullable()) {
+    const ValidatableType* nullableType = type->NullableType();
+
+    if (nullableType) {
+      return nullableType;
+    }
+  }
+
+  if (aidl_type.IsNullable()) {
+    type = type->NullableType();
+    if (!type) {
+      *error_msg = StringPrintf("type '%s%s' cannot be marked as possibly null",
+                                aidl_type.GetName().c_str(),
+                                (aidl_type.IsArray()) ? "[]" : "");
+      return nullptr;
+    }
+  }
+
+  return type;
+}
+
+}  // namespace aidl
+}  // namespace android