diff --git a/aidl/Android.mk b/aidl/Android.mk
new file mode 100644
index 0000000..3c1463a
--- /dev/null
+++ b/aidl/Android.mk
@@ -0,0 +1,204 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+aidl_cflags := -Wall -Wextra -Werror
+aidl_static_libraries := libbase libcutils
+
+aidl_module_host_os := darwin linux windows
+ifdef BRILLO
+  aidl_module_host_os := darwin linux
+endif
+
+# Logic shared between aidl and its unittests
+include $(CLEAR_VARS)
+LOCAL_MODULE := libaidl-common
+LOCAL_MODULE_HOST_OS := $(aidl_module_host_os)
+
+LOCAL_WHOLE_STATIC_LIBRARIES := libgtest_prod
+LOCAL_CLANG_CFLAGS := $(aidl_cflags)
+# Tragically, the code is riddled with unused parameters.
+LOCAL_CLANG_CFLAGS += -Wno-unused-parameter
+# yacc dumps a lot of code *just in case*.
+LOCAL_CLANG_CFLAGS += -Wno-unused-function
+LOCAL_CLANG_CFLAGS += -Wno-unneeded-internal-declaration
+# yacc is a tool from a more civilized age.
+LOCAL_CLANG_CFLAGS += -Wno-deprecated-register
+# yacc also has a habit of using char* over const char*.
+LOCAL_CLANG_CFLAGS += -Wno-writable-strings
+LOCAL_STATIC_LIBRARIES := $(aidl_static_libraries)
+
+LOCAL_SRC_FILES := \
+    aidl.cpp \
+    aidl_language.cpp \
+    aidl_language_l.ll \
+    aidl_language_y.yy \
+    ast_cpp.cpp \
+    ast_java.cpp \
+    code_writer.cpp \
+    generate_cpp.cpp \
+    generate_java.cpp \
+    generate_java_binder.cpp \
+    import_resolver.cpp \
+    line_reader.cpp \
+    io_delegate.cpp \
+    options.cpp \
+    type_cpp.cpp \
+    type_java.cpp \
+    type_namespace.cpp \
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+# aidl executable
+include $(CLEAR_VARS)
+LOCAL_MODULE := aidl
+
+LOCAL_MODULE_HOST_OS := $(aidl_module_host_os)
+LOCAL_CFLAGS := $(aidl_cflags)
+LOCAL_WHOLE_STATIC_LIBRARIES := libgtest_prod
+LOCAL_SRC_FILES := main_java.cpp
+LOCAL_STATIC_LIBRARIES := libaidl-common $(aidl_static_libraries)
+include $(BUILD_HOST_EXECUTABLE)
+
+# aidl-cpp executable
+include $(CLEAR_VARS)
+LOCAL_MODULE := aidl-cpp
+
+LOCAL_MODULE_HOST_OS := $(aidl_module_host_os)
+LOCAL_CFLAGS := $(aidl_cflags)
+LOCAL_WHOLE_STATIC_LIBRARIES := libgtest_prod
+LOCAL_SRC_FILES := main_cpp.cpp
+LOCAL_STATIC_LIBRARIES := libaidl-common $(aidl_static_libraries)
+include $(BUILD_HOST_EXECUTABLE)
+
+# Unit tests
+include $(CLEAR_VARS)
+LOCAL_MODULE := aidl_unittests
+LOCAL_MODULE_HOST_OS := darwin linux
+
+LOCAL_CFLAGS := $(aidl_cflags) -g -DUNIT_TEST
+# Tragically, the code is riddled with unused parameters.
+LOCAL_CLANG_CFLAGS := -Wno-unused-parameter
+LOCAL_SRC_FILES := \
+    aidl_unittest.cpp \
+    ast_cpp_unittest.cpp \
+    ast_java_unittest.cpp \
+    generate_cpp_unittest.cpp \
+    io_delegate_unittest.cpp \
+    options_unittest.cpp \
+    tests/end_to_end_tests.cpp \
+    tests/fake_io_delegate.cpp \
+    tests/main.cpp \
+    tests/test_data_example_interface.cpp \
+    tests/test_data_ping_responder.cpp \
+    tests/test_data_string_constants.cpp \
+    tests/test_util.cpp \
+    type_cpp_unittest.cpp \
+    type_java_unittest.cpp \
+
+LOCAL_STATIC_LIBRARIES := \
+    libaidl-common \
+    $(aidl_static_libraries) \
+    libgmock_host \
+
+LOCAL_LDLIBS_linux := -lrt
+include $(BUILD_HOST_NATIVE_TEST)
+
+#
+# Everything below here is used for integration testing of generated AIDL code.
+#
+aidl_integration_test_cflags := $(aidl_cflags) -Wunused-parameter
+aidl_integration_test_shared_libs := \
+    libbase \
+    libbinder \
+    liblog \
+    libutils
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libaidl-integration-test
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_CFLAGS := $(aidl_integration_test_cflags)
+LOCAL_SHARED_LIBRARIES := $(aidl_integration_test_shared_libs)
+LOCAL_AIDL_INCLUDES := \
+    system/tools/aidl/tests/ \
+    frameworks/native/aidl/binder
+LOCAL_SRC_FILES := \
+    tests/android/aidl/tests/ITestService.aidl \
+    tests/android/aidl/tests/INamedCallback.aidl \
+    tests/simple_parcelable.cpp
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := aidl_test_service
+LOCAL_CFLAGS := $(aidl_integration_test_cflags)
+LOCAL_SHARED_LIBRARIES := \
+    libaidl-integration-test \
+    $(aidl_integration_test_shared_libs)
+LOCAL_SRC_FILES := \
+    tests/aidl_test_service.cpp
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := aidl_test_client
+LOCAL_CFLAGS := $(aidl_integration_test_cflags)
+LOCAL_SHARED_LIBRARIES := \
+    libaidl-integration-test \
+    $(aidl_integration_test_shared_libs)
+LOCAL_SRC_FILES := \
+    tests/aidl_test_client.cpp \
+    tests/aidl_test_client_file_descriptors.cpp \
+    tests/aidl_test_client_parcelables.cpp \
+    tests/aidl_test_client_nullables.cpp \
+    tests/aidl_test_client_primitives.cpp \
+    tests/aidl_test_client_utf8_strings.cpp \
+    tests/aidl_test_client_service_exceptions.cpp
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := aidl_test_sentinel_searcher
+LOCAL_SRC_FILES := tests/aidl_test_sentinel_searcher.cpp
+LOCAL_CFLAGS := $(aidl_integration_test_cflags)
+include $(BUILD_EXECUTABLE)
+
+
+# aidl on its own doesn't need the framework, but testing native/java
+# compatibility introduces java dependencies.
+ifndef BRILLO
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := aidl_test_services
+# Turn off Java optimization tools to speed up our test iterations.
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+LOCAL_CERTIFICATE := platform
+LOCAL_MANIFEST_FILE := tests/java_app/AndroidManifest.xml
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/tests/java_app/resources
+LOCAL_SRC_FILES := \
+    tests/android/aidl/tests/INamedCallback.aidl \
+    tests/android/aidl/tests/ITestService.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 \
+    tests/java_app/src/android/aidl/tests/TestLogger.java \
+    tests/java_app/src/android/aidl/tests/TestServiceClient.java
+LOCAL_AIDL_INCLUDES := \
+    system/tools/aidl/tests/ \
+    frameworks/native/aidl/binder
+include $(BUILD_PACKAGE)
+
+endif  # not defined BRILLO
diff --git a/aidl/MODULE_LICENSE_APACHE2 b/aidl/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/aidl/MODULE_LICENSE_APACHE2
diff --git a/aidl/NOTICE b/aidl/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/aidl/NOTICE
@@ -0,0 +1,190 @@
+
+   Copyright (c) 2005-2008, 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.
+
+   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.
+
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
diff --git a/aidl/aidl.cpp b/aidl/aidl.cpp
new file mode 100644
index 0000000..cd778fa
--- /dev/null
+++ b/aidl/aidl.cpp
@@ -0,0 +1,771 @@
+/*
+ * 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.h"
+
+#include <fcntl.h>
+#include <iostream>
+#include <map>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifdef _WIN32
+#include <io.h>
+#include <direct.h>
+#include <sys/stat.h>
+#endif
+
+#include <android-base/strings.h>
+
+#include "aidl_language.h"
+#include "generate_cpp.h"
+#include "generate_java.h"
+#include "import_resolver.h"
+#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
+#endif
+
+using android::base::Join;
+using android::base::Split;
+using std::cerr;
+using std::endl;
+using std::map;
+using std::set;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+namespace android {
+namespace aidl {
+namespace {
+
+// The following are gotten as the offset from the allowable id's between
+// android.os.IBinder.FIRST_CALL_TRANSACTION=1 and
+// android.os.IBinder.LAST_CALL_TRANSACTION=16777215
+const int kMinUserSetMethodId = 0;
+const int kMaxUserSetMethodId = 16777214;
+
+bool check_filename(const std::string& filename,
+                    const std::string& package,
+                    const std::string& name,
+                    unsigned line) {
+    const char* p;
+    string expected;
+    string fn;
+    size_t len;
+    bool valid = false;
+
+    if (!IoDelegate::GetAbsolutePath(filename, &fn)) {
+      return false;
+    }
+
+    if (!package.empty()) {
+        expected = package;
+        expected += '.';
+    }
+
+    len = expected.length();
+    for (size_t i=0; i<len; i++) {
+        if (expected[i] == '.') {
+            expected[i] = OS_PATH_SEPARATOR;
+        }
+    }
+
+    expected.append(name, 0, name.find('.'));
+
+    expected += ".aidl";
+
+    len = fn.length();
+    valid = (len >= expected.length());
+
+    if (valid) {
+        p = fn.c_str() + (len - expected.length());
+
+#ifdef _WIN32
+        if (OS_PATH_SEPARATOR != '/') {
+            // Input filename under cygwin most likely has / separators
+            // whereas the expected string uses \\ separators. Adjust
+            // them accordingly.
+          for (char *c = const_cast<char *>(p); *c; ++c) {
+                if (*c == '/') *c = OS_PATH_SEPARATOR;
+            }
+        }
+#endif
+
+        // aidl assumes case-insensitivity on Mac Os and Windows.
+#if defined(__linux__)
+        valid = (expected == p);
+#else
+        valid = !strcasecmp(expected.c_str(), p);
+#endif
+    }
+
+    if (!valid) {
+        fprintf(stderr, "%s:%d interface %s should be declared in a file"
+                " called %s.\n",
+                filename.c_str(), line, name.c_str(), expected.c_str());
+    }
+
+    return valid;
+}
+
+bool check_filenames(const std::string& filename, const AidlDocument* doc) {
+  if (!doc)
+    return true;
+
+  const AidlInterface* interface = doc->GetInterface();
+
+  if (interface) {
+    return check_filename(filename, interface->GetPackage(),
+                          interface->GetName(), interface->GetLine());
+  }
+
+  bool success = true;
+
+  for (const auto& item : doc->GetParcelables()) {
+    success &= check_filename(filename, item->GetPackage(), item->GetName(),
+                              item->GetLine());
+  }
+
+  return success;
+}
+
+bool gather_types(const std::string& filename,
+                  const AidlDocument* doc,
+                  TypeNamespace* types) {
+  bool success = true;
+
+  const AidlInterface* interface = doc->GetInterface();
+
+  if (interface)
+    return types->AddBinderType(*interface, filename);
+
+  for (const auto& item : doc->GetParcelables()) {
+    success &= types->AddParcelableType(*item, filename);
+  }
+
+  return success;
+}
+
+int check_types(const string& filename,
+                const AidlInterface* c,
+                TypeNamespace* types) {
+  int err = 0;
+
+  if (c->IsUtf8() && c->IsUtf8InCpp()) {
+    cerr << filename << ":" << c->GetLine()
+         << "Interface cannot be marked as both @utf8 and @utf8InCpp";
+    err = 1;
+  }
+
+  // Has to be a pointer due to deleting copy constructor. No idea why.
+  map<string, const AidlMethod*> method_names;
+  for (const auto& m : c->GetMethods()) {
+    bool oneway = m->IsOneway() || c->IsOneway();
+
+    if (!types->MaybeAddContainerType(m->GetType())) {
+      err = 1;  // return type is invalid
+    }
+
+    const ValidatableType* return_type =
+        types->GetReturnType(m->GetType(), filename, *c);
+
+    if (!return_type) {
+      err = 1;
+    }
+
+    m->GetMutableType()->SetLanguageType(return_type);
+
+    if (oneway && m->GetType().GetName() != "void") {
+        cerr << filename << ":" << m->GetLine()
+            << " oneway method '" << m->GetName() << "' cannot return a value"
+            << endl;
+        err = 1;
+    }
+
+    int index = 1;
+    for (const auto& arg : m->GetArguments()) {
+      if (!types->MaybeAddContainerType(arg->GetType())) {
+        err = 1;
+      }
+
+      const ValidatableType* arg_type =
+          types->GetArgType(*arg, index, filename, *c);
+
+      if (!arg_type) {
+        err = 1;
+      }
+
+      arg->GetMutableType()->SetLanguageType(arg_type);
+
+      if (oneway && arg->IsOut()) {
+        cerr << filename << ":" << m->GetLine()
+            << " oneway method '" << m->GetName()
+            << "' cannot have out parameters" << endl;
+        err = 1;
+      }
+    }
+
+    auto it = method_names.find(m->GetName());
+    // prevent duplicate methods
+    if (it == method_names.end()) {
+      method_names[m->GetName()] = m.get();
+    } else {
+      cerr << filename << ":" << m->GetLine()
+           << " attempt to redefine method " << m->GetName() << "," << endl
+           << filename << ":" << it->second->GetLine()
+           << "    previously defined here." << endl;
+      err = 1;
+    }
+  }
+  return err;
+}
+
+void write_common_dep_file(const string& output_file,
+                           const vector<string>& aidl_sources,
+                           CodeWriter* writer) {
+  // Encode that the output file depends on aidl input files.
+  writer->Write("%s : \\\n", output_file.c_str());
+  writer->Write("  %s", Join(aidl_sources, " \\\n  ").c_str());
+  writer->Write("\n\n");
+
+  // Output "<input_aidl_file>: " so make won't fail if the input .aidl file
+  // has been deleted, moved or renamed in incremental build.
+  for (const auto& src : aidl_sources) {
+    writer->Write("%s :\n", src.c_str());
+  }
+}
+
+bool write_java_dep_file(const JavaOptions& options,
+                         const vector<unique_ptr<AidlImport>>& imports,
+                         const IoDelegate& io_delegate,
+                         const string& output_file_name) {
+  string dep_file_name = options.DependencyFilePath();
+  if (dep_file_name.empty()) {
+    return true;  // nothing to do
+  }
+  CodeWriterPtr writer = io_delegate.GetCodeWriter(dep_file_name);
+  if (!writer) {
+    LOG(ERROR) << "Could not open dependency file: " << dep_file_name;
+    return false;
+  }
+
+  vector<string> source_aidl = {options.input_file_name_};
+  for (const auto& import : imports) {
+    if (!import->GetFilename().empty()) {
+      source_aidl.push_back(import->GetFilename());
+    }
+  }
+
+  write_common_dep_file(output_file_name, source_aidl, writer.get());
+
+  return true;
+}
+
+bool write_cpp_dep_file(const CppOptions& options,
+                        const AidlInterface& interface,
+                        const vector<unique_ptr<AidlImport>>& imports,
+                        const IoDelegate& io_delegate) {
+  using ::android::aidl::cpp::HeaderFile;
+  using ::android::aidl::cpp::ClassNames;
+
+  string dep_file_name = options.DependencyFilePath();
+  if (dep_file_name.empty()) {
+    return true;  // nothing to do
+  }
+  CodeWriterPtr writer = io_delegate.GetCodeWriter(dep_file_name);
+  if (!writer) {
+    LOG(ERROR) << "Could not open dependency file: " << dep_file_name;
+    return false;
+  }
+
+  vector<string> source_aidl = {options.InputFileName()};
+  for (const auto& import : imports) {
+    if (!import->GetFilename().empty()) {
+      source_aidl.push_back(import->GetFilename());
+    }
+  }
+
+  vector<string> headers;
+  for (ClassNames c : {ClassNames::CLIENT,
+                       ClassNames::SERVER,
+                       ClassNames::INTERFACE}) {
+    headers.push_back(options.OutputHeaderDir() + '/' +
+                      HeaderFile(interface, c, false /* use_os_sep */));
+  }
+
+  write_common_dep_file(options.OutputCppFilePath(), source_aidl, writer.get());
+  writer->Write("\n");
+
+  // Generated headers also depend on the source aidl files.
+  writer->Write("%s : \\\n    %s\n", Join(headers, " \\\n    ").c_str(),
+                Join(source_aidl, " \\\n    ").c_str());
+
+  return true;
+}
+
+string generate_outputFileName(const JavaOptions& options,
+                               const AidlInterface& interface) {
+    const string& name = interface.GetName();
+    string package = interface.GetPackage();
+    string result;
+
+    // create the path to the destination folder based on the
+    // interface package name
+    result = options.output_base_folder_;
+    result += OS_PATH_SEPARATOR;
+
+    string packageStr = package;
+    size_t len = packageStr.length();
+    for (size_t i=0; i<len; i++) {
+        if (packageStr[i] == '.') {
+            packageStr[i] = OS_PATH_SEPARATOR;
+        }
+    }
+
+    result += packageStr;
+
+    // add the filename by replacing the .aidl extension to .java
+    result += OS_PATH_SEPARATOR;
+    result.append(name, 0, name.find('.'));
+    result += ".java";
+
+    return result;
+}
+
+int check_and_assign_method_ids(const char * filename,
+                                const std::vector<std::unique_ptr<AidlMethod>>& items) {
+    // Check whether there are any methods with manually assigned id's and any that are not.
+    // Either all method id's must be manually assigned or all of them must not.
+    // Also, check for duplicates of user set id's and that the id's are within the proper bounds.
+    set<int> usedIds;
+    bool hasUnassignedIds = false;
+    bool hasAssignedIds = false;
+    for (const auto& item : items) {
+        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.
+                fprintf(stderr,
+                        "%s:%d Found duplicate method id (%d) for method: %s\n",
+                        filename, item->GetLine(),
+                        item->GetId(), item->GetName().c_str());
+                return 1;
+            }
+            // Ensure that the user set id is within the appropriate limits
+            if (item->GetId() < kMinUserSetMethodId ||
+                    item->GetId() > kMaxUserSetMethodId) {
+                fprintf(stderr, "%s:%d Found out of bounds id (%d) for method: %s\n",
+                        filename, item->GetLine(),
+                        item->GetId(), item->GetName().c_str());
+                fprintf(stderr, "    Value for id must be between %d and %d inclusive.\n",
+                        kMinUserSetMethodId, kMaxUserSetMethodId);
+                return 1;
+            }
+            usedIds.insert(item->GetId());
+        } else {
+            hasUnassignedIds = true;
+        }
+        if (hasAssignedIds && hasUnassignedIds) {
+            fprintf(stderr,
+                    "%s: You must either assign id's to all methods or to none of them.\n",
+                    filename);
+            return 1;
+        }
+    }
+
+    // In the case that all methods have unassigned id's, set a unique id for them.
+    if (hasUnassignedIds) {
+        int newId = 0;
+        for (const auto& item : items) {
+            item->SetId(newId++);
+        }
+    }
+
+    // success
+    return 0;
+}
+
+bool validate_constants(const AidlInterface& interface) {
+  bool success = true;
+  set<string> names;
+  for (const std::unique_ptr<AidlIntConstant>& int_constant :
+       interface.GetIntConstants()) {
+    if (names.count(int_constant->GetName()) > 0) {
+      LOG(ERROR) << "Found duplicate constant name '" << int_constant->GetName()
+                 << "'";
+      success = false;
+    }
+    names.insert(int_constant->GetName());
+    // We've logged an error message for this on object construction.
+    success = success && int_constant->IsValid();
+  }
+  for (const std::unique_ptr<AidlStringConstant>& string_constant :
+       interface.GetStringConstants()) {
+    if (names.count(string_constant->GetName()) > 0) {
+      LOG(ERROR) << "Found duplicate constant name '" << string_constant->GetName()
+                 << "'";
+      success = false;
+    }
+    names.insert(string_constant->GetName());
+    // We've logged an error message for this on object construction.
+    success = success && string_constant->IsValid();
+  }
+  return success;
+}
+
+// TODO: Remove this in favor of using the YACC parser b/25479378
+bool ParsePreprocessedLine(const string& line, string* decl,
+                           vector<string>* package, string* class_name) {
+  // erase all trailing whitespace and semicolons
+  const size_t end = line.find_last_not_of(" ;\t");
+  if (end == string::npos) {
+    return false;
+  }
+  if (line.rfind(';', end) != string::npos) {
+    return false;
+  }
+
+  decl->clear();
+  string type;
+  vector<string> pieces = Split(line.substr(0, end + 1), " \t");
+  for (const string& piece : pieces) {
+    if (piece.empty()) {
+      continue;
+    }
+    if (decl->empty()) {
+      *decl = std::move(piece);
+    } else if (type.empty()) {
+      type = std::move(piece);
+    } else {
+      return false;
+    }
+  }
+
+  // Note that this logic is absolutely wrong.  Given a parcelable
+  // org.some.Foo.Bar, the class name is Foo.Bar, but this code will claim that
+  // the class is just Bar.  However, this was the way it was done in the past.
+  //
+  // See b/17415692
+  size_t dot_pos = type.rfind('.');
+  if (dot_pos != string::npos) {
+    *class_name = type.substr(dot_pos + 1);
+    *package = Split(type.substr(0, dot_pos), ".");
+  } else {
+    *class_name = type;
+    package->clear();
+  }
+
+  return true;
+}
+
+}  // namespace
+
+namespace internals {
+
+bool parse_preprocessed_file(const IoDelegate& io_delegate,
+                             const string& filename, TypeNamespace* types) {
+  bool success = true;
+  unique_ptr<LineReader> line_reader = io_delegate.GetLineReader(filename);
+  if (!line_reader) {
+    LOG(ERROR) << "cannot open preprocessed file: " << filename;
+    success = false;
+    return success;
+  }
+
+  string line;
+  unsigned lineno = 1;
+  for ( ; line_reader->ReadLine(&line); ++lineno) {
+    if (line.empty() || line.compare(0, 2, "//") == 0) {
+      // skip comments and empty lines
+      continue;
+    }
+
+    string decl;
+    vector<string> package;
+    string class_name;
+    if (!ParsePreprocessedLine(line, &decl, &package, &class_name)) {
+      success = false;
+      break;
+    }
+
+    if (decl == "parcelable") {
+      AidlParcelable doc(new AidlQualifiedName(class_name, ""),
+                         lineno, package);
+      types->AddParcelableType(doc, filename);
+    } else if (decl == "interface") {
+      auto temp = new std::vector<std::unique_ptr<AidlMember>>();
+      AidlInterface doc(class_name, lineno, "", false, temp, package);
+      types->AddBinderType(doc, filename);
+    } else {
+      success = false;
+      break;
+    }
+  }
+  if (!success) {
+    LOG(ERROR) << filename << ':' << lineno
+               << " malformed preprocessed file line: '" << line << "'";
+  }
+
+  return success;
+}
+
+AidlError load_and_validate_aidl(
+    const std::vector<std::string>& preprocessed_files,
+    const std::vector<std::string>& import_paths,
+    const std::string& input_file_name,
+    const IoDelegate& io_delegate,
+    TypeNamespace* types,
+    std::unique_ptr<AidlInterface>* returned_interface,
+    std::vector<std::unique_ptr<AidlImport>>* returned_imports) {
+  AidlError err = AidlError::OK;
+
+  std::map<AidlImport*,std::unique_ptr<AidlDocument>> docs;
+
+  // import the preprocessed file
+  for (const string& s : preprocessed_files) {
+    if (!parse_preprocessed_file(io_delegate, s, types)) {
+      err = AidlError::BAD_PRE_PROCESSED_FILE;
+    }
+  }
+  if (err != AidlError::OK) {
+    return err;
+  }
+
+  // parse the input file
+  Parser p{io_delegate};
+  if (!p.ParseFile(input_file_name)) {
+    return AidlError::PARSE_ERROR;
+  }
+
+  AidlDocument* parsed_doc = p.GetDocument();
+
+  unique_ptr<AidlInterface> interface(parsed_doc->ReleaseInterface());
+
+  if (!interface) {
+    LOG(ERROR) << "refusing to generate code from aidl file defining "
+                  "parcelable";
+    return AidlError::FOUND_PARCELABLE;
+  }
+
+  if (!check_filename(input_file_name.c_str(), interface->GetPackage(),
+                      interface->GetName(), interface->GetLine()) ||
+      !types->IsValidPackage(interface->GetPackage())) {
+    LOG(ERROR) << "Invalid package declaration '" << interface->GetPackage()
+               << "'";
+    return AidlError::BAD_PACKAGE;
+  }
+
+  // parse the imports of the input file
+  ImportResolver import_resolver{io_delegate, import_paths};
+  for (auto& import : p.GetImports()) {
+    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...
+      continue;
+    }
+    string import_path = import_resolver.FindImportFile(import->GetNeededClass());
+    if (import_path.empty()) {
+      cerr << import->GetFileFrom() << ":" << import->GetLine()
+           << ": couldn't find import for class "
+           << import->GetNeededClass() << endl;
+      err = AidlError::BAD_IMPORT;
+      continue;
+    }
+    import->SetFilename(import_path);
+
+    Parser p{io_delegate};
+    if (!p.ParseFile(import->GetFilename())) {
+      cerr << "error while parsing import for class "
+           << import->GetNeededClass() << endl;
+      err = AidlError::BAD_IMPORT;
+      continue;
+    }
+
+    std::unique_ptr<AidlDocument> document(p.ReleaseDocument());
+    if (!check_filenames(import->GetFilename(), document.get()))
+      err = AidlError::BAD_IMPORT;
+    docs[import.get()] = std::move(document);
+  }
+  if (err != AidlError::OK) {
+    return err;
+  }
+
+  // gather the types that have been declared
+  if (!types->AddBinderType(*interface.get(), input_file_name)) {
+    err = AidlError::BAD_TYPE;
+  }
+
+  interface->SetLanguageType(types->GetInterfaceType(*interface));
+
+  for (const auto& import : p.GetImports()) {
+    // If we skipped an unresolved import above (see comment there) we'll have
+    // an empty bucket here.
+    const auto import_itr = docs.find(import.get());
+    if (import_itr == docs.cend()) {
+      continue;
+    }
+
+    if (!gather_types(import->GetFilename(), import_itr->second.get(), types)) {
+      err = AidlError::BAD_TYPE;
+    }
+  }
+
+  // check the referenced types in parsed_doc to make sure we've imported them
+  if (check_types(input_file_name, interface.get(), types) != 0) {
+    err = AidlError::BAD_TYPE;
+  }
+  if (err != AidlError::OK) {
+    return err;
+  }
+
+
+  // assign method ids and validate.
+  if (check_and_assign_method_ids(input_file_name.c_str(),
+                                  interface->GetMethods()) != 0) {
+    return AidlError::BAD_METHOD_ID;
+  }
+  if (!validate_constants(*interface)) {
+    return AidlError::BAD_CONSTANTS;
+  }
+
+  if (returned_interface)
+    *returned_interface = std::move(interface);
+
+  if (returned_imports)
+    p.ReleaseImports(returned_imports);
+
+  return AidlError::OK;
+}
+
+} // namespace internals
+
+int compile_aidl_to_cpp(const CppOptions& options,
+                        const IoDelegate& io_delegate) {
+  unique_ptr<AidlInterface> interface;
+  std::vector<std::unique_ptr<AidlImport>> imports;
+  unique_ptr<cpp::TypeNamespace> types(new cpp::TypeNamespace());
+  types->Init();
+  AidlError err = internals::load_and_validate_aidl(
+      std::vector<std::string>{},  // no preprocessed files
+      options.ImportPaths(),
+      options.InputFileName(),
+      io_delegate,
+      types.get(),
+      &interface,
+      &imports);
+  if (err != AidlError::OK) {
+    return 1;
+  }
+
+  if (!write_cpp_dep_file(options, *interface, imports, io_delegate)) {
+    return 1;
+  }
+
+  return (cpp::GenerateCpp(options, *types, *interface, io_delegate)) ? 0 : 1;
+}
+
+int compile_aidl_to_java(const JavaOptions& options,
+                         const IoDelegate& io_delegate) {
+  unique_ptr<AidlInterface> interface;
+  std::vector<std::unique_ptr<AidlImport>> imports;
+  unique_ptr<java::JavaTypeNamespace> types(new java::JavaTypeNamespace());
+  types->Init();
+  AidlError aidl_err = internals::load_and_validate_aidl(
+      options.preprocessed_files_,
+      options.import_paths_,
+      options.input_file_name_,
+      io_delegate,
+      types.get(),
+      &interface,
+      &imports);
+  if (aidl_err == AidlError::FOUND_PARCELABLE && !options.fail_on_parcelable_) {
+    // We aborted code generation because this file contains parcelables.
+    // However, we were not told to complain if we find parcelables.
+    // Just generate a dep file and exit quietly.  The dep file is for a legacy
+    // use case by the SDK.
+    write_java_dep_file(options, imports, io_delegate, "");
+    return 0;
+  }
+  if (aidl_err != AidlError::OK) {
+    return 1;
+  }
+
+  string output_file_name = options.output_file_name_;
+  // if needed, generate the output file name from the base folder
+  if (output_file_name.empty() && !options.output_base_folder_.empty()) {
+    output_file_name = generate_outputFileName(options, *interface);
+  }
+
+  // make sure the folders of the output file all exists
+  if (!io_delegate.CreatePathForFile(output_file_name)) {
+    return 1;
+  }
+
+  if (!write_java_dep_file(options, imports, io_delegate, output_file_name)) {
+    return 1;
+  }
+
+  return generate_java(output_file_name, options.input_file_name_.c_str(),
+                       interface.get(), types.get(), io_delegate);
+}
+
+bool preprocess_aidl(const JavaOptions& options,
+                     const IoDelegate& io_delegate) {
+  unique_ptr<CodeWriter> writer =
+      io_delegate.GetCodeWriter(options.output_file_name_);
+
+  for (const auto& file : options.files_to_preprocess_) {
+    Parser p{io_delegate};
+    if (!p.ParseFile(file))
+      return false;
+    AidlDocument* doc = p.GetDocument();
+    string line;
+
+    const AidlInterface* interface = doc->GetInterface();
+
+    if (interface != nullptr &&
+        !writer->Write("interface %s;\n",
+                       interface->GetCanonicalName().c_str())) {
+      return false;
+    }
+
+    for (const auto& parcelable : doc->GetParcelables()) {
+      if (!writer->Write("parcelable %s;\n",
+                         parcelable->GetCanonicalName().c_str())) {
+        return false;
+      }
+    }
+  }
+
+  return writer->Close();
+}
+
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/aidl.h b/aidl/aidl.h
new file mode 100644
index 0000000..2e5b0ee
--- /dev/null
+++ b/aidl/aidl.h
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_AIDL_H_
+#define AIDL_AIDL_H_
+
+#include <limits>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "aidl_language.h"
+#include "io_delegate.h"
+#include "options.h"
+#include "type_namespace.h"
+
+namespace android {
+namespace aidl {
+
+enum class AidlError {
+  UNKOWN = std::numeric_limits<int32_t>::min(),
+  BAD_PRE_PROCESSED_FILE,
+  PARSE_ERROR,
+  FOUND_PARCELABLE,
+  BAD_PACKAGE,
+  BAD_IMPORT,
+  BAD_TYPE,
+  BAD_METHOD_ID,
+  GENERATION_ERROR,
+  BAD_CONSTANTS,
+
+  OK = 0,
+};
+
+int compile_aidl_to_cpp(const CppOptions& options,
+                        const IoDelegate& io_delegate);
+int compile_aidl_to_java(const JavaOptions& options,
+                         const IoDelegate& io_delegate);
+bool preprocess_aidl(const JavaOptions& options,
+                     const IoDelegate& io_delegate);
+
+namespace internals {
+
+AidlError load_and_validate_aidl(
+    const std::vector<std::string>& preprocessed_files,
+    const std::vector<std::string>& import_paths,
+    const std::string& input_file_name,
+    const IoDelegate& io_delegate,
+    TypeNamespace* types,
+    std::unique_ptr<AidlInterface>* returned_interface,
+    std::vector<std::unique_ptr<AidlImport>>* returned_imports);
+
+bool parse_preprocessed_file(const IoDelegate& io_delegate,
+                             const std::string& filename, TypeNamespace* types);
+
+} // namespace internals
+
+}  // namespace android
+}  // namespace aidl
+
+#endif  // AIDL_AIDL_H_
diff --git a/aidl/aidl_language.cpp b/aidl/aidl_language.cpp
new file mode 100644
index 0000000..bbe305b
--- /dev/null
+++ b/aidl/aidl_language.cpp
@@ -0,0 +1,312 @@
+#include "aidl_language.h"
+
+#include <iostream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+
+#include <android-base/parseint.h>
+#include <android-base/strings.h>
+
+#include "aidl_language_y.h"
+#include "logging.h"
+
+#ifdef _WIN32
+int isatty(int  fd)
+{
+    return (fd == 0);
+}
+#endif
+
+using android::aidl::IoDelegate;
+using android::base::Join;
+using android::base::Split;
+using std::cerr;
+using std::endl;
+using std::string;
+using std::unique_ptr;
+
+void yylex_init(void **);
+void yylex_destroy(void *);
+void yyset_in(FILE *f, void *);
+int yyparse(Parser*);
+YY_BUFFER_STATE yy_scan_buffer(char *, size_t, void *);
+void yy_delete_buffer(YY_BUFFER_STATE, void *);
+
+AidlToken::AidlToken(const std::string& text, const std::string& comments)
+    : text_(text),
+      comments_(comments) {}
+
+AidlType::AidlType(const std::string& name, unsigned line,
+                   const std::string& comments, bool is_array)
+    : name_(name),
+      line_(line),
+      is_array_(is_array),
+      comments_(comments) {}
+
+string AidlType::ToString() const {
+  return name_ + (is_array_ ? "[]" : "");
+}
+
+AidlArgument::AidlArgument(AidlArgument::Direction direction, AidlType* type,
+                           std::string name, unsigned line)
+    : type_(type),
+      direction_(direction),
+      direction_specified_(true),
+      name_(name),
+      line_(line) {}
+
+AidlArgument::AidlArgument(AidlType* type, std::string name, unsigned line)
+    : type_(type),
+      direction_(AidlArgument::IN_DIR),
+      direction_specified_(false),
+      name_(name),
+      line_(line) {}
+
+string AidlArgument::ToString() const {
+  string ret;
+
+  if (direction_specified_) {
+    switch(direction_) {
+    case AidlArgument::IN_DIR:
+      ret += "in ";
+      break;
+    case AidlArgument::OUT_DIR:
+      ret += "out ";
+      break;
+    case AidlArgument::INOUT_DIR:
+      ret += "inout ";
+      break;
+    }
+  }
+
+  ret += type_->ToString();
+  ret += " ";
+  ret += name_;
+
+  return ret;
+}
+
+AidlIntConstant::AidlIntConstant(std::string name, int32_t value)
+    : name_(name),
+      value_(value),
+      is_valid_(true) {}
+
+AidlIntConstant::AidlIntConstant(std::string name,
+                                 std::string value,
+                                 unsigned line_number)
+    : name_(name) {
+  uint32_t unsigned_val;
+  if (!android::base::ParseUint(value.c_str(), &unsigned_val)) {
+    is_valid_ = false;
+    LOG(ERROR) << "Found invalid int value '" << value
+               << "' on line " << line_number;
+  } else {
+    // Converting from unsigned to signed integer.
+    value_ = unsigned_val;
+    is_valid_ = true;
+  }
+}
+
+AidlStringConstant::AidlStringConstant(std::string name,
+                                       std::string value,
+                                       unsigned line_number)
+    : name_(name),
+      value_(value) {
+  is_valid_ = true;
+  for (size_t i = 0; i < value_.length(); ++i) {
+    const char& c = value_[i];
+    if (c <= 0x1f || // control characters are < 0x20
+        c >= 0x7f || // DEL is 0x7f
+        c == '\\') { // Disallow backslashes for future proofing.
+      LOG(ERROR) << "Found invalid character at index " << i
+                 << " in string constant '" << value_
+                 << "' beginning on line " << line_number;
+      is_valid_ = false;
+      break;
+    }
+  }
+}
+
+AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
+                       std::vector<std::unique_ptr<AidlArgument>>* args,
+                       unsigned line, const std::string& comments, int id)
+    : oneway_(oneway),
+      comments_(comments),
+      type_(type),
+      name_(name),
+      line_(line),
+      arguments_(std::move(*args)),
+      id_(id) {
+  has_id_ = true;
+  delete args;
+  for (const unique_ptr<AidlArgument>& a : arguments_) {
+    if (a->IsIn()) { in_arguments_.push_back(a.get()); }
+    if (a->IsOut()) { out_arguments_.push_back(a.get()); }
+  }
+}
+
+AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
+                       std::vector<std::unique_ptr<AidlArgument>>* args,
+                       unsigned line, const std::string& comments)
+    : AidlMethod(oneway, type, name, args, line, comments, 0) {
+  has_id_ = false;
+}
+
+Parser::Parser(const IoDelegate& io_delegate)
+    : io_delegate_(io_delegate) {
+  yylex_init(&scanner_);
+}
+
+AidlParcelable::AidlParcelable(AidlQualifiedName* name, unsigned line,
+                               const std::vector<std::string>& package,
+                               const std::string& cpp_header)
+    : name_(name),
+      line_(line),
+      package_(package),
+      cpp_header_(cpp_header) {
+  // Strip off quotation marks if we actually have a cpp header.
+  if (cpp_header_.length() >= 2) {
+    cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
+  }
+}
+
+std::string AidlParcelable::GetPackage() const {
+  return Join(package_, '.');
+}
+
+std::string AidlParcelable::GetCanonicalName() const {
+  if (package_.empty()) {
+    return GetName();
+  }
+  return GetPackage() + "." + GetName();
+}
+
+AidlInterface::AidlInterface(const std::string& name, unsigned line,
+                             const std::string& comments, bool oneway,
+                             std::vector<std::unique_ptr<AidlMember>>* members,
+                             const std::vector<std::string>& package)
+    : name_(name),
+      comments_(comments),
+      line_(line),
+      oneway_(oneway),
+      package_(package) {
+  for (auto& member : *members) {
+    AidlMember* local = member.release();
+    AidlMethod* method = local->AsMethod();
+    AidlIntConstant* int_constant = local->AsIntConstant();
+    AidlStringConstant* string_constant = local->AsStringConstant();
+
+    if (method) {
+      methods_.emplace_back(method);
+    } else if (int_constant) {
+      int_constants_.emplace_back(int_constant);
+    } else if (string_constant) {
+      string_constants_.emplace_back(string_constant);
+    } else {
+      LOG(FATAL) << "Member is neither method nor constant!";
+    }
+  }
+
+  delete members;
+}
+
+std::string AidlInterface::GetPackage() const {
+  return Join(package_, '.');
+}
+
+std::string AidlInterface::GetCanonicalName() const {
+  if (package_.empty()) {
+    return GetName();
+  }
+  return GetPackage() + "." + GetName();
+}
+
+AidlDocument::AidlDocument(AidlInterface* interface)
+    : interface_(interface) {}
+
+AidlQualifiedName::AidlQualifiedName(std::string term,
+                                     std::string comments)
+    : terms_({term}),
+      comments_(comments) {
+  if (term.find('.') != string::npos) {
+    terms_ = Split(term, ".");
+    for (const auto& term: terms_) {
+      if (term.empty()) {
+        LOG(FATAL) << "Malformed qualified identifier: '" << term << "'";
+      }
+    }
+  }
+}
+
+void AidlQualifiedName::AddTerm(const std::string& term) {
+  terms_.push_back(term);
+}
+
+AidlImport::AidlImport(const std::string& from,
+                       const std::string& needed_class, unsigned line)
+    : from_(from),
+      needed_class_(needed_class),
+      line_(line) {}
+
+Parser::~Parser() {
+  if (raw_buffer_) {
+    yy_delete_buffer(buffer_, scanner_);
+    raw_buffer_.reset();
+  }
+  yylex_destroy(scanner_);
+}
+
+bool Parser::ParseFile(const string& filename) {
+  // Make sure we can read the file first, before trashing previous state.
+  unique_ptr<string> new_buffer = io_delegate_.GetFileContents(filename);
+  if (!new_buffer) {
+    LOG(ERROR) << "Error while opening file for parsing: '" << filename << "'";
+    return false;
+  }
+
+  // Throw away old parsing state if we have any.
+  if (raw_buffer_) {
+    yy_delete_buffer(buffer_, scanner_);
+    raw_buffer_.reset();
+  }
+
+  raw_buffer_ = std::move(new_buffer);
+  // We're going to scan this buffer in place, and yacc demands we put two
+  // nulls at the end.
+  raw_buffer_->append(2u, '\0');
+  filename_ = filename;
+  package_.reset();
+  error_ = 0;
+  document_.reset();
+
+  buffer_ = yy_scan_buffer(&(*raw_buffer_)[0], raw_buffer_->length(), scanner_);
+
+  if (yy::parser(this).parse() != 0 || error_ != 0) {
+    return false;}
+
+  if (document_.get() != nullptr)
+    return true;
+
+  LOG(ERROR) << "Parser succeeded but yielded no document!";
+  return false;
+}
+
+void Parser::ReportError(const string& err, unsigned line) {
+  cerr << filename_ << ":" << line << ": " << err << endl;
+  error_ = 1;
+}
+
+std::vector<std::string> Parser::Package() const {
+  if (!package_) {
+    return {};
+  }
+  return package_->GetTerms();
+}
+
+void Parser::AddImport(AidlQualifiedName* name, unsigned line) {
+  imports_.emplace_back(new AidlImport(this->FileName(),
+                                       name->GetDotName(), line));
+  delete name;
+}
diff --git a/aidl/aidl_language.h b/aidl/aidl_language.h
new file mode 100644
index 0000000..e27cd10
--- /dev/null
+++ b/aidl/aidl_language.h
@@ -0,0 +1,428 @@
+#ifndef AIDL_AIDL_LANGUAGE_H_
+#define AIDL_AIDL_LANGUAGE_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <android-base/macros.h>
+#include <android-base/strings.h>
+
+#include <io_delegate.h>
+
+struct yy_buffer_state;
+typedef yy_buffer_state* YY_BUFFER_STATE;
+
+class AidlToken {
+ public:
+  AidlToken(const std::string& text, const std::string& comments);
+
+  const std::string& GetText() const { return text_; }
+  const std::string& GetComments() const { return comments_; }
+
+ private:
+  std::string text_;
+  std::string comments_;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlToken);
+};
+
+class AidlNode {
+ public:
+  AidlNode() = default;
+  virtual ~AidlNode() = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AidlNode);
+};
+
+namespace android {
+namespace aidl {
+
+class ValidatableType;
+
+}  // namespace aidl
+}  // namespace android
+
+class AidlAnnotatable : public AidlNode {
+ public:
+  enum Annotation : uint32_t {
+    AnnotationNone = 0,
+    AnnotationNullable = 1 << 0,
+    AnnotationUtf8 = 1 << 1,
+    AnnotationUtf8InCpp = 1 << 2,
+  };
+
+  AidlAnnotatable() = default;
+  virtual ~AidlAnnotatable() = default;
+
+  void Annotate(AidlAnnotatable::Annotation annotation) {
+    annotations_ =
+        static_cast<AidlAnnotatable::Annotation>(annotations_ | annotation);
+  }
+  bool IsNullable() const {
+    return annotations_ & AnnotationNullable;
+  }
+  bool IsUtf8() const {
+    return annotations_ & AnnotationUtf8;
+  }
+  bool IsUtf8InCpp() const {
+    return annotations_ & AnnotationUtf8InCpp;
+  }
+
+ private:
+  Annotation annotations_ = AnnotationNone;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlAnnotatable);
+};
+
+class AidlType : public AidlAnnotatable {
+ public:
+  AidlType(const std::string& name, unsigned line,
+           const std::string& comments, bool is_array);
+  virtual ~AidlType() = default;
+
+  const std::string& GetName() const { return name_; }
+  unsigned GetLine() const { return line_; }
+  bool IsArray() const { return is_array_; }
+  const std::string& GetComments() const { return comments_; }
+
+  std::string ToString() 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:
+  std::string name_;
+  unsigned line_;
+  bool is_array_;
+  std::string comments_;
+  const android::aidl::ValidatableType* language_type_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlType);
+};
+
+class AidlArgument : public AidlNode {
+ public:
+  enum Direction { IN_DIR = 1, OUT_DIR = 2, INOUT_DIR = 3 };
+
+  AidlArgument(AidlArgument::Direction direction, AidlType* type,
+               std::string name, unsigned line);
+  AidlArgument(AidlType* type, std::string name, unsigned line);
+  virtual ~AidlArgument() = default;
+
+  Direction GetDirection() const { return direction_; }
+  bool IsOut() const { return direction_ & OUT_DIR; }
+  bool IsIn() const { return direction_ & IN_DIR; }
+  bool DirectionWasSpecified() const { return direction_specified_; }
+
+  std::string GetName() const { return name_; }
+  int GetLine() const { return line_; }
+  const AidlType& GetType() const { return *type_; }
+  AidlType* GetMutableType() { return type_.get(); }
+
+  std::string ToString() const;
+
+ private:
+  std::unique_ptr<AidlType> type_;
+  Direction direction_;
+  bool direction_specified_;
+  std::string name_;
+  unsigned line_;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlArgument);
+};
+
+class AidlMethod;
+class AidlIntConstant;
+class AidlStringConstant;
+class AidlMember : public AidlNode {
+ public:
+  AidlMember() = default;
+  virtual ~AidlMember() = default;
+
+  virtual AidlMethod* AsMethod() { return nullptr; }
+  virtual AidlIntConstant* AsIntConstant() { return nullptr; }
+  virtual AidlStringConstant* AsStringConstant() { return nullptr; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AidlMember);
+};
+
+class AidlIntConstant : public AidlMember {
+ public:
+  AidlIntConstant(std::string name, int32_t value);
+  AidlIntConstant(std::string name, std::string value, unsigned line_number);
+  virtual ~AidlIntConstant() = default;
+
+  const std::string& GetName() const { return name_; }
+  int GetValue() const { return value_; }
+  bool IsValid() const { return is_valid_; }
+
+  AidlIntConstant* AsIntConstant() override { return this; }
+
+ private:
+  std::string name_;
+  int32_t value_;
+  bool is_valid_;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlIntConstant);
+};
+
+class AidlStringConstant : public AidlMember {
+ public:
+  AidlStringConstant(std::string name, std::string value, unsigned line_number);
+  virtual ~AidlStringConstant() = default;
+
+  const std::string& GetName() const { return name_; }
+  const std::string& GetValue() const { return value_; }
+  bool IsValid() const { return is_valid_; }
+
+  AidlStringConstant* AsStringConstant() override { return this; }
+
+ private:
+  std::string name_;
+  std::string value_;
+  bool is_valid_;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlStringConstant);
+};
+
+class AidlMethod : public AidlMember {
+ public:
+  AidlMethod(bool oneway, AidlType* type, std::string name,
+             std::vector<std::unique_ptr<AidlArgument>>* args,
+             unsigned line, const std::string& comments);
+  AidlMethod(bool oneway, AidlType* type, std::string name,
+             std::vector<std::unique_ptr<AidlArgument>>* args,
+             unsigned line, const std::string& comments, int id);
+  virtual ~AidlMethod() = default;
+
+  AidlMethod* AsMethod() override { return this; }
+
+  const std::string& GetComments() const { return comments_; }
+  const AidlType& GetType() const { return *type_; }
+  AidlType* GetMutableType() { return type_.get(); }
+  bool IsOneway() const { return oneway_; }
+  const std::string& GetName() const { return name_; }
+  unsigned GetLine() const { return line_; }
+  bool HasId() const { return has_id_; }
+  int GetId() { return id_; }
+  void SetId(unsigned id) { id_ = id; }
+
+  const std::vector<std::unique_ptr<AidlArgument>>& GetArguments() const {
+    return arguments_;
+  }
+  // An inout parameter will appear in both GetInArguments()
+  // and GetOutArguments().  AidlMethod retains ownership of the argument
+  // pointers returned in this way.
+  const std::vector<const AidlArgument*>& GetInArguments() const {
+    return in_arguments_;
+  }
+  const std::vector<const AidlArgument*>& GetOutArguments() const {
+    return out_arguments_;
+  }
+
+ private:
+  bool oneway_;
+  std::string comments_;
+  std::unique_ptr<AidlType> type_;
+  std::string name_;
+  unsigned line_;
+  const std::vector<std::unique_ptr<AidlArgument>> arguments_;
+  std::vector<const AidlArgument*> in_arguments_;
+  std::vector<const AidlArgument*> out_arguments_;
+  bool has_id_;
+  int id_;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlMethod);
+};
+
+class AidlParcelable;
+class AidlInterface;
+class AidlDocument : public AidlNode {
+ public:
+  AidlDocument() = default;
+  explicit AidlDocument(AidlInterface* interface);
+  virtual ~AidlDocument() = default;
+
+  const AidlInterface* GetInterface() const { return interface_.get(); }
+  AidlInterface* ReleaseInterface() { return interface_.release(); }
+
+  const std::vector<std::unique_ptr<AidlParcelable>>& GetParcelables() const {
+    return parcelables_;
+  }
+
+  void AddParcelable(AidlParcelable* parcelable) {
+    parcelables_.push_back(std::unique_ptr<AidlParcelable>(parcelable));
+  }
+
+ private:
+  std::vector<std::unique_ptr<AidlParcelable>> parcelables_;
+  std::unique_ptr<AidlInterface> interface_;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlDocument);
+};
+
+class AidlQualifiedName : public AidlNode {
+ public:
+  AidlQualifiedName(std::string term, std::string comments);
+  virtual ~AidlQualifiedName() = default;
+
+  const std::vector<std::string>& GetTerms() const { return terms_; }
+  const std::string& GetComments() const { return comments_; }
+  std::string GetDotName() const { return android::base::Join(terms_, '.'); }
+
+  void AddTerm(const std::string& term);
+
+ private:
+  std::vector<std::string> terms_;
+  std::string comments_;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlQualifiedName);
+};
+
+class AidlParcelable : public AidlNode {
+ public:
+  AidlParcelable(AidlQualifiedName* name, unsigned line,
+                 const std::vector<std::string>& package,
+                 const std::string& cpp_header = "");
+  virtual ~AidlParcelable() = default;
+
+  std::string GetName() const { return name_->GetDotName(); }
+  unsigned GetLine() const { return line_; }
+  std::string GetPackage() const;
+  const std::vector<std::string>& GetSplitPackage() const { return package_; }
+  std::string GetCppHeader() const { return cpp_header_; }
+  std::string GetCanonicalName() const;
+
+ private:
+  std::unique_ptr<AidlQualifiedName> name_;
+  unsigned line_;
+  const std::vector<std::string> package_;
+  std::string cpp_header_;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlParcelable);
+};
+
+class AidlInterface : public AidlAnnotatable {
+ public:
+  AidlInterface(const std::string& name, unsigned line,
+                const std::string& comments, bool oneway_,
+                std::vector<std::unique_ptr<AidlMember>>* members,
+                const std::vector<std::string>& package);
+  virtual ~AidlInterface() = default;
+
+  const std::string& GetName() const { return name_; }
+  unsigned GetLine() const { return line_; }
+  const std::string& GetComments() const { return comments_; }
+  bool IsOneway() const { return oneway_; }
+  const std::vector<std::unique_ptr<AidlMethod>>& GetMethods() const
+      { return methods_; }
+  const std::vector<std::unique_ptr<AidlIntConstant>>& GetIntConstants() const
+      { return int_constants_; }
+  const std::vector<std::unique_ptr<AidlStringConstant>>&
+      GetStringConstants() const { return string_constants_; }
+  std::string GetPackage() const;
+  std::string GetCanonicalName() const;
+  const std::vector<std::string>& GetSplitPackage() const { return package_; }
+
+  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:
+  std::string name_;
+  std::string comments_;
+  unsigned line_;
+  bool oneway_;
+  std::vector<std::unique_ptr<AidlMethod>> methods_;
+  std::vector<std::unique_ptr<AidlIntConstant>> int_constants_;
+  std::vector<std::unique_ptr<AidlStringConstant>> string_constants_;
+  std::vector<std::string> package_;
+
+  const android::aidl::ValidatableType* language_type_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlInterface);
+};
+
+class AidlImport : public AidlNode {
+ public:
+  AidlImport(const std::string& from, const std::string& needed_class,
+             unsigned line);
+  virtual ~AidlImport() = default;
+
+  const std::string& GetFileFrom() const { return from_; }
+  const std::string& GetFilename() const { return filename_; }
+  const std::string& GetNeededClass() const { return needed_class_; }
+  unsigned GetLine() const { return line_; }
+
+  void SetFilename(const std::string& filename) { filename_ = filename; }
+
+ private:
+  std::string from_;
+  std::string filename_;
+  std::string needed_class_;
+  unsigned line_;
+
+  DISALLOW_COPY_AND_ASSIGN(AidlImport);
+};
+
+class Parser {
+ public:
+  explicit Parser(const android::aidl::IoDelegate& io_delegate);
+  ~Parser();
+
+  // Parse contents of file |filename|.
+  bool ParseFile(const std::string& filename);
+
+  void ReportError(const std::string& err, unsigned line);
+
+  bool FoundNoErrors() const { return error_ == 0; }
+  const std::string& FileName() const { return filename_; }
+  void* Scanner() const { return scanner_; }
+
+  void SetDocument(AidlDocument* doc) { document_.reset(doc); };
+
+  void AddImport(AidlQualifiedName* name, unsigned line);
+
+  std::vector<std::string> Package() const;
+  void SetPackage(AidlQualifiedName* name) { package_.reset(name); }
+
+  AidlDocument* GetDocument() const { return document_.get(); }
+  AidlDocument* ReleaseDocument() { return document_.release(); }
+  const std::vector<std::unique_ptr<AidlImport>>& GetImports() {
+    return imports_;
+  }
+
+  void ReleaseImports(std::vector<std::unique_ptr<AidlImport>>* ret) {
+      *ret = std::move(imports_);
+      imports_.clear();
+  }
+
+ private:
+  const android::aidl::IoDelegate& io_delegate_;
+  int error_ = 0;
+  std::string filename_;
+  std::unique_ptr<AidlQualifiedName> package_;
+  void* scanner_ = nullptr;
+  std::unique_ptr<AidlDocument> document_;
+  std::vector<std::unique_ptr<AidlImport>> imports_;
+  std::unique_ptr<std::string> raw_buffer_;
+  YY_BUFFER_STATE buffer_;
+
+  DISALLOW_COPY_AND_ASSIGN(Parser);
+};
+
+#endif // AIDL_AIDL_LANGUAGE_H_
diff --git a/aidl/aidl_language_l.ll b/aidl/aidl_language_l.ll
new file mode 100644
index 0000000..a56758b
--- /dev/null
+++ b/aidl/aidl_language_l.ll
@@ -0,0 +1,106 @@
+%{
+#include <string.h>
+#include <stdlib.h>
+
+#include "aidl_language.h"
+#include "aidl_language_y.h"
+
+#define YY_USER_ACTION yylloc->columns(yyleng);
+%}
+
+%option yylineno
+%option noyywrap
+%option reentrant
+%option bison-bridge
+%option bison-locations
+
+%x COPYING LONG_COMMENT
+
+identifier  [_a-zA-Z][_a-zA-Z0-9]*
+whitespace  ([ \t\r]+)
+intvalue    [-+]?(0|[1-9][0-9]*)
+hexvalue    0[x|X][0-9a-fA-F]+
+
+%%
+%{
+  /* This happens at every call to yylex (every time we receive one token) */
+  std::string extra_text;
+  yylloc->step();
+%}
+
+
+\%\%\{                { extra_text += "/**"; BEGIN(COPYING); }
+<COPYING>\}\%\%       { extra_text += "**/"; yylloc->step(); BEGIN(INITIAL); }
+<COPYING>.*           { extra_text += yytext; }
+<COPYING>\n+          { extra_text += yytext; yylloc->lines(yyleng); }
+
+\/\*                  { extra_text += yytext; BEGIN(LONG_COMMENT); }
+<LONG_COMMENT>\*+\/   { extra_text += yytext; yylloc->step(); BEGIN(INITIAL);  }
+<LONG_COMMENT>\*+     { extra_text += yytext; }
+<LONG_COMMENT>\n+     { extra_text += yytext; yylloc->lines(yyleng); }
+<LONG_COMMENT>[^*\n]+ { extra_text += yytext; }
+
+\"[^\"]*\"            { yylval->token = new AidlToken(yytext, extra_text);
+                        return yy::parser::token::C_STR; }
+
+\/\/.*\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 '>'; }
+
+    /* keywords */
+parcelable            { return yy::parser::token::PARCELABLE; }
+import                { return yy::parser::token::IMPORT; }
+package               { return yy::parser::token::PACKAGE; }
+int                   { return yy::parser::token::INT; }
+String                { return yy::parser::token::STRING; }
+in                    { return yy::parser::token::IN; }
+out                   { return yy::parser::token::OUT; }
+inout                 { return yy::parser::token::INOUT; }
+cpp_header            { return yy::parser::token::CPP_HEADER; }
+const                 { return yy::parser::token::CONST; }
+@nullable             { return yy::parser::token::ANNOTATION_NULLABLE; }
+@utf8                 { return yy::parser::token::ANNOTATION_UTF8; }
+@utf8InCpp            { return yy::parser::token::ANNOTATION_UTF8_CPP; }
+
+interface             { yylval->token = new AidlToken("interface", extra_text);
+                        return yy::parser::token::INTERFACE;
+                      }
+oneway                { yylval->token = new AidlToken("oneway", extra_text);
+                        return yy::parser::token::ONEWAY;
+                      }
+
+    /* scalars */
+{identifier}          { yylval->token = new AidlToken(yytext, extra_text);
+                        return yy::parser::token::IDENTIFIER;
+                      }
+{intvalue}            { yylval->integer = std::stoi(yytext);
+                        return yy::parser::token::INTVALUE; }
+{hexvalue}            { yylval->token = new AidlToken(yytext, extra_text);
+                        return yy::parser::token::HEXVALUE; }
+
+    /* syntax error! */
+.                     { printf("UNKNOWN(%s)", yytext);
+                        yylval->token = new AidlToken(yytext, extra_text);
+                        return yy::parser::token::IDENTIFIER;
+                      }
+
+%%
+
+// comment and whitespace handling
+// ================================================
diff --git a/aidl/aidl_language_y.yy b/aidl/aidl_language_y.yy
new file mode 100644
index 0000000..4ad6754
--- /dev/null
+++ b/aidl/aidl_language_y.yy
@@ -0,0 +1,321 @@
+%{
+#include "aidl_language.h"
+#include "aidl_language_y.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int yylex(yy::parser::semantic_type *, yy::parser::location_type *, void *);
+
+#define lex_scanner ps->Scanner()
+
+%}
+
+%parse-param { Parser* ps }
+%lex-param { void *lex_scanner }
+
+%pure-parser
+%skeleton "glr.cc"
+
+%union {
+    AidlToken* token;
+    int integer;
+    std::string *str;
+    AidlType::Annotation annotation;
+    AidlType::Annotation annotation_list;
+    AidlType* type;
+    AidlType* unannotated_type;
+    AidlArgument* arg;
+    AidlArgument::Direction direction;
+    std::vector<std::unique_ptr<AidlArgument>>* arg_list;
+    AidlMethod* method;
+    AidlMember* constant;
+    std::vector<std::unique_ptr<AidlMember>>* members;
+    AidlQualifiedName* qname;
+    AidlInterface* interface_obj;
+    AidlParcelable* parcelable;
+    AidlDocument* parcelable_list;
+}
+
+%token<token> IDENTIFIER INTERFACE ONEWAY C_STR HEXVALUE
+%token<integer> INTVALUE
+
+%token '(' ')' ',' '=' '[' ']' '<' '>' '.' '{' '}' ';'
+%token IN OUT INOUT PACKAGE IMPORT PARCELABLE CPP_HEADER CONST INT STRING
+%token ANNOTATION_NULLABLE ANNOTATION_UTF8 ANNOTATION_UTF8_CPP
+
+%type<parcelable_list> parcelable_decls
+%type<parcelable> parcelable_decl
+%type<members> members
+%type<interface_obj> interface_decl
+%type<method> method_decl
+%type<constant> constant_decl
+%type<annotation> annotation
+%type<annotation_list>annotation_list
+%type<type> type
+%type<unannotated_type> unannotated_type
+%type<arg_list> arg_list
+%type<arg> arg
+%type<direction> direction
+%type<str> generic_list
+%type<qname> qualified_name
+
+%type<token> identifier error
+%%
+document
+ : package imports parcelable_decls
+  { ps->SetDocument($3); }
+ | package imports interface_decl
+  { ps->SetDocument(new AidlDocument($3)); };
+
+/* A couple of tokens that are keywords elsewhere are identifiers when
+ * occurring in the identifier position. Therefore identifier is a
+ * non-terminal, which is either an IDENTIFIER token, or one of the
+ * aforementioned keyword tokens.
+ */
+identifier
+ : IDENTIFIER
+  { $$ = $1; }
+ | CPP_HEADER
+  { $$ = new AidlToken("cpp_header", ""); }
+ | INT
+  { $$ = new AidlToken("int", ""); }
+ | STRING
+  { $$ = new AidlToken("String", ""); }
+ ;
+
+package
+ : {}
+ | PACKAGE qualified_name ';'
+  { ps->SetPackage($2); };
+
+imports
+ : {}
+ | import imports {};
+
+import
+ : IMPORT qualified_name ';'
+  { ps->AddImport($2, @1.begin.line); };
+
+qualified_name
+ : identifier {
+    $$ = new AidlQualifiedName($1->GetText(), $1->GetComments());
+    delete $1;
+  }
+ | qualified_name '.' identifier
+  { $$ = $1;
+    $$->AddTerm($3->GetText());
+  };
+
+parcelable_decls
+ :
+  { $$ = new AidlDocument(); }
+ | parcelable_decls parcelable_decl {
+   $$ = $1;
+   $$->AddParcelable($2);
+  }
+ | parcelable_decls error {
+    fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n",
+            ps->FileName().c_str(),
+            @2.begin.line, $2->GetText().c_str());
+    $$ = $1;
+  };
+
+parcelable_decl
+ : PARCELABLE qualified_name ';' {
+    $$ = new AidlParcelable($2, @2.begin.line, ps->Package());
+  }
+ | PARCELABLE qualified_name CPP_HEADER C_STR ';' {
+    $$ = new AidlParcelable($2, @2.begin.line, ps->Package(), $4->GetText());
+  }
+ | PARCELABLE ';' {
+    fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n",
+            ps->FileName().c_str(), @1.begin.line);
+    $$ = NULL;
+  }
+ | PARCELABLE error ';' {
+    fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n",
+            ps->FileName().c_str(), @2.begin.line, $2->GetText().c_str());
+    $$ = NULL;
+  };
+
+interface_decl
+ : annotation_list INTERFACE identifier '{' members '}' {
+    $$ = new AidlInterface($3->GetText(), @2.begin.line, $2->GetComments(),
+                           false, $5, ps->Package());
+    $$->Annotate($1);
+    delete $2;
+    delete $3;
+  }
+ | annotation_list ONEWAY INTERFACE identifier '{' members '}' {
+    $$ = new AidlInterface($4->GetText(), @4.begin.line, $2->GetComments(),
+                           true, $6, ps->Package());
+    $$->Annotate($1);
+    delete $2;
+    delete $3;
+    delete $4;
+  }
+ | annotation_list INTERFACE error '{' members '}' {
+    fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected "
+                    "type name, saw \"%s\"\n",
+            ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str());
+    $$ = NULL;
+    delete $2;
+    delete $3;
+    delete $5;
+  }
+ | annotation_list INTERFACE error '}' {
+    fprintf(stderr, "%s:%d: syntax error in interface declaration.  Expected "
+                    "type name, saw \"%s\"\n",
+            ps->FileName().c_str(), @3.begin.line, $3->GetText().c_str());
+    $$ = NULL;
+    delete $2;
+    delete $3;
+  };
+
+members
+ :
+  { $$ = new std::vector<std::unique_ptr<AidlMember>>(); }
+ | members method_decl
+  { $1->push_back(std::unique_ptr<AidlMember>($2)); }
+ | members constant_decl
+  { $1->push_back(std::unique_ptr<AidlMember>($2)); }
+ | members error ';' {
+    fprintf(stderr, "%s:%d: syntax error before ';' "
+                    "(expected method or constant declaration)\n",
+            ps->FileName().c_str(), @3.begin.line);
+    $$ = $1;
+  };
+
+constant_decl
+ : CONST INT identifier '=' INTVALUE ';' {
+    $$ = new AidlIntConstant($3->GetText(), $5);
+    delete $3;
+   }
+ | CONST INT identifier '=' HEXVALUE ';' {
+    $$ = new AidlIntConstant($3->GetText(), $5->GetText(), @5.begin.line);
+    delete $3;
+   }
+ | CONST STRING identifier '=' C_STR ';' {
+    $$ = new AidlStringConstant($3->GetText(), $5->GetText(), @5.begin.line);
+    delete $3;
+    delete $5;
+   }
+ ;
+
+method_decl
+ : type identifier '(' arg_list ')' ';' {
+    $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line,
+                        $1->GetComments());
+    delete $2;
+  }
+ | ONEWAY type identifier '(' arg_list ')' ';' {
+    $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line,
+                        $1->GetComments());
+    delete $1;
+    delete $3;
+  }
+ | type identifier '(' arg_list ')' '=' INTVALUE ';' {
+    $$ = new AidlMethod(false, $1, $2->GetText(), $4, @2.begin.line,
+                        $1->GetComments(), $7);
+    delete $2;
+  }
+ | ONEWAY type identifier '(' arg_list ')' '=' INTVALUE ';' {
+    $$ = new AidlMethod(true, $2, $3->GetText(), $5, @3.begin.line,
+                        $1->GetComments(), $8);
+    delete $1;
+    delete $3;
+  };
+
+arg_list
+ :
+  { $$ = 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));
+  }
+ | error {
+    fprintf(stderr, "%s:%d: syntax error in parameter list\n",
+            ps->FileName().c_str(), @1.begin.line);
+    $$ = new std::vector<std::unique_ptr<AidlArgument>>();
+  };
+
+arg
+ : direction type identifier {
+    $$ = new AidlArgument($1, $2, $3->GetText(), @3.begin.line);
+    delete $3;
+  };
+ | type identifier {
+    $$ = new AidlArgument($1, $2->GetText(), @2.begin.line);
+    delete $2;
+  };
+
+unannotated_type
+ : qualified_name {
+    $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(), false);
+    delete $1;
+  }
+ | qualified_name '[' ']' {
+    $$ = new AidlType($1->GetDotName(), @1.begin.line, $1->GetComments(),
+                      true);
+    delete $1;
+  }
+ | qualified_name '<' generic_list '>' {
+    $$ = new AidlType($1->GetDotName() + "<" + *$3 + ">", @1.begin.line,
+                      $1->GetComments(), false);
+    delete $1;
+    delete $3;
+  };
+
+type
+ : annotation_list unannotated_type {
+    $$ = $2;
+    $2->Annotate($1);
+  };
+
+generic_list
+ : qualified_name {
+    $$ = new std::string($1->GetDotName());
+    delete $1;
+  }
+ | generic_list ',' qualified_name {
+    $$ = new std::string(*$1 + "," + $3->GetDotName());
+    delete $1;
+    delete $3;
+  };
+
+annotation_list
+ :
+  { $$ = AidlType::AnnotationNone; }
+ | annotation_list annotation
+  { $$ = static_cast<AidlType::Annotation>($1 | $2); };
+
+annotation
+ : ANNOTATION_NULLABLE
+  { $$ = AidlType::AnnotationNullable; }
+ | ANNOTATION_UTF8
+  { $$ = AidlType::AnnotationUtf8; }
+ | ANNOTATION_UTF8_CPP
+  { $$ = AidlType::AnnotationUtf8InCpp; };
+
+direction
+ : IN
+  { $$ = AidlArgument::IN_DIR; }
+ | OUT
+  { $$ = AidlArgument::OUT_DIR; }
+ | INOUT
+  { $$ = AidlArgument::INOUT_DIR; };
+
+%%
+
+#include <ctype.h>
+#include <stdio.h>
+
+void yy::parser::error(const yy::parser::location_type& l,
+                       const std::string& errstr) {
+  ps->ReportError(errstr, l.begin.line);
+}
diff --git a/aidl/aidl_unittest.cpp b/aidl/aidl_unittest.cpp
new file mode 100644
index 0000000..0d2ba53
--- /dev/null
+++ b/aidl/aidl_unittest.cpp
@@ -0,0 +1,399 @@
+/*
+ * 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 <set>
+#include <string>
+#include <vector>
+
+#include <android-base/stringprintf.h>
+#include <gtest/gtest.h>
+
+#include "aidl.h"
+#include "aidl_language.h"
+#include "tests/fake_io_delegate.h"
+#include "type_cpp.h"
+#include "type_java.h"
+#include "type_namespace.h"
+
+using android::aidl::test::FakeIoDelegate;
+using android::base::StringPrintf;
+using std::set;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+using android::aidl::internals::parse_preprocessed_file;
+
+namespace android {
+namespace aidl {
+namespace {
+
+const char kExpectedDepFileContents[] =
+R"(place/for/output/p/IFoo.java : \
+  p/IFoo.aidl
+
+p/IFoo.aidl :
+)";
+
+const char kExpectedParcelableDepFileContents[] =
+R"( : \
+  p/Foo.aidl
+
+p/Foo.aidl :
+)";
+
+}  // namespace
+
+class AidlTest : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    java_types_.Init();
+    cpp_types_.Init();
+  }
+
+  unique_ptr<AidlInterface> Parse(const string& path,
+                                  const string& contents,
+                                  TypeNamespace* types,
+                                  AidlError* error = nullptr) {
+    io_delegate_.SetFileContents(path, contents);
+    unique_ptr<AidlInterface> ret;
+    std::vector<std::unique_ptr<AidlImport>> imports;
+    AidlError actual_error = ::android::aidl::internals::load_and_validate_aidl(
+        preprocessed_files_,
+        import_paths_,
+        path,
+        io_delegate_,
+        types,
+        &ret,
+        &imports);
+    if (error != nullptr) {
+      *error = actual_error;
+    }
+    return ret;
+  }
+
+  FakeIoDelegate io_delegate_;
+  vector<string> preprocessed_files_;
+  vector<string> import_paths_;
+  java::JavaTypeNamespace java_types_;
+  cpp::TypeNamespace cpp_types_;
+};
+
+TEST_F(AidlTest, JavaAcceptsMissingPackage) {
+  EXPECT_NE(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &java_types_));
+}
+
+TEST_F(AidlTest, RejectsArraysOfBinders) {
+  import_paths_.push_back("");
+  io_delegate_.SetFileContents("bar/IBar.aidl",
+                               "package bar; interface IBar {}");
+  string path = "foo/IFoo.aidl";
+  string contents = "package foo;\n"
+                    "import bar.IBar;\n"
+                    "interface IFoo { void f(in IBar[] input); }";
+  EXPECT_EQ(nullptr, Parse(path, contents, &java_types_));
+  EXPECT_EQ(nullptr, Parse(path, contents, &cpp_types_));
+}
+
+TEST_F(AidlTest, CppRejectsMissingPackage) {
+  EXPECT_EQ(nullptr, Parse("IFoo.aidl", "interface IFoo { }", &cpp_types_));
+  EXPECT_NE(nullptr,
+            Parse("a/IFoo.aidl", "package a; interface IFoo { }", &cpp_types_));
+}
+
+TEST_F(AidlTest, RejectsOnewayOutParameters) {
+  string oneway_interface =
+      "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, &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, &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, &cpp_types_));
+  EXPECT_EQ(nullptr, Parse("a/IFoo.aidl", oneway_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" : ""),
+        &cpp_types_);
+    ASSERT_NE(nullptr, parse_result);
+    ASSERT_FALSE(parse_result->GetMethods().empty());
+    EXPECT_EQ(parse_result->GetMethods()[0]->GetType().IsNullable(),
+              is_nullable);
+  }
+}
+
+TEST_F(AidlTest, ParsesUtf8Annotations) {
+  for (auto is_utf8: {true, false}) {
+    auto parse_result = Parse(
+        "a/IFoo.aidl",
+        StringPrintf( "package a; interface IFoo {%s String f(); }",
+                     (is_utf8) ? "@utf8InCpp" : ""),
+        &cpp_types_);
+    ASSERT_NE(nullptr, parse_result);
+    ASSERT_FALSE(parse_result->GetMethods().empty());
+    EXPECT_EQ(parse_result->GetMethods()[0]->GetType().IsUtf8InCpp(),
+              is_utf8);
+  }
+}
+
+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, &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(java_types_.HasTypeByCanonicalName("a.Foo"));
+  EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_));
+  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(java_types_.HasTypeByCanonicalName("a.Foo"));
+  EXPECT_TRUE(parse_preprocessed_file(io_delegate_, "path", &java_types_));
+  EXPECT_TRUE(java_types_.HasTypeByCanonicalName("a.Foo"));
+  EXPECT_TRUE(java_types_.HasTypeByCanonicalName("b.IBar"));
+}
+
+TEST_F(AidlTest, PreferImportToPreprocessed) {
+  io_delegate_.SetFileContents("preprocessed", "interface another.IBar;");
+  io_delegate_.SetFileContents("one/IBar.aidl", "package one; "
+                                                "interface IBar {}");
+  preprocessed_files_.push_back("preprocessed");
+  import_paths_.push_back("");
+  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(java_types_.HasTypeByCanonicalName("one.IBar"));
+  EXPECT_TRUE(java_types_.HasTypeByCanonicalName("another.IBar"));
+  // But if we request just "IBar" we should get our imported one.
+  AidlType ambiguous_type("IBar", 0, "", false /* not an array */);
+  const java::Type* type = java_types_.Find(ambiguous_type);
+  ASSERT_TRUE(type);
+  EXPECT_EQ("one.IBar", type->CanonicalName());
+}
+
+TEST_F(AidlTest, WritePreprocessedFile) {
+  io_delegate_.SetFileContents("p/Outer.aidl",
+                               "package p; parcelable Outer.Inner;");
+  io_delegate_.SetFileContents("one/IBar.aidl", "package one; import p.Outer;"
+                                                "interface IBar {}");
+
+  JavaOptions options;
+  options.output_file_name_ = "preprocessed";
+  options.files_to_preprocess_.resize(2);
+  options.files_to_preprocess_[0] = "p/Outer.aidl";
+  options.files_to_preprocess_[1] = "one/IBar.aidl";
+  EXPECT_TRUE(::android::aidl::preprocess_aidl(options, io_delegate_));
+
+  string output;
+  EXPECT_TRUE(io_delegate_.GetWrittenContents("preprocessed", &output));
+  EXPECT_EQ("parcelable p.Outer.Inner;\ninterface one.IBar;\n", output);
+}
+
+TEST_F(AidlTest, RequireOuterClass) {
+  io_delegate_.SetFileContents("p/Outer.aidl",
+                               "package p; parcelable Outer.Inner;");
+  import_paths_.push_back("");
+  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);
+}
+
+TEST_F(AidlTest, ParseCompoundParcelableFromPreprocess) {
+  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); }",
+      &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
+  EXPECT_NE(nullptr, parse_result);
+}
+
+TEST_F(AidlTest, FailOnParcelable) {
+  JavaOptions options;
+  options.input_file_name_ = "p/IFoo.aidl";
+  io_delegate_.SetFileContents(options.input_file_name_,
+                               "package p; parcelable IFoo;");
+  // By default, we shouldn't fail on parcelable.
+  EXPECT_EQ(0, ::android::aidl::compile_aidl_to_java(options, io_delegate_));
+  options.fail_on_parcelable_ = true;
+  EXPECT_NE(0, ::android::aidl::compile_aidl_to_java(options, io_delegate_));
+}
+
+TEST_F(AidlTest, FailOnDuplicateConstantNames) {
+  AidlError reported_error;
+  EXPECT_EQ(nullptr,
+            Parse("p/IFoo.aidl",
+                   R"(package p;
+                      interface IFoo {
+                        const String DUPLICATED = "d";
+                        const int DUPLICATED = 1;
+                      }
+                   )",
+                   &cpp_types_,
+                   &reported_error));
+  EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
+}
+
+TEST_F(AidlTest, FailOnMalformedConstHexValue) {
+  AidlError reported_error;
+  EXPECT_EQ(nullptr,
+            Parse("p/IFoo.aidl",
+                   R"(package p;
+                      interface IFoo {
+                        const int BAD_HEX_VALUE = 0xffffffffffffffffff;
+                      }
+                   )",
+                   &cpp_types_,
+                   &reported_error));
+  EXPECT_EQ(AidlError::BAD_CONSTANTS, reported_error);
+}
+
+TEST_F(AidlTest, ParsePositiveConstHexValue) {
+  AidlError reported_error;
+  auto cpp_parse_result =
+    Parse("p/IFoo.aidl",
+           R"(package p;
+              interface IFoo {
+                const int POSITIVE_HEX_VALUE = 0xf5;
+              }
+           )",
+           &cpp_types_,
+           &reported_error);
+  EXPECT_NE(nullptr, cpp_parse_result);
+  const auto& cpp_int_constants = cpp_parse_result->GetIntConstants();
+  EXPECT_EQ((size_t)1, cpp_int_constants.size());
+  EXPECT_EQ("POSITIVE_HEX_VALUE", cpp_int_constants[0]->GetName());
+  EXPECT_EQ(245, cpp_int_constants[0]->GetValue());
+}
+
+TEST_F(AidlTest, ParseNegativeConstHexValue) {
+  AidlError reported_error;
+  auto cpp_parse_result =
+    Parse("p/IFoo.aidl",
+           R"(package p;
+              interface IFoo {
+                const int NEGATIVE_HEX_VALUE = 0xffffffff;
+              }
+           )",
+           &cpp_types_,
+           &reported_error);
+  EXPECT_NE(nullptr, cpp_parse_result);
+  const auto& cpp_int_constants = cpp_parse_result->GetIntConstants();
+  EXPECT_EQ((size_t)1, cpp_int_constants.size());
+  EXPECT_EQ("NEGATIVE_HEX_VALUE", cpp_int_constants[0]->GetName());
+  EXPECT_EQ(-1, cpp_int_constants[0]->GetValue());
+}
+
+TEST_F(AidlTest, UnderstandsNativeParcelables) {
+  io_delegate_.SetFileContents(
+      "p/Bar.aidl",
+      "package p; parcelable Bar cpp_header \"baz/header\";");
+  import_paths_.push_back("");
+  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, &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) {
+  // While the in tree build system always gives us an output file name,
+  // other android tools take advantage of our ability to infer the intended
+  // file name.  This test makes sure we handle this correctly.
+  JavaOptions options;
+  options.input_file_name_ = "p/IFoo.aidl";
+  options.output_base_folder_ = "place/for/output";
+  options.dep_file_name_ = "dep/file/path";
+  io_delegate_.SetFileContents(options.input_file_name_,
+                               "package p; interface IFoo {}");
+  EXPECT_EQ(0, ::android::aidl::compile_aidl_to_java(options, io_delegate_));
+  string actual_dep_file_contents;
+  EXPECT_TRUE(io_delegate_.GetWrittenContents(options.dep_file_name_,
+                                              &actual_dep_file_contents));
+  EXPECT_EQ(actual_dep_file_contents, kExpectedDepFileContents);
+}
+
+TEST_F(AidlTest, WritesTrivialDependencyFileForParcelable) {
+  // The SDK uses aidl to decide whether a .aidl file is a parcelable.  It does
+  // this by calling aidl with every .aidl file it finds, then parsing the
+  // generated dependency files.  Those that reference .java output files are
+  // for interfaces and those that do not are parcelables.  However, for both
+  // parcelables and interfaces, we *must* generate a non-empty dependency file.
+  JavaOptions options;
+  options.input_file_name_ = "p/Foo.aidl";
+  options.output_base_folder_ = "place/for/output";
+  options.dep_file_name_ = "dep/file/path";
+  io_delegate_.SetFileContents(options.input_file_name_,
+                               "package p; parcelable Foo;");
+  EXPECT_EQ(0, ::android::aidl::compile_aidl_to_java(options, io_delegate_));
+  string actual_dep_file_contents;
+  EXPECT_TRUE(io_delegate_.GetWrittenContents(options.dep_file_name_,
+                                              &actual_dep_file_contents));
+  EXPECT_EQ(actual_dep_file_contents, kExpectedParcelableDepFileContents);
+}
+
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/ast_cpp.cpp b/aidl/ast_cpp.cpp
new file mode 100644
index 0000000..783b0f3
--- /dev/null
+++ b/aidl/ast_cpp.cpp
@@ -0,0 +1,455 @@
+/*
+ * 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 "ast_cpp.h"
+
+#include <algorithm>
+
+#include "code_writer.h"
+#include "logging.h"
+
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+ClassDecl::ClassDecl(const std::string& name, const std::string& parent)
+    : name_(name),
+      parent_(parent) {}
+
+ClassDecl::ClassDecl(const std::string& name, const std::string& parent,
+                     std::vector<unique_ptr<Declaration>> public_members,
+                     std::vector<unique_ptr<Declaration>> private_members)
+    : name_(name),
+      parent_(parent),
+      public_members_(std::move(public_members)),
+      private_members_(std::move(private_members)) {}
+
+void ClassDecl::Write(CodeWriter* to) const {
+  to->Write("class %s ", name_.c_str());
+
+  if (parent_.length() > 0)
+      to->Write(": public %s ", parent_.c_str());
+
+  to->Write("{\n");
+
+  if (!public_members_.empty())
+      to->Write("public:\n");
+
+  for (const auto& dec : public_members_)
+    dec->Write(to);
+
+  if (!private_members_.empty())
+      to->Write("private:\n");
+
+  for (const auto& dec : private_members_)
+    dec->Write(to);
+
+  to->Write("};  // class %s\n", name_.c_str());
+}
+
+void ClassDecl::AddPublic(std::unique_ptr<Declaration> member) {
+  public_members_.push_back(std::move(member));
+}
+
+void ClassDecl::AddPrivate(std::unique_ptr<Declaration> member) {
+  private_members_.push_back(std::move(member));
+}
+
+Enum::EnumField::EnumField(const string& k, const string& v)
+    : key(k),
+      value(v) {}
+
+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 {
+  if (underlying_type_.empty()) {
+    to->Write("enum %s {\n", enum_name_.c_str());
+  } else {
+    to->Write("enum %s : %s {\n", enum_name_.c_str(), underlying_type_.c_str());
+  }
+  for (const auto& field : fields_) {
+    if (field.value.empty()) {
+      to->Write("  %s,\n", field.key.c_str());
+    } else {
+      to->Write("  %s = %s,\n", field.key.c_str(), field.value.c_str());
+    }
+  }
+  to->Write("};\n");
+}
+
+void Enum::AddValue(const string& key, const string& value) {
+  fields_.emplace_back(key, value);
+}
+
+ArgList::ArgList(const std::string& single_argument)
+    : ArgList(vector<string>{single_argument}) {}
+
+ArgList::ArgList(const std::vector<std::string>& arg_list) {
+  for (const auto& s : arg_list) {
+    arguments_.emplace_back(new LiteralExpression(s));
+  }
+}
+
+ArgList::ArgList(std::vector<std::unique_ptr<AstNode>> arg_list)
+    : arguments_(std::move(arg_list)) {}
+
+ArgList::ArgList(ArgList&& arg_list)
+    : arguments_(std::move(arg_list.arguments_)) {}
+
+void ArgList::Write(CodeWriter* to) const {
+  to->Write("(");
+  bool is_first = true;
+  for (const auto& s : arguments_) {
+    if (!is_first) { to->Write(", "); }
+    is_first = false;
+    s->Write(to);
+  }
+  to->Write(")");
+}
+
+ConstructorDecl::ConstructorDecl(
+    const std::string& name,
+    ArgList&& arg_list)
+    : ConstructorDecl(name, std::move(arg_list), 0u) {}
+
+ConstructorDecl::ConstructorDecl(
+    const std::string& name,
+    ArgList&& arg_list,
+    uint32_t modifiers)
+    : name_(name),
+      arguments_(std::move(arg_list)),
+      modifiers_(modifiers) {}
+
+void ConstructorDecl::Write(CodeWriter* to) const {
+  if (modifiers_ & Modifiers::IS_VIRTUAL)
+    to->Write("virtual ");
+
+  if (modifiers_ & Modifiers::IS_EXPLICIT)
+    to->Write("explicit ");
+
+  to->Write("%s", name_.c_str());
+
+  arguments_.Write(to);
+
+  if (modifiers_ & Modifiers::IS_DEFAULT)
+    to->Write(" = default");
+
+  to->Write(";\n");
+}
+
+MacroDecl::MacroDecl(const std::string& name, ArgList&& arg_list)
+    : name_(name),
+      arguments_(std::move(arg_list)) {}
+
+void MacroDecl::Write(CodeWriter* to) const {
+  to->Write("%s", name_.c_str());
+  arguments_.Write(to);
+  to->Write("\n");
+}
+
+MethodDecl::MethodDecl(const std::string& return_type,
+                       const std::string& name,
+                       ArgList&& arg_list)
+    : MethodDecl(return_type, name, std::move(arg_list), 0u) {}
+
+MethodDecl::MethodDecl(const std::string& return_type,
+                       const std::string& name,
+                       ArgList&& arg_list,
+                       uint32_t modifiers)
+    : return_type_(return_type),
+      name_(name),
+      arguments_(std::move(arg_list)),
+      is_const_(modifiers & IS_CONST),
+      is_virtual_(modifiers & IS_VIRTUAL),
+      is_override_(modifiers & IS_OVERRIDE),
+      is_pure_virtual_(modifiers & IS_PURE_VIRTUAL),
+      is_static_(modifiers & IS_STATIC) {}
+
+void MethodDecl::Write(CodeWriter* to) const {
+  if (is_virtual_)
+    to->Write("virtual ");
+
+  if (is_static_)
+    to->Write("static ");
+
+  to->Write("%s %s", return_type_.c_str(), name_.c_str());
+
+  arguments_.Write(to);
+
+  if (is_const_)
+    to->Write(" const");
+
+  if (is_override_)
+    to->Write(" override");
+
+  if (is_pure_virtual_)
+    to->Write(" = 0");
+
+  to->Write(";\n");
+}
+
+void StatementBlock::AddStatement(unique_ptr<AstNode> statement) {
+  statements_.push_back(std::move(statement));
+}
+
+void StatementBlock::AddStatement(AstNode* statement) {
+  statements_.emplace_back(statement);
+}
+
+void StatementBlock::AddLiteral(const std::string& expression_str,
+                                bool add_semicolon) {
+  if (add_semicolon) {
+    statements_.push_back(unique_ptr<AstNode>(new Statement(expression_str)));
+  } else {
+    statements_.push_back(unique_ptr<AstNode>(
+        new LiteralExpression(expression_str)));
+  }
+}
+
+void StatementBlock::Write(CodeWriter* to) const {
+  to->Write("{\n");
+  for (const auto& statement : statements_) {
+    statement->Write(to);
+  }
+  to->Write("}\n");
+}
+
+ConstructorImpl::ConstructorImpl(const string& class_name,
+                                 ArgList&& arg_list,
+                                 const vector<string>& initializer_list)
+      : class_name_(class_name),
+        arguments_(std::move(arg_list)),
+        initializer_list_(initializer_list) {}
+
+void ConstructorImpl::Write(CodeWriter* to) const {
+  to->Write("%s::%s", class_name_.c_str(), class_name_.c_str());
+  arguments_.Write(to);
+  to->Write("\n");
+
+  bool is_first = true;
+  for (const string& i : initializer_list_) {
+    if (is_first) {
+      to->Write("    : %s", i.c_str());
+    } else {
+      to->Write(",\n      %s", i.c_str());
+    }
+    is_first = false;
+  }
+
+  body_.Write(to);
+}
+
+MethodImpl::MethodImpl(const string& return_type,
+                       const string& class_name,
+                       const string& method_name,
+                       ArgList&& arg_list,
+                       bool is_const_method)
+    : return_type_(return_type),
+      method_name_(method_name),
+      arguments_(std::move(arg_list)),
+      is_const_method_(is_const_method) {
+  if (!class_name.empty()) {
+    method_name_ = class_name + "::" + method_name;
+  }
+}
+
+StatementBlock* MethodImpl::GetStatementBlock() {
+  return &statements_;
+}
+
+void MethodImpl::Write(CodeWriter* to) const {
+  to->Write("%s %s", return_type_.c_str(), method_name_.c_str());
+  arguments_.Write(to);
+  to->Write("%s ", (is_const_method_) ? " const" : "");
+  statements_.Write(to);
+}
+
+SwitchStatement::SwitchStatement(const std::string& expression)
+    : switch_expression_(expression) {}
+
+StatementBlock* SwitchStatement::AddCase(const string& value_expression) {
+  auto it = std::find(case_values_.begin(), case_values_.end(), value_expression);
+  if (it != case_values_.end()) {
+    LOG(ERROR) << "internal error: duplicate switch case labels";
+    return nullptr;
+  }
+  StatementBlock* ret = new StatementBlock();
+  case_values_.push_back(value_expression);
+  case_logic_.push_back(unique_ptr<StatementBlock>{ret});
+  return ret;
+}
+
+void SwitchStatement::Write(CodeWriter* to) const {
+  to->Write("switch (%s) {\n", switch_expression_.c_str());
+  for (size_t i = 0; i < case_values_.size(); ++i) {
+    const string& case_value = case_values_[i];
+    const unique_ptr<StatementBlock>& statements = case_logic_[i];
+    if (case_value.empty()) {
+      to->Write("default:\n");
+    } else {
+      to->Write("case %s:\n", case_value.c_str());
+    }
+    statements->Write(to);
+    to->Write("break;\n");
+  }
+  to->Write("}\n");
+}
+
+
+Assignment::Assignment(const std::string& left, const std::string& right)
+    : Assignment(left, new LiteralExpression{right}) {}
+
+Assignment::Assignment(const std::string& left, AstNode* right)
+    : lhs_(left),
+      rhs_(right) {}
+
+void Assignment::Write(CodeWriter* to) const {
+  to->Write("%s = ", lhs_.c_str());
+  rhs_->Write(to);
+  to->Write(";\n");
+}
+
+MethodCall::MethodCall(const std::string& method_name,
+                       const std::string& single_argument)
+    : MethodCall(method_name, ArgList{single_argument}) {}
+
+MethodCall::MethodCall(const std::string& method_name,
+                       ArgList&& arg_list)
+    : method_name_(method_name),
+      arguments_{std::move(arg_list)} {}
+
+void MethodCall::Write(CodeWriter* to) const {
+  to->Write("%s", method_name_.c_str());
+  arguments_.Write(to);
+}
+
+IfStatement::IfStatement(AstNode* expression, bool invert_expression)
+    : expression_(expression),
+      invert_expression_(invert_expression) {}
+
+void IfStatement::Write(CodeWriter* to) const {
+  to->Write("if (%s", (invert_expression_) ? "!(" : "");
+  expression_->Write(to);
+  to->Write(")%s ", (invert_expression_) ? ")" : "");
+  on_true_.Write(to);
+
+  if (!on_false_.Empty()) {
+    to->Write("else ");
+    on_false_.Write(to);
+  }
+}
+
+Statement::Statement(unique_ptr<AstNode> expression)
+    : expression_(std::move(expression)) {}
+
+Statement::Statement(AstNode* expression) : expression_(expression) {}
+
+Statement::Statement(const string& expression)
+    : expression_(new LiteralExpression(expression)) {}
+
+void Statement::Write(CodeWriter* to) const {
+  expression_->Write(to);
+  to->Write(";\n");
+}
+
+Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs)
+    : left_(lhs),
+      right_(rhs),
+      operator_(comparison) {}
+
+void Comparison::Write(CodeWriter* to) const {
+  to->Write("((");
+  left_->Write(to);
+  to->Write(") %s (", operator_.c_str());
+  right_->Write(to);
+  to->Write("))");
+}
+
+LiteralExpression::LiteralExpression(const std::string& expression)
+    : expression_(expression) {}
+
+void LiteralExpression::Write(CodeWriter* to) const {
+  to->Write("%s", expression_.c_str());
+}
+
+CppNamespace::CppNamespace(const std::string& name,
+                           std::vector<unique_ptr<Declaration>> declarations)
+    : declarations_(std::move(declarations)),
+      name_(name) {}
+
+CppNamespace::CppNamespace(const std::string& name,
+                           unique_ptr<Declaration> declaration)
+    : name_(name) {
+  declarations_.push_back(std::move(declaration));
+}
+CppNamespace::CppNamespace(const std::string& name)
+    : name_(name) {}
+
+void CppNamespace::Write(CodeWriter* to) const {
+  to->Write("namespace %s {\n\n", name_.c_str());
+
+  for (const auto& dec : declarations_) {
+    dec->Write(to);
+    to->Write("\n");
+  }
+
+  to->Write("}  // namespace %s\n", name_.c_str());
+}
+
+Document::Document(const std::vector<std::string>& include_list,
+                   unique_ptr<CppNamespace> a_namespace)
+    : include_list_(include_list),
+      namespace_(std::move(a_namespace)) {}
+
+void Document::Write(CodeWriter* to) const {
+  for (const auto& include : include_list_) {
+    to->Write("#include <%s>\n", include.c_str());
+  }
+  to->Write("\n");
+
+  namespace_->Write(to);
+}
+
+CppHeader::CppHeader(const std::string& include_guard,
+                     const std::vector<std::string>& include_list,
+                     unique_ptr<CppNamespace> a_namespace)
+    : Document(include_list, std::move(a_namespace)),
+      include_guard_(include_guard) {}
+
+void CppHeader::Write(CodeWriter* to) const {
+  to->Write("#ifndef %s\n", include_guard_.c_str());
+  to->Write("#define %s\n\n", include_guard_.c_str());
+
+  Document::Write(to);
+  to->Write("\n");
+
+  to->Write("#endif  // %s\n", include_guard_.c_str());
+}
+
+CppSource::CppSource(const std::vector<std::string>& include_list,
+                     unique_ptr<CppNamespace> a_namespace)
+    : Document(include_list, std::move(a_namespace)) {}
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/ast_cpp.h b/aidl/ast_cpp.h
new file mode 100644
index 0000000..bb251ec
--- /dev/null
+++ b/aidl/ast_cpp.h
@@ -0,0 +1,420 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_AST_CPP_H_
+#define AIDL_AST_CPP_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <android-base/macros.h>
+
+namespace android {
+namespace aidl {
+class CodeWriter;
+}  // namespace aidl
+}  // namespace android
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+class AstNode {
+ public:
+  AstNode() = default;
+  virtual ~AstNode() = default;
+  virtual void Write(CodeWriter* to) const = 0;
+};  // class AstNode
+
+class Declaration : public AstNode {
+ public:
+  Declaration() = default;
+  virtual ~Declaration() = default;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Declaration);
+};  // class Declaration
+
+class ClassDecl : public Declaration {
+ public:
+  ClassDecl(const std::string& name,
+            const std::string& parent);
+  ClassDecl(const std::string& name,
+            const std::string& parent,
+            std::vector<std::unique_ptr<Declaration>> public_members,
+            std::vector<std::unique_ptr<Declaration>> private_members);
+  virtual ~ClassDecl() = default;
+
+  void Write(CodeWriter* to) const override;
+
+  void AddPublic(std::unique_ptr<Declaration> member);
+  void AddPrivate(std::unique_ptr<Declaration> member);
+
+ private:
+  std::string name_;
+  std::string parent_;
+  std::vector<std::unique_ptr<Declaration>> public_members_;
+  std::vector<std::unique_ptr<Declaration>> private_members_;
+
+  DISALLOW_COPY_AND_ASSIGN(ClassDecl);
+};  // class ClassDecl
+
+class Enum : public Declaration {
+ public:
+  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(); }
+  void Write(CodeWriter* to) const override;
+
+  void AddValue(const std::string& key, const std::string& value);
+
+ private:
+  struct EnumField {
+    EnumField(const std::string& k, const std::string& v);
+    const std::string key;
+    const std::string value;
+  };
+
+  std::string enum_name_;
+  std::string underlying_type_;
+  std::vector<EnumField> fields_;
+
+  DISALLOW_COPY_AND_ASSIGN(Enum);
+};  // class Enum
+
+class ArgList : public AstNode {
+ public:
+  ArgList() = default;
+  explicit ArgList(const std::string& single_argument);
+  explicit ArgList(const std::vector<std::string>& arg_list);
+  explicit ArgList(std::vector<std::unique_ptr<AstNode>> arg_list);
+  ArgList(ArgList&& arg_list);
+  virtual ~ArgList() = default;
+
+  void Write(CodeWriter* to) const override;
+
+ private:
+  std::vector<std::unique_ptr<AstNode>> arguments_;
+
+  DISALLOW_COPY_AND_ASSIGN(ArgList);
+};  // class ArgList
+
+class ConstructorDecl : public Declaration {
+ public:
+  enum Modifiers {
+    IS_VIRTUAL = 1 << 0,
+    IS_DEFAULT = 1 << 1,
+    IS_EXPLICIT = 1 << 2,
+  };
+
+  ConstructorDecl(const std::string& name,
+                  ArgList&& arg_list);
+  ConstructorDecl(const std::string& name,
+                  ArgList&& arg_list,
+                  uint32_t modifiers);
+
+  virtual ~ConstructorDecl() = default;
+
+  void Write(CodeWriter* to) const override;
+
+ private:
+  const std::string name_;
+  const ArgList arguments_;
+  const uint32_t modifiers_;
+
+  DISALLOW_COPY_AND_ASSIGN(ConstructorDecl);
+};  // class ConstructorDecl
+
+class MacroDecl : public Declaration {
+ public:
+  MacroDecl(const std::string& name, ArgList&& arg_list);
+  virtual ~MacroDecl() = default;
+
+  void Write(CodeWriter* to) const override;
+
+ private:
+  const std::string name_;
+  const ArgList arguments_;
+
+  DISALLOW_COPY_AND_ASSIGN(MacroDecl);
+};  // class MacroDecl
+
+class MethodDecl : public Declaration {
+ public:
+  enum Modifiers {
+    IS_CONST = 1 << 0,
+    IS_VIRTUAL = 1 << 1,
+    IS_OVERRIDE = 1 << 2,
+    IS_PURE_VIRTUAL = 1 << 3,
+    IS_STATIC = 1 << 4,
+  };
+
+  MethodDecl(const std::string& return_type,
+             const std::string& name,
+             ArgList&& arg_list);
+  MethodDecl(const std::string& return_type,
+             const std::string& name,
+             ArgList&& arg_list,
+             uint32_t modifiers);
+  virtual ~MethodDecl() = default;
+
+  void Write(CodeWriter* to) const override;
+
+ private:
+  const std::string return_type_;
+  const std::string name_;
+  const ArgList arguments_;
+  bool is_const_ = false;
+  bool is_virtual_ = false;
+  bool is_override_ = false;
+  bool is_pure_virtual_ = false;
+  bool is_static_ = true;
+
+  DISALLOW_COPY_AND_ASSIGN(MethodDecl);
+};  // class MethodDecl
+
+class StatementBlock : public Declaration {
+ public:
+  StatementBlock() = default;
+  virtual ~StatementBlock() = default;
+
+  void AddStatement(std::unique_ptr<AstNode> statement);
+  void AddStatement(AstNode* statement);  // Takes ownership
+  void AddLiteral(const std::string& expression, bool add_semicolon = true);
+  bool Empty() const { return statements_.empty(); }
+
+  void Write(CodeWriter* to) const override;
+
+ private:
+  std::vector<std::unique_ptr<AstNode>> statements_;
+
+  DISALLOW_COPY_AND_ASSIGN(StatementBlock);
+};  // class StatementBlock
+
+class ConstructorImpl : public Declaration {
+ public:
+  ConstructorImpl(const std::string& class_name,
+                  ArgList&& arg_list,
+                  const std::vector<std::string>& initializer_list);
+  virtual ~ConstructorImpl() = default;
+
+  void Write(CodeWriter* to) const override;
+
+ private:
+  std::string class_name_;
+  ArgList arguments_;
+  std::vector<std::string> initializer_list_;
+  StatementBlock body_;
+
+  DISALLOW_COPY_AND_ASSIGN(ConstructorImpl);
+};  // class ConstructorImpl
+
+class MethodImpl : public Declaration {
+ public:
+  // Passing an empty class name causes the method to be declared as a normal
+  // function (ie. no ClassName:: qualifier).
+  MethodImpl(const std::string& return_type,
+             const std::string& class_name,
+             const std::string& method_name,
+             ArgList&& arg_list,
+             bool is_const_method = false);
+  virtual ~MethodImpl() = default;
+
+  // MethodImpl retains ownership of the statement block.
+  StatementBlock* GetStatementBlock();
+
+  void Write(CodeWriter* to) const override;
+
+ private:
+  std::string return_type_;
+  std::string method_name_;
+  const ArgList arguments_;
+  StatementBlock statements_;
+  bool is_const_method_ = false;
+
+  DISALLOW_COPY_AND_ASSIGN(MethodImpl);
+};  // class MethodImpl
+
+class SwitchStatement : public AstNode {
+ public:
+  explicit SwitchStatement(const std::string& expression);
+  virtual ~SwitchStatement() = default;
+
+  // Add a case statement and return a pointer code block corresponding
+  // to the case.  The switch statement will add a break statement
+  // after the code block by default to prevent accidental fall-through.
+  // Returns nullptr on duplicate value expressions (by strcmp, not value
+  // equivalence).
+  StatementBlock* AddCase(const std::string& value_expression);
+  void Write(CodeWriter* to) const override;
+
+ private:
+  const std::string switch_expression_;
+  std::vector<std::string> case_values_;
+  std::vector<std::unique_ptr<StatementBlock>> case_logic_;
+
+  DISALLOW_COPY_AND_ASSIGN(SwitchStatement);
+};  // class SwitchStatement
+
+class Assignment : public AstNode {
+ public:
+  Assignment(const std::string& left, const std::string& right);
+  Assignment(const std::string& left, AstNode* right);
+  ~Assignment() = default;
+  void Write(CodeWriter* to) const override;
+
+ private:
+  const std::string lhs_;
+  std::unique_ptr<AstNode> rhs_;
+
+  DISALLOW_COPY_AND_ASSIGN(Assignment);
+};  // class Assignment
+
+class MethodCall : public AstNode {
+ public:
+  MethodCall(const std::string& method_name,
+             const std::string& single_argument);
+  MethodCall(const std::string& method_name, ArgList&& arg_list);
+  ~MethodCall() = default;
+  void Write(CodeWriter* to) const override;
+
+ private:
+  const std::string method_name_;
+  const ArgList arguments_;
+
+  DISALLOW_COPY_AND_ASSIGN(MethodCall);
+};  // class MethodCall
+
+class IfStatement : public AstNode {
+ public:
+  explicit IfStatement(AstNode* expression,
+              bool invert_expression = false);
+  virtual ~IfStatement() = default;
+  StatementBlock* OnTrue() { return &on_true_; }
+  StatementBlock* OnFalse() { return &on_false_; }
+  void Write(CodeWriter* to) const override;
+
+ private:
+  std::unique_ptr<AstNode> expression_;
+  bool invert_expression_ = false;
+  StatementBlock on_true_;
+  StatementBlock on_false_;
+
+  DISALLOW_COPY_AND_ASSIGN(IfStatement);
+};  // class IfStatement
+
+class Statement : public AstNode {
+ public:
+  explicit Statement(std::unique_ptr<AstNode> expression);
+  explicit Statement(AstNode* expression);  // Takes possession.
+  explicit Statement(const std::string& expression);
+  ~Statement() = default;
+  void Write(CodeWriter* to) const override;
+
+ private:
+  std::unique_ptr<AstNode> expression_;
+
+  DISALLOW_COPY_AND_ASSIGN(Statement);
+};  // class Statement
+
+class Comparison : public AstNode {
+ public:
+  Comparison(AstNode* lhs, const std::string& comparison, AstNode* rhs);
+  ~Comparison() = default;
+  void Write(CodeWriter* to) const override;
+
+ private:
+  std::unique_ptr<AstNode> left_;
+  std::unique_ptr<AstNode> right_;
+  const std::string operator_;
+
+  DISALLOW_COPY_AND_ASSIGN(Comparison);
+};  // class Comparison
+
+class LiteralExpression : public AstNode {
+ public:
+  explicit LiteralExpression(const std::string& expression);
+  ~LiteralExpression() = default;
+  void Write(CodeWriter* to) const override;
+
+ private:
+  const std::string expression_;
+
+  DISALLOW_COPY_AND_ASSIGN(LiteralExpression);
+};  // class LiteralExpression
+
+class CppNamespace : public Declaration {
+ public:
+  CppNamespace(const std::string& name,
+               std::vector<std::unique_ptr<Declaration>> declarations);
+  CppNamespace(const std::string& name,
+               std::unique_ptr<Declaration> declaration);
+  explicit CppNamespace(const std::string& name);
+  virtual ~CppNamespace() = default;
+
+  void Write(CodeWriter* to) const override;
+
+ private:
+  std::vector<std::unique_ptr<Declaration>> declarations_;
+  std::string name_;
+
+  DISALLOW_COPY_AND_ASSIGN(CppNamespace);
+};  // class CppNamespace
+
+class Document : public AstNode {
+ public:
+  Document(const std::vector<std::string>& include_list,
+           std::unique_ptr<CppNamespace> a_namespace);
+
+  void Write(CodeWriter* to) const override;
+
+ private:
+  std::vector<std::string> include_list_;
+  std::unique_ptr<CppNamespace> namespace_;
+
+  DISALLOW_COPY_AND_ASSIGN(Document);
+};  // class Document
+
+class CppHeader final : public Document {
+ public:
+  CppHeader(const std::string& include_guard,
+            const std::vector<std::string>& include_list,
+            std::unique_ptr<CppNamespace> a_namespace);
+  void Write(CodeWriter* to) const override;
+
+ private:
+  const std::string include_guard_;
+
+  DISALLOW_COPY_AND_ASSIGN(CppHeader);
+};  // class CppHeader
+
+class CppSource final : public Document {
+ public:
+  CppSource(const std::vector<std::string>& include_list,
+            std::unique_ptr<CppNamespace> a_namespace);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CppSource);
+};  // class CppSource
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
+
+#endif // AIDL_AST_CPP_H_
diff --git a/aidl/ast_cpp_unittest.cpp b/aidl/ast_cpp_unittest.cpp
new file mode 100644
index 0000000..aee23b7
--- /dev/null
+++ b/aidl/ast_cpp_unittest.cpp
@@ -0,0 +1,246 @@
+/*
+ * 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 <string>
+
+#include <gtest/gtest.h>
+
+#include "ast_cpp.h"
+#include "code_writer.h"
+
+using std::string;
+using std::vector;
+using std::unique_ptr;
+
+namespace android {
+namespace aidl {
+namespace cpp {
+namespace {
+
+const char kExpectedHeaderOutput[] =
+R"(#ifndef HEADER_INCLUDE_GUARD_H_
+#define HEADER_INCLUDE_GUARD_H_
+
+#include <string>
+#include <memory>
+
+namespace android {
+
+namespace test {
+
+class TestClass {
+public:
+void NormalMethod(int normalarg, float normal2);
+virtual void SubMethod(int subarg) const;
+};  // class TestClass
+
+class TestSubClass : public TestClass {
+public:
+virtual void SubMethod(int subarg) const;
+};  // class TestSubClass
+
+}  // namespace test
+
+}  // namespace android
+
+#endif  // HEADER_INCLUDE_GUARD_H_
+)";
+
+const char kExpectedEnumOutput[] =
+R"(enum Foo {
+  BAR = 42,
+  BAZ,
+};
+)";
+
+const char kExpectedSwitchOutput[] =
+R"(switch (var) {
+case 2:
+{
+baz;
+}
+break;
+case 1:
+{
+foo;
+bar;
+}
+break;
+}
+)";
+
+const char kExpectedMethodImplOutput[] =
+R"(return_type ClassName::MethodName(arg 1, arg 2, arg 3) const {
+foo;
+bar;
+}
+)";
+}  // namespace
+
+class AstCppTests : public ::testing::Test {
+ protected:
+  void CompareGeneratedCode(const AstNode& node,
+                            const string& expected_output) {
+    string actual_output;
+    CodeWriterPtr writer = GetStringWriter(&actual_output);
+    node.Write(writer.get());
+    EXPECT_EQ(expected_output, actual_output);
+  }
+};  // class AstCppTests
+
+
+TEST_F(AstCppTests, GeneratesHeader) {
+  unique_ptr<MethodDecl> norm{new MethodDecl(
+      "void", "NormalMethod",
+      ArgList{vector<string>{"int normalarg", "float normal2"}})};
+  unique_ptr<MethodDecl> sub{
+      new MethodDecl("void", "SubMethod",
+                     ArgList{ "int subarg" },
+                     MethodDecl::IS_CONST | MethodDecl::IS_VIRTUAL)};
+  unique_ptr<MethodDecl> sub2{
+      new MethodDecl("void", "SubMethod",
+                     ArgList{ "int subarg" },
+                     MethodDecl::IS_CONST | MethodDecl::IS_VIRTUAL)};
+  vector<unique_ptr<Declaration>> test_methods;
+  test_methods.push_back(std::move(norm));
+  test_methods.push_back(std::move(sub));
+
+  vector<unique_ptr<Declaration>> test_sub_methods;
+  test_sub_methods.push_back(std::move(sub2));
+
+  unique_ptr<Declaration> test{new ClassDecl { "TestClass", "",
+      std::move(test_methods), {} }};
+
+  unique_ptr<Declaration> test_sub{new ClassDecl { "TestSubClass",
+      "TestClass", std::move(test_sub_methods), {} }};
+
+  vector<unique_ptr<Declaration>> classes;
+  classes.push_back(std::move(test));
+  classes.push_back(std::move(test_sub));
+
+  unique_ptr<CppNamespace> test_ns{new CppNamespace {"test",
+      std::move(classes)}};
+
+  vector<unique_ptr<Declaration>> test_ns_vec;
+  test_ns_vec.push_back(std::move(test_ns));
+
+  unique_ptr<CppNamespace> android_ns{new CppNamespace {"android",
+      std::move(test_ns_vec) }};
+
+  CppHeader cpp_header{"HEADER_INCLUDE_GUARD_H_", {"string", "memory"},
+      std::move(android_ns) };
+  CompareGeneratedCode(cpp_header, kExpectedHeaderOutput);
+}
+
+TEST_F(AstCppTests, GeneratesEnum) {
+  Enum e("Foo");
+  e.AddValue("BAR", "42");
+  e.AddValue("BAZ", "");
+  CompareGeneratedCode(e, kExpectedEnumOutput);
+}
+
+TEST_F(AstCppTests, GeneratesArgList) {
+  ArgList simple("foo");
+  CompareGeneratedCode(simple, "(foo)");
+  ArgList compound({"foo", "bar", "baz"});
+  CompareGeneratedCode(compound, "(foo, bar, baz)");
+  std::vector<unique_ptr<AstNode>> args;
+  args.emplace_back(new LiteralExpression("foo()"));
+  ArgList nested(std::move(args));
+  CompareGeneratedCode(nested, "(foo())");
+}
+
+TEST_F(AstCppTests, GeneratesStatement) {
+  Statement s(new LiteralExpression("foo"));
+  CompareGeneratedCode(s, "foo;\n");
+}
+
+TEST_F(AstCppTests, GeneratesComparison) {
+  Comparison c(
+      new LiteralExpression("lhs"), "&&", new LiteralExpression("rhs"));
+  CompareGeneratedCode(c, "((lhs) && (rhs))");
+}
+
+TEST_F(AstCppTests, GeneratesStatementBlock) {
+  StatementBlock block;
+  block.AddStatement(unique_ptr<AstNode>(new Statement("foo")));
+  block.AddStatement(unique_ptr<AstNode>(new Statement("bar")));
+  CompareGeneratedCode(block, "{\nfoo;\nbar;\n}\n");
+}
+
+TEST_F(AstCppTests, GeneratesConstructorImpl) {
+  ConstructorImpl c("ClassName", ArgList({"a", "b", "c"}),
+                    {"baz_(foo)", "bar_(blah)"});
+  string expected = R"(ClassName::ClassName(a, b, c)
+    : baz_(foo),
+      bar_(blah){
+}
+)";
+  CompareGeneratedCode(c, expected);
+}
+
+TEST_F(AstCppTests, GeneratesAssignment) {
+  Assignment simple("foo", "8");
+  CompareGeneratedCode(simple, "foo = 8;\n");
+  Assignment less_simple("foo", new MethodCall("f", "8"));
+  CompareGeneratedCode(less_simple, "foo = f(8);\n");
+}
+
+TEST_F(AstCppTests, GeneratesMethodCall) {
+  MethodCall single("single", "arg");
+  CompareGeneratedCode(single, "single(arg)");
+  MethodCall multi(
+      "multi",
+      ArgList({"has", "some", "args"}));
+  CompareGeneratedCode(multi, "multi(has, some, args)");
+}
+
+TEST_F(AstCppTests, GeneratesIfStatement) {
+  IfStatement s(new LiteralExpression("foo"));
+  s.OnTrue()->AddLiteral("on true1");
+  s.OnFalse()->AddLiteral("on false");
+  CompareGeneratedCode(s, "if (foo) {\non true1;\n}\nelse {\non false;\n}\n");
+
+  IfStatement s2(new LiteralExpression("bar"));
+  s2.OnTrue()->AddLiteral("on true1");
+  CompareGeneratedCode(s2, "if (bar) {\non true1;\n}\n");
+}
+
+TEST_F(AstCppTests, GeneratesSwitchStatement) {
+  SwitchStatement s("var");
+  // These are intentionally out of alphanumeric order.  We're testing
+  // that switch respects case addition order.
+  auto case2 = s.AddCase("2");
+  case2->AddStatement(unique_ptr<AstNode>{new Statement{"baz"}});
+  auto case1 = s.AddCase("1");
+  case1->AddStatement(unique_ptr<AstNode>{new Statement{"foo"}});
+  case1->AddStatement(unique_ptr<AstNode>{new Statement{"bar"}});
+  CompareGeneratedCode(s, kExpectedSwitchOutput);
+}
+
+TEST_F(AstCppTests, GeneratesMethodImpl) {
+  MethodImpl m{"return_type", "ClassName", "MethodName",
+               ArgList{{"arg 1", "arg 2", "arg 3"}},
+               true};
+  auto b = m.GetStatementBlock();
+  b->AddLiteral("foo");
+  b->AddLiteral("bar");
+  CompareGeneratedCode(m, kExpectedMethodImplOutput);
+}
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/ast_java.cpp b/aidl/ast_java.cpp
new file mode 100644
index 0000000..1ba723c
--- /dev/null
+++ b/aidl/ast_java.cpp
@@ -0,0 +1,525 @@
+/*
+ * 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 "ast_java.h"
+
+#include "code_writer.h"
+#include "type_java.h"
+
+using std::vector;
+using std::string;
+
+namespace android {
+namespace aidl {
+namespace java {
+
+void WriteModifiers(CodeWriter* to, int mod, int mask) {
+  int m = mod & mask;
+
+  if (m & OVERRIDE) {
+    to->Write("@Override ");
+  }
+
+  if ((m & SCOPE_MASK) == PUBLIC) {
+    to->Write("public ");
+  } else if ((m & SCOPE_MASK) == PRIVATE) {
+    to->Write("private ");
+  } else if ((m & SCOPE_MASK) == PROTECTED) {
+    to->Write("protected ");
+  }
+
+  if (m & STATIC) {
+    to->Write("static ");
+  }
+
+  if (m & FINAL) {
+    to->Write("final ");
+  }
+
+  if (m & ABSTRACT) {
+    to->Write("abstract ");
+  }
+}
+
+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);
+    if (i != N - 1) {
+      to->Write(", ");
+    }
+  }
+}
+
+Field::Field(int m, Variable* v) : ClassElement(), modifiers(m), variable(v) {}
+
+void Field::Write(CodeWriter* to) const {
+  if (this->comment.length() != 0) {
+    to->Write("%s\n", this->comment.c_str());
+  }
+  WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL | OVERRIDE);
+  to->Write("%s %s", this->variable->type->JavaType().c_str(),
+            this->variable->name.c_str());
+  if (this->value.length() != 0) {
+    to->Write(" = %s", this->value.c_str());
+  }
+  to->Write(";\n");
+}
+
+LiteralExpression::LiteralExpression(const string& v) : value(v) {}
+
+void LiteralExpression::Write(CodeWriter* to) const {
+  to->Write("%s", this->value.c_str());
+}
+
+StringLiteralExpression::StringLiteralExpression(const string& v) : value(v) {}
+
+void StringLiteralExpression::Write(CodeWriter* to) const {
+  to->Write("\"%s\"", this->value.c_str());
+}
+
+Variable::Variable(const Type* t, const string& n)
+    : type(t), name(n), dimension(0) {}
+
+Variable::Variable(const Type* t, const string& n, int d)
+    : type(t), name(n), dimension(d) {}
+
+void Variable::WriteDeclaration(CodeWriter* to) const {
+  string dim;
+  for (int i = 0; i < this->dimension; i++) {
+    dim += "[]";
+  }
+  to->Write("%s%s %s", this->type->JavaType().c_str(), dim.c_str(),
+            this->name.c_str());
+}
+
+void Variable::Write(CodeWriter* to) const { to->Write("%s", name.c_str()); }
+
+FieldVariable::FieldVariable(Expression* o, const string& n)
+    : object(o), clazz(NULL), name(n) {}
+
+FieldVariable::FieldVariable(const Type* c, const string& n)
+    : object(NULL), clazz(c), name(n) {}
+
+void FieldVariable::Write(CodeWriter* to) const {
+  if (this->object != NULL) {
+    this->object->Write(to);
+  } else if (this->clazz != NULL) {
+    to->Write("%s", this->clazz->JavaType().c_str());
+  }
+  to->Write(".%s", name.c_str());
+}
+
+void StatementBlock::Write(CodeWriter* to) const {
+  to->Write("{\n");
+  int N = this->statements.size();
+  for (int i = 0; i < N; i++) {
+    this->statements[i]->Write(to);
+  }
+  to->Write("}\n");
+}
+
+void StatementBlock::Add(Statement* statement) {
+  this->statements.push_back(statement);
+}
+
+void StatementBlock::Add(Expression* expression) {
+  this->statements.push_back(new ExpressionStatement(expression));
+}
+
+ExpressionStatement::ExpressionStatement(Expression* e) : expression(e) {}
+
+void ExpressionStatement::Write(CodeWriter* to) const {
+  this->expression->Write(to);
+  to->Write(";\n");
+}
+
+Assignment::Assignment(Variable* l, Expression* r)
+    : lvalue(l), rvalue(r), cast(NULL) {}
+
+Assignment::Assignment(Variable* l, Expression* r, const Type* c)
+    : lvalue(l), rvalue(r), cast(c) {}
+
+void Assignment::Write(CodeWriter* to) const {
+  this->lvalue->Write(to);
+  to->Write(" = ");
+  if (this->cast != NULL) {
+    to->Write("(%s)", this->cast->JavaType().c_str());
+  }
+  this->rvalue->Write(to);
+}
+
+MethodCall::MethodCall(const string& n) : name(n) {}
+
+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(Expression* o, const string& n) : obj(o), name(n) {}
+
+MethodCall::MethodCall(const Type* t, const string& n) : clazz(t), name(n) {}
+
+MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...)
+    : obj(o), name(n) {
+  va_list args;
+  va_start(args, argc);
+  init(argc, args);
+  va_end(args);
+}
+
+MethodCall::MethodCall(const Type* t, const string& n, int argc = 0, ...)
+    : clazz(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 {
+  if (this->obj != NULL) {
+    this->obj->Write(to);
+    to->Write(".");
+  } else if (this->clazz != NULL) {
+    to->Write("%s.", this->clazz->JavaType().c_str());
+  }
+  to->Write("%s(", this->name.c_str());
+  WriteArgumentList(to, this->arguments);
+  to->Write(")");
+}
+
+Comparison::Comparison(Expression* l, const string& o, Expression* r)
+    : lvalue(l), op(o), rvalue(r) {}
+
+void Comparison::Write(CodeWriter* to) const {
+  to->Write("(");
+  this->lvalue->Write(to);
+  to->Write("%s", this->op.c_str());
+  this->rvalue->Write(to);
+  to->Write(")");
+}
+
+NewExpression::NewExpression(const Type* t) : type(t) {}
+
+NewExpression::NewExpression(const Type* t, int argc = 0, ...) : type(t) {
+  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->type->InstantiableName().c_str());
+  WriteArgumentList(to, this->arguments);
+  to->Write(")");
+}
+
+NewArrayExpression::NewArrayExpression(const Type* t, Expression* s)
+    : type(t), size(s) {}
+
+void NewArrayExpression::Write(CodeWriter* to) const {
+  to->Write("new %s[", this->type->JavaType().c_str());
+  size->Write(to);
+  to->Write("]");
+}
+
+Ternary::Ternary(Expression* a, Expression* b, Expression* c)
+    : condition(a), ifpart(b), elsepart(c) {}
+
+void Ternary::Write(CodeWriter* to) const {
+  to->Write("((");
+  this->condition->Write(to);
+  to->Write(")?(");
+  this->ifpart->Write(to);
+  to->Write("):(");
+  this->elsepart->Write(to);
+  to->Write("))");
+}
+
+Cast::Cast(const Type* t, Expression* e) : type(t), expression(e) {}
+
+void Cast::Write(CodeWriter* to) const {
+  to->Write("((%s)", this->type->JavaType().c_str());
+  expression->Write(to);
+  to->Write(")");
+}
+
+VariableDeclaration::VariableDeclaration(Variable* l, Expression* r,
+                                         const Type* c)
+    : lvalue(l), cast(c), rvalue(r) {}
+
+VariableDeclaration::VariableDeclaration(Variable* l) : lvalue(l) {}
+
+void VariableDeclaration::Write(CodeWriter* to) const {
+  this->lvalue->WriteDeclaration(to);
+  if (this->rvalue != NULL) {
+    to->Write(" = ");
+    if (this->cast != NULL) {
+      to->Write("(%s)", this->cast->JavaType().c_str());
+    }
+    this->rvalue->Write(to);
+  }
+  to->Write(";\n");
+}
+
+void IfStatement::Write(CodeWriter* to) const {
+  if (this->expression != NULL) {
+    to->Write("if (");
+    this->expression->Write(to);
+    to->Write(") ");
+  }
+  this->statements->Write(to);
+  if (this->elseif != NULL) {
+    to->Write("else ");
+    this->elseif->Write(to);
+  }
+}
+
+ReturnStatement::ReturnStatement(Expression* e) : expression(e) {}
+
+void ReturnStatement::Write(CodeWriter* to) const {
+  to->Write("return ");
+  this->expression->Write(to);
+  to->Write(";\n");
+}
+
+void TryStatement::Write(CodeWriter* to) const {
+  to->Write("try ");
+  this->statements->Write(to);
+}
+
+CatchStatement::CatchStatement(Variable* e)
+    : statements(new StatementBlock), exception(e) {}
+
+void CatchStatement::Write(CodeWriter* to) const {
+  to->Write("catch ");
+  if (this->exception != NULL) {
+    to->Write("(");
+    this->exception->WriteDeclaration(to);
+    to->Write(") ");
+  }
+  this->statements->Write(to);
+}
+
+void FinallyStatement::Write(CodeWriter* to) const {
+  to->Write("finally ");
+  this->statements->Write(to);
+}
+
+Case::Case(const string& c) { cases.push_back(c); }
+
+void Case::Write(CodeWriter* to) const {
+  int N = this->cases.size();
+  if (N > 0) {
+    for (int i = 0; i < N; i++) {
+      string s = this->cases[i];
+      if (s.length() != 0) {
+        to->Write("case %s:\n", s.c_str());
+      } else {
+        to->Write("default:\n");
+      }
+    }
+  } else {
+    to->Write("default:\n");
+  }
+  statements->Write(to);
+}
+
+SwitchStatement::SwitchStatement(Expression* e) : expression(e) {}
+
+void SwitchStatement::Write(CodeWriter* to) const {
+  to->Write("switch (");
+  this->expression->Write(to);
+  to->Write(")\n{\n");
+  int N = this->cases.size();
+  for (int i = 0; i < N; i++) {
+    this->cases[i]->Write(to);
+  }
+  to->Write("}\n");
+}
+
+void Break::Write(CodeWriter* to) const { to->Write("break;\n"); }
+
+void Method::Write(CodeWriter* to) const {
+  size_t N, i;
+
+  if (this->comment.length() != 0) {
+    to->Write("%s\n", this->comment.c_str());
+  }
+
+  WriteModifiers(to, this->modifiers,
+                 SCOPE_MASK | STATIC | ABSTRACT | FINAL | OVERRIDE);
+
+  if (this->returnType != NULL) {
+    string dim;
+    for (i = 0; i < this->returnTypeDimension; i++) {
+      dim += "[]";
+    }
+    to->Write("%s%s ", this->returnType->JavaType().c_str(), dim.c_str());
+  }
+
+  to->Write("%s(", this->name.c_str());
+
+  N = this->parameters.size();
+  for (i = 0; i < N; i++) {
+    this->parameters[i]->WriteDeclaration(to);
+    if (i != N - 1) {
+      to->Write(", ");
+    }
+  }
+
+  to->Write(")");
+
+  N = this->exceptions.size();
+  for (i = 0; i < N; i++) {
+    if (i == 0) {
+      to->Write(" throws ");
+    } else {
+      to->Write(", ");
+    }
+    to->Write("%s", this->exceptions[i]->JavaType().c_str());
+  }
+
+  if (this->statements == NULL) {
+    to->Write(";\n");
+  } else {
+    to->Write("\n");
+    this->statements->Write(to);
+  }
+}
+
+void IntConstant::Write(CodeWriter* to) const {
+  WriteModifiers(to, STATIC | FINAL | PUBLIC, ALL_MODIFIERS);
+  to->Write("int %s = %d;\n", name.c_str(), value);
+}
+
+void StringConstant::Write(CodeWriter* to) const {
+  WriteModifiers(to, STATIC | FINAL | PUBLIC, ALL_MODIFIERS);
+  to->Write("String %s = %s;\n", name.c_str(), value.c_str());
+}
+
+void Class::Write(CodeWriter* to) const {
+  size_t N, i;
+
+  if (this->comment.length() != 0) {
+    to->Write("%s\n", this->comment.c_str());
+  }
+
+  WriteModifiers(to, this->modifiers, ALL_MODIFIERS);
+
+  if (this->what == Class::CLASS) {
+    to->Write("class ");
+  } else {
+    to->Write("interface ");
+  }
+
+  string name = this->type->JavaType();
+  size_t pos = name.rfind('.');
+  if (pos != string::npos) {
+    name = name.c_str() + pos + 1;
+  }
+
+  to->Write("%s", name.c_str());
+
+  if (this->extends != NULL) {
+    to->Write(" extends %s", this->extends->JavaType().c_str());
+  }
+
+  N = this->interfaces.size();
+  if (N != 0) {
+    if (this->what == Class::CLASS) {
+      to->Write(" implements");
+    } else {
+      to->Write(" extends");
+    }
+    for (i = 0; i < N; i++) {
+      to->Write(" %s", this->interfaces[i]->JavaType().c_str());
+    }
+  }
+
+  to->Write("\n");
+  to->Write("{\n");
+
+  N = this->elements.size();
+  for (i = 0; i < N; i++) {
+    this->elements[i]->Write(to);
+  }
+
+  to->Write("}\n");
+}
+
+static string escape_backslashes(const string& str) {
+  string result;
+  const size_t I = str.length();
+  for (size_t i = 0; i < I; i++) {
+    char c = str[i];
+    if (c == '\\') {
+      result += "\\\\";
+    } else {
+      result += c;
+    }
+  }
+  return result;
+}
+
+Document::Document(const std::string& comment,
+                   const std::string& package,
+                   const std::string& original_src,
+                   std::unique_ptr<Class> clazz)
+    : comment_(comment),
+      package_(package),
+      original_src_(original_src),
+      clazz_(std::move(clazz)) {
+}
+
+void Document::Write(CodeWriter* to) const {
+  if (!comment_.empty()) {
+    to->Write("%s\n", comment_.c_str());
+  }
+  to->Write(
+      "/*\n"
+      " * This file is auto-generated.  DO NOT MODIFY.\n"
+      " * Original file: %s\n"
+      " */\n",
+      escape_backslashes(original_src_).c_str());
+  if (!package_.empty()) {
+    to->Write("package %s;\n", package_.c_str());
+  }
+
+  if (clazz_) {
+    clazz_->Write(to);
+  }
+}
+
+}  // namespace java
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/ast_java.h b/aidl/ast_java.h
new file mode 100644
index 0000000..c5ded58
--- /dev/null
+++ b/aidl/ast_java.h
@@ -0,0 +1,388 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_AST_JAVA_H_
+#define AIDL_AST_JAVA_H_
+
+#include <memory>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+enum {
+  PACKAGE_PRIVATE = 0x00000000,
+  PUBLIC = 0x00000001,
+  PRIVATE = 0x00000002,
+  PROTECTED = 0x00000003,
+  SCOPE_MASK = 0x00000003,
+
+  STATIC = 0x00000010,
+  FINAL = 0x00000020,
+  ABSTRACT = 0x00000040,
+
+  OVERRIDE = 0x00000100,
+
+  ALL_MODIFIERS = 0xffffffff
+};
+
+namespace android {
+namespace aidl {
+class CodeWriter;
+}  // namespace aidl
+}  // namespace android
+
+namespace android {
+namespace aidl {
+namespace java {
+
+class Type;
+
+// Write the modifiers that are set in both mod and mask
+void WriteModifiers(CodeWriter* to, int mod, int mask);
+
+struct ClassElement {
+  ClassElement() = default;
+  virtual ~ClassElement() = default;
+
+  virtual void Write(CodeWriter* to) const = 0;
+};
+
+struct Expression {
+  virtual ~Expression() = default;
+  virtual void Write(CodeWriter* to) const = 0;
+};
+
+struct LiteralExpression : public Expression {
+  std::string value;
+
+  explicit LiteralExpression(const std::string& value);
+  virtual ~LiteralExpression() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+// TODO: also escape the contents.  not needed for now
+struct StringLiteralExpression : public Expression {
+  std::string value;
+
+  explicit StringLiteralExpression(const std::string& value);
+  virtual ~StringLiteralExpression() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct Variable : public Expression {
+  const Type* type = nullptr;
+  std::string name;
+  int dimension = 0;
+
+  Variable() = default;
+  Variable(const Type* type, const std::string& name);
+  Variable(const Type* type, const std::string& name, int dimension);
+  virtual ~Variable() = default;
+
+  void WriteDeclaration(CodeWriter* to) const;
+  void Write(CodeWriter* to) const;
+};
+
+struct FieldVariable : public Expression {
+  Expression* object;
+  const Type* clazz;
+  std::string name;
+
+  FieldVariable(Expression* object, const std::string& name);
+  FieldVariable(const Type* clazz, const std::string& name);
+  virtual ~FieldVariable() = default;
+
+  void Write(CodeWriter* to) const;
+};
+
+struct Field : public ClassElement {
+  std::string comment;
+  int modifiers = 0;
+  Variable* variable = nullptr;
+  std::string value;
+
+  Field() = default;
+  Field(int modifiers, Variable* variable);
+  virtual ~Field() = default;
+
+  void Write(CodeWriter* to) const override;
+};
+
+struct Statement {
+  virtual ~Statement() = default;
+  virtual void Write(CodeWriter* to) const = 0;
+};
+
+struct StatementBlock : public Statement {
+  std::vector<Statement*> statements;
+
+  StatementBlock() = default;
+  virtual ~StatementBlock() = default;
+  void Write(CodeWriter* to) const override;
+
+  void Add(Statement* statement);
+  void Add(Expression* expression);
+};
+
+struct ExpressionStatement : public Statement {
+  Expression* expression;
+
+  explicit ExpressionStatement(Expression* expression);
+  virtual ~ExpressionStatement() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct Assignment : public Expression {
+  Variable* lvalue;
+  Expression* rvalue;
+  const Type* cast;
+
+  Assignment(Variable* lvalue, Expression* rvalue);
+  Assignment(Variable* lvalue, Expression* rvalue, const Type* cast);
+  virtual ~Assignment() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct MethodCall : public Expression {
+  Expression* obj = nullptr;
+  const Type* clazz = nullptr;
+  std::string name;
+  std::vector<Expression*> arguments;
+  std::vector<std::string> exceptions;
+
+  explicit MethodCall(const std::string& name);
+  MethodCall(const std::string& name, int argc, ...);
+  MethodCall(Expression* obj, const std::string& name);
+  MethodCall(const Type* clazz, const std::string& name);
+  MethodCall(Expression* obj, const std::string& name, int argc, ...);
+  MethodCall(const Type* clazz, 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 {
+  Expression* lvalue;
+  std::string op;
+  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 Type* type;
+  std::vector<Expression*> arguments;
+
+  explicit NewExpression(const Type* type);
+  NewExpression(const Type* type, int argc, ...);
+  virtual ~NewExpression() = default;
+  void Write(CodeWriter* to) const override;
+
+ private:
+  void init(int n, va_list args);
+};
+
+struct NewArrayExpression : public Expression {
+  const Type* type;
+  Expression* size;
+
+  NewArrayExpression(const Type* type, Expression* size);
+  virtual ~NewArrayExpression() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct Ternary : public Expression {
+  Expression* condition = nullptr;
+  Expression* ifpart = nullptr;
+  Expression* elsepart = nullptr;
+
+  Ternary() = default;
+  Ternary(Expression* condition, Expression* ifpart, Expression* elsepart);
+  virtual ~Ternary() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct Cast : public Expression {
+  const Type* type = nullptr;
+  Expression* expression = nullptr;
+
+  Cast() = default;
+  Cast(const Type* type, Expression* expression);
+  virtual ~Cast() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct VariableDeclaration : public Statement {
+  Variable* lvalue = nullptr;
+  const Type* cast = nullptr;
+  Expression* rvalue = nullptr;
+
+  explicit VariableDeclaration(Variable* lvalue);
+  VariableDeclaration(Variable* lvalue, Expression* rvalue,
+                      const Type* cast = NULL);
+  virtual ~VariableDeclaration() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct IfStatement : public Statement {
+  Expression* expression = nullptr;
+  StatementBlock* statements = new StatementBlock;
+  IfStatement* elseif = nullptr;
+
+  IfStatement() = default;
+  virtual ~IfStatement() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct ReturnStatement : public Statement {
+  Expression* expression;
+
+  explicit ReturnStatement(Expression* expression);
+  virtual ~ReturnStatement() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct TryStatement : public Statement {
+  StatementBlock* statements = new StatementBlock;
+
+  TryStatement() = default;
+  virtual ~TryStatement() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct CatchStatement : public Statement {
+  StatementBlock* statements;
+  Variable* exception;
+
+  explicit CatchStatement(Variable* exception);
+  virtual ~CatchStatement() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct FinallyStatement : public Statement {
+  StatementBlock* statements = new StatementBlock;
+
+  FinallyStatement() = default;
+  virtual ~FinallyStatement() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct Case {
+  std::vector<std::string> cases;
+  StatementBlock* statements = new StatementBlock;
+
+  Case() = default;
+  explicit Case(const std::string& c);
+  virtual ~Case() = default;
+  virtual void Write(CodeWriter* to) const;
+};
+
+struct SwitchStatement : public Statement {
+  Expression* expression;
+  std::vector<Case*> cases;
+
+  explicit SwitchStatement(Expression* expression);
+  virtual ~SwitchStatement() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct Break : public Statement {
+  Break() = default;
+  virtual ~Break() = default;
+  void Write(CodeWriter* to) const override;
+};
+
+struct Method : public ClassElement {
+  std::string comment;
+  int modifiers = 0;
+  const Type* returnType = nullptr;  // nullptr means constructor
+  size_t returnTypeDimension = 0;
+  std::string name;
+  std::vector<Variable*> parameters;
+  std::vector<const Type*> exceptions;
+  StatementBlock* statements = nullptr;
+
+  Method() = default;
+  virtual ~Method() = default;
+
+  void Write(CodeWriter* to) const override;
+};
+
+struct IntConstant : public ClassElement {
+  const std::string name;
+  const int value;
+
+  IntConstant(std::string name, int value)
+      : name(name), value(value) {}
+  virtual ~IntConstant() = default;
+
+  void Write(CodeWriter* to) const override;
+};
+
+struct StringConstant : public ClassElement {
+  const std::string name;
+  const std::string value;
+
+  StringConstant(std::string name, std::string value)
+      : name(name), value(value) {}
+  ~StringConstant() override = default;
+
+  void Write(CodeWriter* to) const override;
+};
+
+struct Class : public ClassElement {
+  enum { CLASS, INTERFACE };
+
+  std::string comment;
+  int modifiers = 0;
+  int what = CLASS;  // CLASS or INTERFACE
+  const Type* type = nullptr;
+  const Type* extends = nullptr;
+  std::vector<const Type*> interfaces;
+  std::vector<ClassElement*> elements;
+
+  Class() = default;
+  virtual ~Class() = default;
+
+  void Write(CodeWriter* to) const override;
+};
+
+class Document {
+ public:
+  Document(const std::string& comment,
+           const std::string& package,
+           const std::string& original_src,
+           std::unique_ptr<Class> clazz);
+  virtual ~Document() = default;
+  virtual void Write(CodeWriter* to) const;
+
+ private:
+  std::string comment_;
+  std::string package_;
+  std::string original_src_;
+  std::unique_ptr<Class> clazz_;
+};
+
+}  // namespace java
+}  // namespace aidl
+}  // namespace android
+
+#endif  // AIDL_AST_JAVA_H_
diff --git a/aidl/ast_java_unittest.cpp b/aidl/ast_java_unittest.cpp
new file mode 100644
index 0000000..b2aad23
--- /dev/null
+++ b/aidl/ast_java_unittest.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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 <string>
+
+#include <gtest/gtest.h>
+
+#include "ast_java.h"
+#include "code_writer.h"
+#include "type_java.h"
+
+using std::string;
+
+namespace android {
+namespace aidl {
+namespace java {
+namespace {
+
+const char kExpectedClassOutput[] =
+R"(// class comment
+final class TestClass extends SuperClass
+{
+}
+)";
+
+}  // namespace
+
+TEST(AstJavaTests, GeneratesClass) {
+  JavaTypeNamespace types;
+  types.Init();
+  Type class_type(&types, "TestClass", ValidatableType::KIND_GENERATED,
+                  false, false);
+  Type extend_type(&types, "SuperClass", ValidatableType::KIND_BUILT_IN,
+                   false, false);
+  Class a_class;
+  a_class.comment = "// class comment";
+  a_class.modifiers = FINAL;
+  a_class.what = Class::CLASS;
+  a_class.type = &class_type;
+  a_class.extends = &extend_type;
+
+  string actual_output;
+  CodeWriterPtr writer = GetStringWriter(&actual_output);
+  a_class.Write(writer.get());
+  EXPECT_EQ(string(kExpectedClassOutput), actual_output);
+}
+
+}  // namespace java
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/code_writer.cpp b/aidl/code_writer.cpp
new file mode 100644
index 0000000..58b1dc1
--- /dev/null
+++ b/aidl/code_writer.cpp
@@ -0,0 +1,115 @@
+/*
+ * 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 "code_writer.h"
+
+#include <iostream>
+#include <stdarg.h>
+
+#include <android-base/stringprintf.h>
+
+using std::cerr;
+using std::endl;
+
+namespace android {
+namespace aidl {
+
+namespace {
+
+class StringCodeWriter : public CodeWriter {
+ public:
+  explicit StringCodeWriter(std::string* output_buffer) : output_(output_buffer) {}
+  virtual ~StringCodeWriter() = default;
+
+  bool Write(const char* format, ...) override {
+    va_list ap;
+    va_start(ap, format);
+    android::base::StringAppendV(output_, format, ap);
+    va_end(ap);
+    return true;
+  }
+
+  bool Close() override { return true; }
+
+ private:
+  std::string* output_;
+};  // class StringCodeWriter
+
+class FileCodeWriter : public CodeWriter {
+ public:
+  FileCodeWriter(FILE* output_file, bool close_on_destruction)
+      : output_(output_file),
+        close_on_destruction_(close_on_destruction) {}
+  virtual ~FileCodeWriter() {
+    if (close_on_destruction_ && output_ != nullptr) {
+      fclose(output_);
+    }
+  }
+
+  bool Write(const char* format, ...) override {
+    bool success;
+    va_list ap;
+    va_start(ap, format);
+    success = vfprintf(output_, format, ap) >= 0;
+    va_end(ap);
+    no_error_ = no_error_ && success;
+    return success;
+  }
+
+  bool Close() override {
+    if (output_ != nullptr) {
+      no_error_ = fclose(output_) == 0 && no_error_;
+      output_ = nullptr;
+    }
+    return no_error_;
+  }
+
+ private:
+  bool no_error_ = true;
+  FILE* output_;
+  bool close_on_destruction_;
+};  // class StringCodeWriter
+
+}  // namespace
+
+CodeWriterPtr GetFileWriter(const std::string& output_file) {
+  CodeWriterPtr result;
+  FILE* to = nullptr;
+  bool close_on_destruction = true;
+  if (output_file == "-") {
+    to = stdout;
+    close_on_destruction = false;
+  } else {
+    // open file in binary mode to ensure that the tool produces the
+    // same output on all platforms !!
+    to = fopen(output_file.c_str(), "wb");
+  }
+
+  if (to != nullptr) {
+    result.reset(new FileCodeWriter(to, close_on_destruction));
+  } else {
+    cerr << "unable to open " << output_file << " for write" << endl;
+  }
+
+  return result;
+}
+
+CodeWriterPtr GetStringWriter(std::string* output_buffer) {
+  return CodeWriterPtr(new StringCodeWriter(output_buffer));
+}
+
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/code_writer.h b/aidl/code_writer.h
new file mode 100644
index 0000000..4b2fe16
--- /dev/null
+++ b/aidl/code_writer.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_CODE_WRITER_H_
+#define AIDL_CODE_WRITER_H_
+
+#include <memory>
+#include <string>
+
+#include <stdio.h>
+
+#include <android-base/macros.h>
+
+namespace android {
+namespace aidl {
+
+class CodeWriter {
+ public:
+  // Write a formatted string to this writer in the usual printf sense.
+  // Returns false on error.
+  virtual bool Write(const char* format, ...) = 0;
+  virtual bool Close() = 0;
+  virtual ~CodeWriter() = default;
+};  // class CodeWriter
+
+using CodeWriterPtr = std::unique_ptr<CodeWriter>;
+
+// Get a CodeWriter that writes to |output_file|.
+CodeWriterPtr GetFileWriter(const std::string& output_file);
+
+// Get a CodeWriter that writes to a string buffer.
+// Caller retains ownership of the buffer.
+// The buffer must outlive the CodeWriter.
+CodeWriterPtr GetStringWriter(std::string* output_buffer);
+
+}  // namespace aidl
+}  // namespace android
+
+#endif // AIDL_CODE_WRITER_H_
diff --git a/aidl/docs/aidl-cpp.md b/aidl/docs/aidl-cpp.md
new file mode 100644
index 0000000..65cc8e4
--- /dev/null
+++ b/aidl/docs/aidl-cpp.md
@@ -0,0 +1,276 @@
+# Generating C++ Binder Interfaces with `aidl-cpp`
+
+## Background
+
+“aidl” refers to several related but distinct concepts:
+
+ - the AIDL interface [definition language](http://developer.android.com/guide/components/aidl.html)
+ - .aidl files (which contain AIDL)
+ - the aidl generator which transforms AIDL into client/server IPC interfaces
+
+The _aidl generator_ is a command line tool that generates client and server
+stubs for Binder interfaces from a specification in a file with the .aidl
+extension.  For Java interfaces, the executable is called `aidl` while for C++
+the binary is called `aidl-cpp`.  In this document, we’ll use AIDL to describe
+the language of .aidl files and _aidl generator_ to refer to the code generation
+tool that takes an .aidl file, parses the AIDL, and outputs code.
+
+Previously, the _aidl generator_ only generated Java interface/stub/proxy
+objects.  C++ Binder interfaces were handcrafted with various degrees of
+compatibility with the Java equivalents.  The Brillo project added support for
+generating C++ with the _aidl generator_.  This generated C++ is cross-language
+compatible (e.g. Java clients are tested to interoperate with native services).
+
+## Overview
+
+This document describes how C++ generation works with attention to:
+
+ - build interface
+ - cross-language type mapping
+ - implementing a generated interface
+ - C++ parcelables
+ - cross-language error reporting
+ - cross-language null reference handling
+
+## Detailed Design
+
+### Build Interface
+
+Write AIDL in .aidl files and add them to `LOCAL_SRC_FILES` in your Android.mk.
+If your build target is a binary (e.g. you include `$(BUILD_SHARED_LIBRARY)`),
+then the generated code will be C++, not Java.
+
+AIDL definitions should be hosted from the same repository as the
+implementation.  Any system that needs the definition will also need the
+implementation (for both parcelables and interface).  If there are multiple
+implementations (i.e. one in Java and one in C++), keep the definition with the
+native implementation.  Android
+[now has systems](https://developers.google.com/brillo/?hl=en) that run the
+native components of the system without the Java.
+
+If you use an import statement in your AIDL, even from the same package, you
+need to add a path to `LOCAL_AIDL_INCLUDES`.  This path should be relative to
+the root of the Android tree.  For instance, a file IFoo.aidl defining
+com.example.IFoo might sit in a folder hierarchy
+something/something-else/com/example/IFoo.aidl.  Then we would write:
+
+```
+LOCAL_AIDL_INCLUDES := something/something-else
+```
+
+Generated C++ ends up in nested namespaces corresponding to the interface’s
+package.  The generated header also corresponds to the interface package.  So
+com.example.IFoo becomes ::com::example::IFoo in header “com/example/IFoo.h”.
+
+Similar to how Java works, the suffix of the path to a .aidl file must match
+the package.  So if IFoo.aidl declares itself to be in package com.example, the
+folder structure (as given to `LOCAL_SRC_FILES`) must look like:
+`some/prefix/com/example/IFoo.aidl`.
+
+To generate code from .aidl files from another build target (e.g. another
+binary or java), just add a relative path to the .aidl files to
+`LOCAL_SRC_FILES`.  Remember that importing AIDL works the same, even for code
+in other directory hierarchies: add the include root path relative to the
+checkout root to `LOCAL_AIDL_INCLUDES`.
+
+### Type Mapping
+
+The following table summarizes the equivalent C++ types for common Java types
+and whether those types may be used as in/out/inout parameters in AIDL
+interfaces.
+
+| Java Type             | C++ Type            | inout | Notes                                                 |
+|-----------------------|---------------------|-------|-------------------------------------------------------|
+| boolean               | bool                | in    | "These 8 types are all considered primitives.         |
+| byte                  | int8\_t             | in    |                                                       |
+| char                  | char16\_t           | in    |                                                       |
+| int                   | int32\_t            | in    |                                                       |
+| long                  | int64\_t            | in    |                                                       |
+| float                 | float               | in    |                                                       |
+| double                | double              | in    |                                                       |
+| 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 |                                                       |
+| T extends IBinder     | sp<T>               | in    |                                                       |
+| Arrays (T[])          | vector<T>           | inout | May contain only primitives, Strings and parcelables. |
+| List<String>          | vector<String16>    | inout |                                                       |
+| PersistableBundle     | PersistableBundle   | inout | binder/PersistableBundle.h                            |
+| List<IBinder>         | vector<sp<IBinder>> | inout |                                                       |
+| FileDescriptor        | unique_fd           | inout | android-base/unique_fd.h from libbase                 |
+
+Note that java.util.Map and java.utils.List are not good candidates for cross
+language communication because they may contain arbitrary types on the Java
+side.  For instance, Map is cast to Map<String,Object> and then the object
+values dynamically inspected and serialized as type/value pairs.  Support
+exists for sending arbitrary Java serializables, Android Bundles, etc.
+
+Note that annotations may be placed at the interface level, as well as on a
+type by type basis.  Interface level annotations will be applied
+opportunistically and be overridden by per type annotations.  For instance, an
+interface marked @nullable will still not allow null int parameters.
+
+### Implementing a generated interface
+
+Given an interface declaration like:
+
+```
+package foo;
+
+import bar.IAnotherInterface;
+
+interface IFoo {
+  IAnotherInterface DoSomething(int count, out List<String> output);
+}
+```
+
+`aidl-cpp` will generate a C++ interface:
+
+```
+namespace foo {
+
+// Some headers have been omitted for clarity.
+#include <android/String16.h>
+#include <cstdint>
+#include <vector>
+#include <bar/IAnotherInterface.h>
+
+// Some class members have been omitted for clarity.
+class IFoo : public android::IInterface {
+ public:
+  virtual android::binder::Status DoSomething(
+      int32_t count,
+      std::vector<android::String16>* output,
+      android::sp<bar::IAnotherInterface>* returned_value) = 0;
+};
+```
+
+Note that `aidl-cpp` will import headers for types used in the interface.  For
+imported types (e.g. parcelables and interfaces), it will import a header
+corresponding to the package/class name of the import.  For instance,
+`import bar.IAnotherInterface` causes aidl-cpp to generate
+`#include <bar/IAnotherInterface.h>`.
+
+When writing a service that implements this interface, write:
+
+```
+#include "foo/BnFoo.h"
+
+namespace unrelated_namespace {
+
+class MyFoo : public foo::BnFoo {
+ public:
+  android::binder::Status DoSomething(
+      int32_t count,
+      std::vector<android::String16>* output,
+      android::sp<bar::IAnotherInterface>* returned_value) override {
+    for (int32_t i = 0; i < count; ++i) {
+      output->push_back(String16("..."));
+    }
+    *returned_value = new InstanceOfAnotherInterface;
+    return Status::ok();
+  }
+};  // class MyFoo
+
+}  // namespace unrelated_namespace
+```
+
+Note that the output values, `output` and `returned_value` are passed by
+pointer, and that this pointer is always valid.
+
+#### Dependencies
+
+The generated C++ code will use symbols from libbinder as well as libutils.
+AIDL files using the FileDescriptor type will also explicitly require
+libnativehelper, although this is likely a transitive dependency of the other
+two, and should be included automatically within the Android build tree
+regardless.
+
+### C++ Parcelables
+
+In Java, a parcelable should extend android.os.Parcelable and provide a static
+final CREATOR field that acts as a factory for new instances/arrays of
+instances of the parcelable.  In addition, in order to be used as an out
+parameter, a parcelable class must define a readFromParcel method.
+
+In C++, parcelables must implement android::Parcelable from binder/Parcelable.h
+in libbinder.  Parcelables must define a constructor that takes no arguments.
+In order to be used in arrays, a parcelable must implement a copy or move
+constructor (called implicitly in vector).
+
+The C++ generator needs to know what header defines the C++ parcelable.  It
+learns this from the `cpp_header` directive shown below.  The generator takes
+this string and uses it as the literal include statement in generated code.
+The idea here is that you generate your code once, link it into a library along
+with parcelable implementations, and export appropriate header paths.  This
+header include must make sense in the context of the Android.mk that compiles
+this generated code.
+
+```
+// ExampleParcelable.aidl
+package com.example.android;
+
+// Native types must be aliased at their declaration in the appropriate .aidl
+// file.  This allows multiple interfaces to use a parcelable and its C++
+// equivalent without duplicating the mapping between the C++ and Java types.
+// Generator will assume bar/foo.h declares class
+// com::example::android::ExampleParcelable
+parcelable ExampleParcelable cpp_header "bar/foo.h";
+```
+
+### Null Reference Handling
+
+The aidl generator for both C++ and Java languages has been expanded to
+understand nullable annotations.
+
+Given an interface definition like:
+
+```
+interface IExample {
+  void ReadStrings(String neverNull, in @nullable String maybeNull);
+};
+```
+
+the generated C++ header code looks like:
+
+```
+class IExample {
+  android::binder::Status ReadStrings(
+      const android::String16& in_neverNull,
+      const std::unique_ptr<android::String16>& in_maybeNull);
+};
+```
+
+Note that by default, the generated C++ passes a const reference to the value
+of a parameter and rejects null references with a NullPointerException sent
+back the caller.  Parameters marked with @nullable are passed by pointer,
+allowing native services to explicitly control whether they allow method
+overloading via null parameters.  Java stubs and proxies currently do nothing
+with the @nullable annotation.
+
+Consider an AIDL type `in @nullable List<String> bar`.  This type
+indicates that the remote caller may pass in a list of strings, and that both
+the list and any string in the list may be null.  This type will map to a C++
+type `unique_ptr<vector<unique_ptr<String16>>>* bar`.  In this case:
+
+  - `bar` is never null
+  - `*bar` might be null
+  - `(*bar)->empty()` could be true
+  - `(**bar)[0]` could be null (and so on)
+
+### Exception Reporting
+
+C++ methods generated by the aidl generator return `android::binder::Status`
+objects, rather than `android::status_t`.  This Status object allows generated
+C++ code to send and receive exceptions (an exception type and a String16 error
+message) since we do not use real exceptions in C++.  More background on Status
+objects can be found here.
+
+For legacy support and migration ease, the Status object includes a mechanism
+to report a `android::status_t`.  However, that return code is interpreted by a
+different code path and does not include a helpful String message.
+
+For situations where your native service needs to throw an error code specific
+to the service, use `Status::fromServiceSpecificError()`.  This kind of
+exception comes with a helpful message and an integer error code.  Make your
+error codes consistent across services by using interface constants (see
+below).
diff --git a/aidl/docs/constants.md b/aidl/docs/constants.md
new file mode 100644
index 0000000..55fbd97
--- /dev/null
+++ b/aidl/docs/constants.md
@@ -0,0 +1,35 @@
+# Defining constants as part of an interface
+
+AIDL has been enhanced to support defining integer and string constants
+as part of an interface.
+
+## Integer constants
+
+```
+interface IMyInterface {
+    const int CONST_A = 1;
+    const int CONST_B = 2;
+    const int CONST_C = 3;
+    ...
+}
+```
+
+These map to appropriate 32 bit integer class constants in Java and C++ (e.g.
+`IMyInterface.CONST_A` and `IMyInterface::CONST_A` respectively).
+
+## String constants
+
+```
+interface IMyInterface {
+    const String CONST_A = "foo";
+    const String CONST_B = "bar";
+    ...
+}
+```
+
+These map to class level String constants in Java, and static getter
+functions that return a const android::String16& in C++.
+
+The constants are limited to contain printable ASCII characters < 0x10
+and without backspaces (i.e. no '\' character).
+
diff --git a/aidl/docs/making-changes.md b/aidl/docs/making-changes.md
new file mode 100644
index 0000000..ac84b86
--- /dev/null
+++ b/aidl/docs/making-changes.md
@@ -0,0 +1,21 @@
+# Making changes
+
+## Coding style
+
+This project was originally written in C, in the Android platform style.
+It has been substantially re-written in C++, in the Google C++ style.
+
+This style
+[is summarized here](https://google.github.io/styleguide/cppguide.html).
+
+When in doubt, clang-format -style=google is a good reference.
+
+## Testing
+
+This codebase has both integration and unittests, all of which are expected to
+consistently pass against a device/emulator:
+
+```
+$ ./runtests.sh && echo "All tests pass"
+
+```
diff --git a/aidl/generate_cpp.cpp b/aidl/generate_cpp.cpp
new file mode 100644
index 0000000..41e9fb4
--- /dev/null
+++ b/aidl/generate_cpp.cpp
@@ -0,0 +1,858 @@
+/*
+ * 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 "generate_cpp.h"
+
+#include <cctype>
+#include <cstring>
+#include <memory>
+#include <random>
+#include <set>
+#include <string>
+
+#include <android-base/stringprintf.h>
+
+#include "aidl_language.h"
+#include "ast_cpp.h"
+#include "code_writer.h"
+#include "logging.h"
+#include "os.h"
+
+using android::base::StringPrintf;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+using std::set;
+
+namespace android {
+namespace aidl {
+namespace cpp {
+namespace internals {
+namespace {
+
+const char kAndroidStatusVarName[] = "_aidl_ret_status";
+const char kCodeVarName[] = "_aidl_code";
+const char kFlagsVarName[] = "_aidl_flags";
+const char kDataVarName[] = "_aidl_data";
+const char kErrorLabel[] = "_aidl_error";
+const char kImplVarName[] = "_aidl_impl";
+const char kReplyVarName[] = "_aidl_reply";
+const char kReturnVarName[] = "_aidl_return";
+const char kStatusVarName[] = "_aidl_status";
+const char kAndroidParcelLiteral[] = "::android::Parcel";
+const char kAndroidStatusLiteral[] = "::android::status_t";
+const char kAndroidStatusOk[] = "::android::OK";
+const char kBinderStatusLiteral[] = "::android::binder::Status";
+const char kIBinderHeader[] = "binder/IBinder.h";
+const char kIInterfaceHeader[] = "binder/IInterface.h";
+const char kParcelHeader[] = "binder/Parcel.h";
+const char kStatusHeader[] = "binder/Status.h";
+const char kString16Header[] = "utils/String16.h";
+const char kStrongPointerHeader[] = "utils/StrongPointer.h";
+
+unique_ptr<AstNode> BreakOnStatusNotOk() {
+  IfStatement* ret = new IfStatement(new Comparison(
+      new LiteralExpression(kAndroidStatusVarName), "!=",
+      new LiteralExpression(kAndroidStatusOk)));
+  ret->OnTrue()->AddLiteral("break");
+  return unique_ptr<AstNode>(ret);
+}
+
+unique_ptr<AstNode> GotoErrorOnBadStatus() {
+  IfStatement* ret = new IfStatement(new Comparison(
+      new LiteralExpression(kAndroidStatusVarName), "!=",
+      new LiteralExpression(kAndroidStatusOk)));
+  ret->OnTrue()->AddLiteral(StringPrintf("goto %s", kErrorLabel));
+  return unique_ptr<AstNode>(ret);
+}
+
+
+unique_ptr<AstNode> ReturnOnStatusNotOk() {
+  IfStatement* ret = new IfStatement(new Comparison(
+      new LiteralExpression(kAndroidStatusVarName), "!=",
+      new LiteralExpression(kAndroidStatusOk)));
+  ret->OnTrue()->AddLiteral(StringPrintf("return %s", kAndroidStatusVarName));
+  return unique_ptr<AstNode>(ret);
+}
+
+string UpperCase(const std::string& s) {
+  string result = s;
+  for (char& c : result)
+    c = toupper(c);
+  return result;
+}
+
+string BuildVarName(const AidlArgument& a) {
+  string prefix = "out_";
+  if (a.GetDirection() & AidlArgument::IN_DIR) {
+    prefix = "in_";
+  }
+  return prefix + a.GetName();
+}
+
+ArgList BuildArgList(const TypeNamespace& types,
+                     const AidlMethod& method,
+                     bool for_declaration) {
+  // 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 types, pointers to out params, and variable
+      // names that match the .aidl specification.
+      const Type* type = a->GetType().GetLanguageType<Type>();
+
+      literal = type->CppType();
+
+      if (a->IsOut()) {
+        literal = literal + "*";
+      } else {
+        // We pass in parameters that are not primitives by const reference.
+        // Arrays of primitives are not primitives.
+        if (!type->IsCppPrimitive() || a->GetType().IsArray()) {
+          literal = "const " + literal + "&";
+        }
+      }
+
+      literal += " " + a->GetName();
+    } else {
+      if (a->IsOut()) { literal = "&"; }
+      literal += BuildVarName(*a);
+    }
+    method_arguments.push_back(literal);
+  }
+
+  const Type* return_type = method.GetType().GetLanguageType<Type>();
+
+  if (return_type != types.VoidType()) {
+    string literal;
+    if (for_declaration) {
+      literal = StringPrintf(
+          "%s* %s", return_type->CppType().c_str(),
+          kReturnVarName);
+    } else {
+      literal = string{"&"} + kReturnVarName;
+    }
+    method_arguments.push_back(literal);
+  }
+
+  return ArgList(method_arguments);
+}
+
+unique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method,
+                                        const TypeNamespace& types,
+                                        bool for_interface) {
+  uint32_t modifiers = 0;
+  if (for_interface) {
+    modifiers |= MethodDecl::IS_VIRTUAL;
+    modifiers |= MethodDecl::IS_PURE_VIRTUAL;
+  } else {
+    modifiers |= MethodDecl::IS_OVERRIDE;
+  }
+
+  return unique_ptr<Declaration>{
+      new MethodDecl{kBinderStatusLiteral,
+                     method.GetName(),
+                     BuildArgList(types, method, true /* for method decl */),
+                     modifiers}};
+}
+
+unique_ptr<CppNamespace> NestInNamespaces(
+    vector<unique_ptr<Declaration>> decls,
+    const vector<string>& package) {
+  if (package.empty()) {
+    // We should also be checking this before we get this far, but do it again
+    // for the sake of unit tests and meaningful errors.
+    LOG(FATAL) << "C++ generation requires a package declaration "
+                  "for namespacing";
+  }
+  auto it = package.crbegin();  // Iterate over the namespaces inner to outer
+  unique_ptr<CppNamespace> inner{new CppNamespace{*it, std::move(decls)}};
+  ++it;
+  for (; it != package.crend(); ++it) {
+    inner.reset(new CppNamespace{*it, std::move(inner)});
+  }
+  return inner;
+}
+
+unique_ptr<CppNamespace> NestInNamespaces(unique_ptr<Declaration> decl,
+                                          const vector<string>& package) {
+  vector<unique_ptr<Declaration>> decls;
+  decls.push_back(std::move(decl));
+  return NestInNamespaces(std::move(decls), package);
+}
+
+bool DeclareLocalVariable(const TypeNamespace& types, 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;
+}
+
+string ClassName(const AidlInterface& interface, ClassNames type) {
+  string c_name = interface.GetName();
+
+  if (c_name.length() >= 2 && c_name[0] == 'I' && isupper(c_name[1]))
+    c_name = c_name.substr(1);
+
+  switch (type) {
+    case ClassNames::CLIENT:
+      c_name = "Bp" + c_name;
+      break;
+    case ClassNames::SERVER:
+      c_name = "Bn" + c_name;
+      break;
+    case ClassNames::INTERFACE:
+      c_name = "I" + c_name;
+      break;
+    case ClassNames::BASE:
+      break;
+  }
+  return c_name;
+}
+
+string BuildHeaderGuard(const AidlInterface& interface,
+                        ClassNames header_type) {
+  string class_name = ClassName(interface, header_type);
+  for (size_t i = 1; i < class_name.size(); ++i) {
+    if (isupper(class_name[i])) {
+      class_name.insert(i, "_");
+      ++i;
+    }
+  }
+  string ret = StringPrintf("AIDL_GENERATED_%s_%s_H_",
+                            interface.GetPackage().c_str(),
+                            class_name.c_str());
+  for (char& c : ret) {
+    if (c == '.') {
+      c = '_';
+    }
+    c = toupper(c);
+  }
+  return ret;
+}
+
+unique_ptr<Declaration> DefineClientTransaction(const TypeNamespace& types,
+                                                const AidlInterface& interface,
+                                                const AidlMethod& method) {
+  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(types, method, true /* for method decl */)}}};
+  StatementBlock* b = ret->GetStatementBlock();
+
+  // Declare parcels to hold our query and the response.
+  b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kDataVarName));
+  // Even if we're oneway, the transact method still takes a parcel.
+  b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kReplyVarName));
+
+  // Declare the status_t variable we need for error handling.
+  b->AddLiteral(StringPrintf("%s %s = %s", kAndroidStatusLiteral,
+                             kAndroidStatusVarName,
+                             kAndroidStatusOk));
+  // We unconditionally return a Status object.
+  b->AddLiteral(StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName));
+
+  // Add the name of the interface we're hoping to call.
+  b->AddStatement(new Assignment(
+      kAndroidStatusVarName,
+      new MethodCall(StringPrintf("%s.writeInterfaceToken",
+                                  kDataVarName),
+                     "getInterfaceDescriptor()")));
+  b->AddStatement(GotoErrorOnBadStatus());
+
+  for (const auto& a: method.GetArguments()) {
+    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 = 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.
+      //     _aidl_ret_status = _aidl_data.writeVectorSize(&out_param_name);
+      //     if (_aidl_ret_status != ::android::OK) { goto error; }
+      b->AddStatement(new Assignment(
+          kAndroidStatusVarName,
+          new MethodCall(StringPrintf("%s.writeVectorSize", kDataVarName),
+                         ArgList(var_name))));
+      b->AddStatement(GotoErrorOnBadStatus());
+    }
+  }
+
+  // Invoke the transaction on the remote binder and confirm status.
+  string transaction_code = StringPrintf(
+      "%s::%s", i_name.c_str(), UpperCase(method.GetName()).c_str());
+
+  vector<string> args = {transaction_code, kDataVarName,
+                         StringPrintf("&%s", kReplyVarName)};
+
+  if (interface.IsOneway() || method.IsOneway()) {
+    args.push_back("::android::IBinder::FLAG_ONEWAY");
+  }
+
+  b->AddStatement(new Assignment(
+      kAndroidStatusVarName,
+      new MethodCall("remote()->transact",
+                     ArgList(args))));
+  b->AddStatement(GotoErrorOnBadStatus());
+
+  if (!interface.IsOneway() && !method.IsOneway()) {
+    // Strip off the exception header and fail if we see a remote exception.
+    // _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+    // if (_aidl_ret_status != ::android::OK) { goto error; }
+    // if (!_aidl_status.isOk()) { return _aidl_ret_status; }
+    b->AddStatement(new Assignment(
+        kAndroidStatusVarName,
+        StringPrintf("%s.readFromParcel(%s)", kStatusVarName, kReplyVarName)));
+    b->AddStatement(GotoErrorOnBadStatus());
+    IfStatement* exception_check = new IfStatement(
+        new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName)));
+    b->AddStatement(exception_check);
+    exception_check->OnTrue()->AddLiteral(
+        StringPrintf("return %s", kStatusVarName));
+  }
+
+  // Type checking should guarantee that nothing below emits code until "return
+  // 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.
+  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()),
+                       ArgList(kReturnVarName))));
+    b->AddStatement(GotoErrorOnBadStatus());
+  }
+
+  for (const AidlArgument* a : method.GetOutArguments()) {
+    // Deserialization looks roughly like:
+    //     _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name);
+    //     if (_aidl_status != ::android::OK) { goto _aidl_error; }
+    string method =
+      a->GetType().GetLanguageType<Type>()->ReadFromParcelMethod();
+
+    b->AddStatement(new Assignment(
+        kAndroidStatusVarName,
+        new MethodCall(StringPrintf("%s.%s", kReplyVarName,
+                                    method.c_str()),
+                       ArgList(a->GetName()))));
+    b->AddStatement(GotoErrorOnBadStatus());
+  }
+
+  // If we've gotten to here, one of two things is true:
+  //   1) We've read some bad status_t
+  //   2) We've only read status_t == OK and there was no exception in the
+  //      response.
+  // In both cases, we're free to set Status from the status_t and return.
+  b->AddLiteral(StringPrintf("%s:\n", kErrorLabel), false /* no semicolon */);
+  b->AddLiteral(
+      StringPrintf("%s.setFromStatusT(%s)", kStatusVarName,
+                   kAndroidStatusVarName));
+  b->AddLiteral(StringPrintf("return %s", kStatusVarName));
+
+  return unique_ptr<Declaration>(ret.release());
+}
+
+}  // namespace
+
+unique_ptr<Document> BuildClientSource(const TypeNamespace& types,
+                                       const AidlInterface& interface) {
+  vector<string> include_list = {
+      HeaderFile(interface, ClassNames::CLIENT, false),
+      kParcelHeader
+  };
+  vector<unique_ptr<Declaration>> file_decls;
+
+  // The constructor just passes the IBinder instance up to the super
+  // class.
+  const string i_name = ClassName(interface, ClassNames::INTERFACE);
+  file_decls.push_back(unique_ptr<Declaration>{new ConstructorImpl{
+      ClassName(interface, ClassNames::CLIENT),
+      ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s",
+                           kImplVarName)},
+      { "BpInterface<" + i_name + ">(" + kImplVarName + ")" }}});
+
+  // Clients define a method per transaction.
+  for (const auto& method : interface.GetMethods()) {
+    unique_ptr<Declaration> m = DefineClientTransaction(
+        types, interface, *method);
+    if (!m) { return nullptr; }
+    file_decls.push_back(std::move(m));
+  }
+  return unique_ptr<Document>{new CppSource{
+      include_list,
+      NestInNamespaces(std::move(file_decls), interface.GetSplitPackage())}};
+}
+
+namespace {
+
+bool HandleServerTransaction(const TypeNamespace& types,
+                             const AidlMethod& method,
+                             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(types, *a, b)) { return false; }
+  }
+
+  // Declare a variable to hold the return value.
+  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.
+  IfStatement* interface_check = new IfStatement(
+      new MethodCall(StringPrintf("%s.checkInterface",
+                                  kDataVarName), "this"),
+      true /* invert the check */);
+  b->AddStatement(interface_check);
+  interface_check->OnTrue()->AddStatement(
+      new Assignment(kAndroidStatusVarName, "::android::BAD_TYPE"));
+  interface_check->OnTrue()->AddLiteral("break");
+
+  // Deserialize each "in" parameter to the transaction.
+  for (const auto& a: method.GetArguments()) {
+    // Deserialization looks roughly like:
+    //     _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name);
+    //     if (_aidl_ret_status != ::android::OK) { break; }
+    const Type* type = a->GetType().GetLanguageType<Type>();
+    const string& readMethod = type->ReadFromParcelMethod();
+
+    if (a->IsIn()) {
+      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",
+                         "&" + BuildVarName(*a)}});
+      b->AddStatement(BreakOnStatusNotOk());
+    }
+  }
+
+  // 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(types, method, false /* not for method decl */)));
+  b->AddStatement(new Statement(new MethodCall(
+      StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName),
+      ArgList(std::move(status_args)))));
+
+  // Write exceptions during transaction handling to parcel.
+  if (!method.IsOneway()) {
+    b->AddStatement(new Assignment(
+        kAndroidStatusVarName,
+        StringPrintf("%s.writeToParcel(%s)", kStatusVarName, kReplyVarName)));
+    b->AddStatement(BreakOnStatusNotOk());
+    IfStatement* exception_check = new IfStatement(
+        new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName)));
+    b->AddStatement(exception_check);
+    exception_check->OnTrue()->AddLiteral("break");
+  }
+
+  // If we have a return value, write it first.
+  if (return_type != types.VoidType()) {
+    string writeMethod =
+        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.
+  for (const AidlArgument* a : method.GetOutArguments()) {
+    // Serialization looks roughly like:
+    //     _aidl_ret_status = data.WriteInt32(out_param_name);
+    //     if (_aidl_ret_status != ::android::OK) { break; }
+    const Type* type = a->GetType().GetLanguageType<Type>();
+    const string& writeMethod = type->WriteToParcelMethod();
+
+    b->AddStatement(new Assignment{
+        kAndroidStatusVarName,
+        new MethodCall{string(kReplyVarName) + "->" + writeMethod,
+                       type->WriteCast(BuildVarName(*a))}});
+    b->AddStatement(BreakOnStatusNotOk());
+  }
+
+  return true;
+}
+
+}  // namespace
+
+unique_ptr<Document> BuildServerSource(const TypeNamespace& types,
+                                       const AidlInterface& interface) {
+  const string bn_name = ClassName(interface, ClassNames::SERVER);
+  vector<string> include_list{
+      HeaderFile(interface, ClassNames::SERVER, false),
+      kParcelHeader
+  };
+  unique_ptr<MethodImpl> on_transact{new MethodImpl{
+      kAndroidStatusLiteral, bn_name, "onTransact",
+      ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
+               StringPrintf("const %s& %s", kAndroidParcelLiteral,
+                            kDataVarName),
+               StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName),
+               StringPrintf("uint32_t %s", kFlagsVarName)}}
+      }};
+
+  // Declare the status_t variable
+  on_transact->GetStatementBlock()->AddLiteral(
+      StringPrintf("%s %s = %s", kAndroidStatusLiteral, kAndroidStatusVarName,
+                   kAndroidStatusOk));
+
+  // Add the all important switch statement, but retain a pointer to it.
+  SwitchStatement* s = new SwitchStatement{kCodeVarName};
+  on_transact->GetStatementBlock()->AddStatement(s);
+
+  // The switch statement has a case statement for each transaction code.
+  for (const auto& method : interface.GetMethods()) {
+    StatementBlock* b = s->AddCase("Call::" + UpperCase(method->GetName()));
+    if (!b) { return nullptr; }
+
+    if (!HandleServerTransaction(types, *method, b)) { return nullptr; }
+  }
+
+  // The switch statement has a default case which defers to the super class.
+  // The superclass handles a few pre-defined transactions.
+  StatementBlock* b = s->AddCase("");
+  b->AddLiteral(StringPrintf(
+                "%s = ::android::BBinder::onTransact(%s, %s, "
+                "%s, %s)", kAndroidStatusVarName, kCodeVarName,
+                kDataVarName, kReplyVarName, kFlagsVarName));
+
+  // If we saw a null reference, we can map that to an appropriate exception.
+  IfStatement* null_check = new IfStatement(
+      new LiteralExpression(string(kAndroidStatusVarName) +
+                            " == ::android::UNEXPECTED_NULL"));
+  on_transact->GetStatementBlock()->AddStatement(null_check);
+  null_check->OnTrue()->AddStatement(new Assignment(
+      kAndroidStatusVarName,
+      StringPrintf("%s::fromExceptionCode(%s::EX_NULL_POINTER)"
+                   ".writeToParcel(%s)",
+                   kBinderStatusLiteral, kBinderStatusLiteral,
+                   kReplyVarName)));
+
+  // Finally, the server's onTransact method just returns a status code.
+  on_transact->GetStatementBlock()->AddLiteral(
+      StringPrintf("return %s", kAndroidStatusVarName));
+
+  return unique_ptr<Document>{new CppSource{
+      include_list,
+      NestInNamespaces(std::move(on_transact), interface.GetSplitPackage())}};
+}
+
+unique_ptr<Document> BuildInterfaceSource(const TypeNamespace& /* types */,
+                                          const AidlInterface& interface) {
+  vector<string> include_list{
+      HeaderFile(interface, ClassNames::INTERFACE, false),
+      HeaderFile(interface, ClassNames::CLIENT, false),
+  };
+
+  string fq_name = ClassName(interface, ClassNames::INTERFACE);
+  if (!interface.GetPackage().empty()) {
+    fq_name = interface.GetPackage() + "." + fq_name;
+  }
+
+  vector<unique_ptr<Declaration>> decls;
+
+  unique_ptr<MacroDecl> meta_if{new MacroDecl{
+      "IMPLEMENT_META_INTERFACE",
+      ArgList{vector<string>{ClassName(interface, ClassNames::BASE),
+                             '"' + fq_name + '"'}}}};
+  decls.push_back(std::move(meta_if));
+
+  for (const auto& constant: interface.GetStringConstants()) {
+    unique_ptr<MethodImpl> getter(new MethodImpl(
+        "const ::android::String16&",
+        ClassName(interface, ClassNames::INTERFACE),
+        constant->GetName(),
+        {}));
+    getter->GetStatementBlock()->AddLiteral(
+        StringPrintf("static const ::android::String16 value(%s)",
+                     constant->GetValue().c_str()));
+    getter->GetStatementBlock()->AddLiteral("return value");
+    decls.push_back(std::move(getter));
+  }
+
+  return unique_ptr<Document>{new CppSource{
+      include_list,
+      NestInNamespaces(std::move(decls), interface.GetSplitPackage())}};
+}
+
+unique_ptr<Document> BuildClientHeader(const TypeNamespace& types,
+                                       const AidlInterface& interface) {
+  const string i_name = ClassName(interface, ClassNames::INTERFACE);
+  const string bp_name = ClassName(interface, ClassNames::CLIENT);
+
+  unique_ptr<ConstructorDecl> constructor{new ConstructorDecl{
+      bp_name,
+      ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s",
+                           kImplVarName)},
+      ConstructorDecl::IS_EXPLICIT
+  }};
+  unique_ptr<ConstructorDecl> destructor{new ConstructorDecl{
+      "~" + bp_name,
+      ArgList{},
+      ConstructorDecl::IS_VIRTUAL | ConstructorDecl::IS_DEFAULT}};
+
+  vector<unique_ptr<Declaration>> publics;
+  publics.push_back(std::move(constructor));
+  publics.push_back(std::move(destructor));
+
+  for (const auto& method: interface.GetMethods()) {
+    publics.push_back(BuildMethodDecl(*method, types, false));
+  }
+
+  unique_ptr<ClassDecl> bp_class{
+      new ClassDecl{bp_name,
+                    "::android::BpInterface<" + i_name + ">",
+                    std::move(publics),
+                    {}
+      }};
+
+  return unique_ptr<Document>{new CppHeader{
+      BuildHeaderGuard(interface, ClassNames::CLIENT),
+      {kIBinderHeader,
+       kIInterfaceHeader,
+       "utils/Errors.h",
+       HeaderFile(interface, ClassNames::INTERFACE, false)},
+      NestInNamespaces(std::move(bp_class), interface.GetSplitPackage())}};
+}
+
+unique_ptr<Document> BuildServerHeader(const TypeNamespace& /* types */,
+                                       const AidlInterface& interface) {
+  const string i_name = ClassName(interface, ClassNames::INTERFACE);
+  const string bn_name = ClassName(interface, ClassNames::SERVER);
+
+  unique_ptr<Declaration> on_transact{new MethodDecl{
+      kAndroidStatusLiteral, "onTransact",
+      ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
+               StringPrintf("const %s& %s", kAndroidParcelLiteral,
+                            kDataVarName),
+               StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName),
+               StringPrintf("uint32_t %s = 0", kFlagsVarName)}},
+      MethodDecl::IS_OVERRIDE
+  }};
+
+  std::vector<unique_ptr<Declaration>> publics;
+  publics.push_back(std::move(on_transact));
+
+  unique_ptr<ClassDecl> bn_class{
+      new ClassDecl{bn_name,
+                    "::android::BnInterface<" + i_name + ">",
+                    std::move(publics),
+                    {}
+      }};
+
+  return unique_ptr<Document>{new CppHeader{
+      BuildHeaderGuard(interface, ClassNames::SERVER),
+      {"binder/IInterface.h",
+       HeaderFile(interface, ClassNames::INTERFACE, false)},
+      NestInNamespaces(std::move(bn_class), interface.GetSplitPackage())}};
+}
+
+unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types,
+                                          const AidlInterface& interface) {
+  set<string> includes = { kIBinderHeader, kIInterfaceHeader,
+                           kStatusHeader, kStrongPointerHeader };
+
+  for (const auto& method : interface.GetMethods()) {
+    for (const auto& argument : method->GetArguments()) {
+      const Type* type = argument->GetType().GetLanguageType<Type>();
+      type->GetHeaders(&includes);
+    }
+
+    const Type* return_type = method->GetType().GetLanguageType<Type>();
+    return_type->GetHeaders(&includes);
+  }
+
+  unique_ptr<ClassDecl> if_class{
+      new ClassDecl{ClassName(interface, ClassNames::INTERFACE),
+                    "::android::IInterface"}};
+  if_class->AddPublic(unique_ptr<Declaration>{new MacroDecl{
+      "DECLARE_META_INTERFACE",
+      ArgList{vector<string>{ClassName(interface, ClassNames::BASE)}}}});
+
+  unique_ptr<Enum> constant_enum{new Enum{"", "int32_t"}};
+  for (const auto& constant : interface.GetIntConstants()) {
+    constant_enum->AddValue(
+        constant->GetName(), std::to_string(constant->GetValue()));
+  }
+  if (constant_enum->HasValues()) {
+    if_class->AddPublic(std::move(constant_enum));
+  }
+
+  if (!interface.GetStringConstants().empty()) {
+    includes.insert(kString16Header);
+  }
+  for (const auto& constant : interface.GetStringConstants()) {
+    unique_ptr<MethodDecl> getter(new MethodDecl(
+          "const ::android::String16&", constant->GetName(),
+          {}, MethodDecl::IS_STATIC));
+    if_class->AddPublic(std::move(getter));
+  }
+
+  if (!interface.GetMethods().empty()) {
+    unique_ptr<Enum> call_enum{new Enum{"Call"}};
+    for (const auto& method : interface.GetMethods()) {
+      // Each method gets an enum entry and pure virtual declaration.
+      if_class->AddPublic(BuildMethodDecl(*method, types, true));
+      call_enum->AddValue(
+          UpperCase(method->GetName()),
+          StringPrintf("::android::IBinder::FIRST_CALL_TRANSACTION + %d",
+                       method->GetId()));
+    }
+    if_class->AddPublic(std::move(call_enum));
+  }
+
+  return unique_ptr<Document>{new CppHeader{
+      BuildHeaderGuard(interface, ClassNames::INTERFACE),
+      vector<string>(includes.begin(), includes.end()),
+      NestInNamespaces(std::move(if_class), interface.GetSplitPackage())}};
+}
+
+bool WriteHeader(const CppOptions& 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(types, interface);
+      break;
+    case ClassNames::CLIENT:
+      header = BuildClientHeader(types, interface);
+      break;
+    case ClassNames::SERVER:
+      header = BuildServerHeader(types, interface);
+      break;
+    default:
+      LOG(FATAL) << "aidl internal error";
+  }
+  if (!header) {
+    LOG(ERROR) << "aidl internal error: Failed to generate header.";
+    return false;
+  }
+
+  const string header_path = options.OutputHeaderDir() + OS_PATH_SEPARATOR +
+                             HeaderFile(interface, header_type);
+  unique_ptr<CodeWriter> code_writer(io_delegate.GetCodeWriter(header_path));
+  header->Write(code_writer.get());
+
+  const bool success = code_writer->Close();
+  if (!success) {
+    io_delegate.RemovePath(header_path);
+  }
+
+  return success;
+}
+
+}  // namespace internals
+
+using namespace internals;
+
+string HeaderFile(const AidlInterface& interface,
+                  ClassNames class_type,
+                  bool use_os_sep) {
+  string file_path = interface.GetPackage();
+  for (char& c: file_path) {
+    if (c == '.') {
+      c = (use_os_sep) ? OS_PATH_SEPARATOR : '/';
+    }
+  }
+  if (!file_path.empty()) {
+    file_path += (use_os_sep) ? OS_PATH_SEPARATOR : '/';
+  }
+  file_path += ClassName(interface, class_type);
+  file_path += ".h";
+
+  return file_path;
+}
+
+bool GenerateCpp(const CppOptions& options,
+                 const TypeNamespace& types,
+                 const AidlInterface& interface,
+                 const IoDelegate& io_delegate) {
+  auto interface_src = BuildInterfaceSource(types, interface);
+  auto client_src = BuildClientSource(types, interface);
+  auto server_src = BuildServerSource(types, interface);
+
+  if (!interface_src || !client_src || !server_src) {
+    return false;
+  }
+
+  if (!io_delegate.CreatedNestedDirs(options.OutputHeaderDir(),
+                                     interface.GetSplitPackage())) {
+    LOG(ERROR) << "Failed to create directory structure for headers.";
+    return false;
+  }
+
+  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;
+  }
+
+  unique_ptr<CodeWriter> writer = io_delegate.GetCodeWriter(
+      options.OutputCppFilePath());
+  interface_src->Write(writer.get());
+  client_src->Write(writer.get());
+  server_src->Write(writer.get());
+
+  const bool success = writer->Close();
+  if (!success) {
+    io_delegate.RemovePath(options.OutputCppFilePath());
+  }
+
+  return success;
+}
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/generate_cpp.h b/aidl/generate_cpp.h
new file mode 100644
index 0000000..1ffc681
--- /dev/null
+++ b/aidl/generate_cpp.h
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_GENERATE_CPP_H_
+#define AIDL_GENERATE_CPP_H_
+
+#include <memory>
+#include <string>
+
+#include "aidl_language.h"
+#include "ast_cpp.h"
+#include "options.h"
+#include "type_cpp.h"
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+bool GenerateCpp(const CppOptions& options,
+                 const cpp::TypeNamespace& types,
+                 const AidlInterface& parsed_doc,
+                 const IoDelegate& io_delegate);
+
+// These roughly correspond to the various class names in the C++ hierarchy:
+enum class ClassNames {
+  BASE,       // Foo (not a real class, but useful in some circumstances).
+  CLIENT,     // BpFoo
+  SERVER,     // BnFoo
+  INTERFACE,  // IFoo
+};
+
+// Generate the relative path to a header file.  If |use_os_sep| we'll use the
+// operating system specific path separator rather than C++'s expected '/' when
+// including headers.
+std::string HeaderFile(const AidlInterface& interface, ClassNames class_type,
+                       bool use_os_sep = true);
+
+namespace internals {
+std::unique_ptr<Document> BuildClientSource(const TypeNamespace& types,
+                                            const AidlInterface& parsed_doc);
+std::unique_ptr<Document> BuildServerSource(const TypeNamespace& types,
+                                            const AidlInterface& parsed_doc);
+std::unique_ptr<Document> BuildInterfaceSource(const TypeNamespace& types,
+                                               const AidlInterface& parsed_doc);
+std::unique_ptr<Document> BuildClientHeader(const TypeNamespace& types,
+                                            const AidlInterface& parsed_doc);
+std::unique_ptr<Document> BuildServerHeader(const TypeNamespace& types,
+                                            const AidlInterface& parsed_doc);
+std::unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types,
+                                               const AidlInterface& parsed_doc);
+}
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
+
+#endif // AIDL_GENERATE_CPP_H_
diff --git a/aidl/generate_cpp_unittest.cpp b/aidl/generate_cpp_unittest.cpp
new file mode 100644
index 0000000..50bfd9c
--- /dev/null
+++ b/aidl/generate_cpp_unittest.cpp
@@ -0,0 +1,888 @@
+/*
+ * 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 <string>
+
+#include <android-base/stringprintf.h>
+#include <gtest/gtest.h>
+
+#include "aidl.h"
+#include "aidl_language.h"
+#include "ast_cpp.h"
+#include "code_writer.h"
+#include "generate_cpp.h"
+#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;
+using std::string;
+using std::unique_ptr;
+
+namespace android {
+namespace aidl {
+namespace cpp {
+namespace {
+
+const string kComplexTypeInterfaceAIDL =
+R"(package android.os;
+import foo.IFooType;
+interface IComplexTypeInterface {
+  const int MY_CONSTANT = 3;
+  int[] Send(in @nullable int[] goes_in, inout double[] goes_in_and_out, out boolean[] goes_out);
+  oneway void Piff(int times);
+  IFooType TakesABinder(IFooType f);
+  @nullable IFooType NullableBinder();
+  List<String> StringListMethod(in java.util.List<String> input, out List<String> output);
+  List<IBinder> BinderListMethod(in java.util.List<IBinder> input, out List<IBinder> output);
+  FileDescriptor TakesAFileDescriptor(in FileDescriptor f);
+  FileDescriptor[] TakesAFileDescriptorArray(in FileDescriptor[] f);
+})";
+
+const char kExpectedComplexTypeClientHeaderOutput[] =
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_
+#define AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_
+
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <utils/Errors.h>
+#include <android/os/IComplexTypeInterface.h>
+
+namespace android {
+
+namespace os {
+
+class BpComplexTypeInterface : public ::android::BpInterface<IComplexTypeInterface> {
+public:
+explicit BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl);
+virtual ~BpComplexTypeInterface() = default;
+::android::binder::Status Send(const ::std::unique_ptr<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) override;
+::android::binder::Status Piff(int32_t times) override;
+::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) override;
+::android::binder::Status NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) override;
+::android::binder::Status StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) override;
+::android::binder::Status BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>& input, ::std::vector<::android::sp<::android::IBinder>>* output, ::std::vector<::android::sp<::android::IBinder>>* _aidl_return) override;
+::android::binder::Status TakesAFileDescriptor(const ::android::base::unique_fd& f, ::android::base::unique_fd* _aidl_return) override;
+::android::binder::Status TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) override;
+};  // class BpComplexTypeInterface
+
+}  // namespace os
+
+}  // namespace android
+
+#endif  // AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_
+)";
+
+const char kExpectedComplexTypeClientSourceOutput[] =
+R"(#include <android/os/BpComplexTypeInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+namespace os {
+
+BpComplexTypeInterface::BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl)
+    : BpInterface<IComplexTypeInterface>(_aidl_impl){
+}
+
+::android::binder::Status BpComplexTypeInterface::Send(const ::std::unique_ptr<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeInt32Vector(goes_in);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeDoubleVector(*goes_in_and_out);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeVectorSize(*goes_out);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IComplexTypeInterface::SEND, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readInt32Vector(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_reply.readDoubleVector(goes_in_and_out);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_reply.readBoolVector(goes_out);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpComplexTypeInterface::Piff(int32_t times) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeInt32(times);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IComplexTypeInterface::PIFF, _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpComplexTypeInterface::TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeStrongBinder(::foo::IFooType::asBinder(f));
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESABINDER, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readStrongBinder(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpComplexTypeInterface::NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IComplexTypeInterface::NULLABLEBINDER, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpComplexTypeInterface::StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeString16Vector(input);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IComplexTypeInterface::STRINGLISTMETHOD, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readString16Vector(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_reply.readString16Vector(output);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpComplexTypeInterface::BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>& input, ::std::vector<::android::sp<::android::IBinder>>* output, ::std::vector<::android::sp<::android::IBinder>>* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeStrongBinderVector(input);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IComplexTypeInterface::BINDERLISTMETHOD, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readStrongBinderVector(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_reply.readStrongBinderVector(output);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptor(const ::android::base::unique_fd& f, ::android::base::unique_fd* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeUniqueFileDescriptor(f);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESAFILEDESCRIPTOR, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readUniqueFileDescriptor(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeUniqueFileDescriptorVector(f);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESAFILEDESCRIPTORARRAY, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readUniqueFileDescriptorVector(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+}  // namespace os
+
+}  // namespace android
+)";
+
+const char kExpectedComplexTypeServerHeaderOutput[] =
+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>
+#include <android/os/IComplexTypeInterface.h>
+
+namespace android {
+
+namespace os {
+
+class BnComplexTypeInterface : public ::android::BnInterface<IComplexTypeInterface> {
+public:
+::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags = 0) override;
+};  // class BnComplexTypeInterface
+
+}  // namespace os
+
+}  // namespace android
+
+#endif  // AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_
+)";
+
+const char kExpectedComplexTypeServerSourceOutput[] =
+R"(#include <android/os/BnComplexTypeInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+namespace os {
+
+::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) {
+case Call::SEND:
+{
+::std::unique_ptr<::std::vector<int32_t>> in_goes_in;
+::std::vector<double> in_goes_in_and_out;
+::std::vector<bool> out_goes_out;
+::std::vector<int32_t> _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readInt32Vector(&in_goes_in);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+_aidl_ret_status = _aidl_data.readDoubleVector(&in_goes_in_and_out);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+_aidl_ret_status = _aidl_data.resizeOutVector(&out_goes_out);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(Send(in_goes_in, &in_goes_in_and_out, &out_goes_out, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeInt32Vector(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeDoubleVector(in_goes_in_and_out);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeBoolVector(out_goes_out);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+case Call::PIFF:
+{
+int32_t in_times;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readInt32(&in_times);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(Piff(in_times));
+}
+break;
+case Call::TAKESABINDER:
+{
+::android::sp<::foo::IFooType> in_f;
+::android::sp<::foo::IFooType> _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readStrongBinder(&in_f);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(TakesABinder(in_f, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return));
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+case Call::NULLABLEBINDER:
+{
+::android::sp<::foo::IFooType> _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+::android::binder::Status _aidl_status(NullableBinder(&_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return));
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+case Call::STRINGLISTMETHOD:
+{
+::std::vector<::android::String16> in_input;
+::std::vector<::android::String16> out_output;
+::std::vector<::android::String16> _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readString16Vector(&in_input);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(StringListMethod(in_input, &out_output, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeString16Vector(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeString16Vector(out_output);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+case Call::BINDERLISTMETHOD:
+{
+::std::vector<::android::sp<::android::IBinder>> in_input;
+::std::vector<::android::sp<::android::IBinder>> out_output;
+::std::vector<::android::sp<::android::IBinder>> _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readStrongBinderVector(&in_input);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(BinderListMethod(in_input, &out_output, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeStrongBinderVector(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeStrongBinderVector(out_output);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+case Call::TAKESAFILEDESCRIPTOR:
+{
+::android::base::unique_fd in_f;
+::android::base::unique_fd _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readUniqueFileDescriptor(&in_f);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(TakesAFileDescriptor(in_f, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptor(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+case Call::TAKESAFILEDESCRIPTORARRAY:
+{
+::std::vector<::android::base::unique_fd> in_f;
+::std::vector<::android::base::unique_fd> _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readUniqueFileDescriptorVector(&in_f);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(TakesAFileDescriptorArray(in_f, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptorVector(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+default:
+{
+_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
+}
+break;
+}
+if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
+_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
+}
+return _aidl_ret_status;
+}
+
+}  // namespace os
+
+}  // namespace android
+)";
+
+const char kExpectedComplexTypeInterfaceHeaderOutput[] =
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_
+#define AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_
+
+#include <android-base/unique_fd.h>
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <binder/Status.h>
+#include <cstdint>
+#include <foo/IFooType.h>
+#include <memory>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+#include <vector>
+
+namespace android {
+
+namespace os {
+
+class IComplexTypeInterface : public ::android::IInterface {
+public:
+DECLARE_META_INTERFACE(ComplexTypeInterface)
+enum  : int32_t {
+  MY_CONSTANT = 3,
+};
+virtual ::android::binder::Status Send(const ::std::unique_ptr<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) = 0;
+virtual ::android::binder::Status Piff(int32_t times) = 0;
+virtual ::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) = 0;
+virtual ::android::binder::Status NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) = 0;
+virtual ::android::binder::Status StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) = 0;
+virtual ::android::binder::Status BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>& input, ::std::vector<::android::sp<::android::IBinder>>* output, ::std::vector<::android::sp<::android::IBinder>>* _aidl_return) = 0;
+virtual ::android::binder::Status TakesAFileDescriptor(const ::android::base::unique_fd& f, ::android::base::unique_fd* _aidl_return) = 0;
+virtual ::android::binder::Status TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) = 0;
+enum Call {
+  SEND = ::android::IBinder::FIRST_CALL_TRANSACTION + 0,
+  PIFF = ::android::IBinder::FIRST_CALL_TRANSACTION + 1,
+  TAKESABINDER = ::android::IBinder::FIRST_CALL_TRANSACTION + 2,
+  NULLABLEBINDER = ::android::IBinder::FIRST_CALL_TRANSACTION + 3,
+  STRINGLISTMETHOD = ::android::IBinder::FIRST_CALL_TRANSACTION + 4,
+  BINDERLISTMETHOD = ::android::IBinder::FIRST_CALL_TRANSACTION + 5,
+  TAKESAFILEDESCRIPTOR = ::android::IBinder::FIRST_CALL_TRANSACTION + 6,
+  TAKESAFILEDESCRIPTORARRAY = ::android::IBinder::FIRST_CALL_TRANSACTION + 7,
+};
+};  // class IComplexTypeInterface
+
+}  // namespace os
+
+}  // namespace android
+
+#endif  // AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_
+)";
+
+const char kExpectedComplexTypeInterfaceSourceOutput[] =
+R"(#include <android/os/IComplexTypeInterface.h>
+#include <android/os/BpComplexTypeInterface.h>
+
+namespace android {
+
+namespace os {
+
+IMPLEMENT_META_INTERFACE(ComplexTypeInterface, "android.os.IComplexTypeInterface")
+
+}  // namespace os
+
+}  // namespace android
+)";
+
+}  // namespace
+
+class ASTTest : public ::testing::Test {
+ protected:
+  ASTTest(string file_path, string file_contents)
+      : file_path_(file_path),
+        file_contents_(file_contents) {
+    types_.Init();
+  }
+
+  unique_ptr<AidlInterface> Parse() {
+    io_delegate_.SetFileContents(file_path_, file_contents_);
+
+    unique_ptr<AidlInterface> ret;
+    std::vector<std::unique_ptr<AidlImport>> imports;
+    AidlError err = ::android::aidl::internals::load_and_validate_aidl(
+        {},  // no preprocessed files
+        {"."},
+        file_path_,
+        io_delegate_,
+        &types_,
+        &ret,
+        &imports);
+
+    if (err != AidlError::OK)
+      return nullptr;
+
+    return ret;
+  }
+
+  void Compare(Document* doc, const char* expected) {
+    string output;
+    unique_ptr<CodeWriter> cw = GetStringWriter(&output);
+
+    doc->Write(cw.get());
+
+    if (expected == output) {
+      return; // Success
+    }
+
+    test::PrintDiff(expected, output);
+    FAIL() << "Document contents did not match expected contents";
+  }
+
+  const string file_path_;
+  const string file_contents_;
+  FakeIoDelegate io_delegate_;
+  TypeNamespace types_;
+};
+
+class ComplexTypeInterfaceASTTest : public ASTTest {
+ public:
+  ComplexTypeInterfaceASTTest()
+      : ASTTest("android/os/IComplexTypeInterface.aidl",
+                kComplexTypeInterfaceAIDL) {
+    io_delegate_.SetFileContents("foo/IFooType.aidl",
+                                 "package foo; interface IFooType {}");
+  }
+};
+
+TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientHeader) {
+  unique_ptr<AidlInterface> interface = Parse();
+  ASSERT_NE(interface, nullptr);
+  unique_ptr<Document> doc = internals::BuildClientHeader(types_, *interface);
+  Compare(doc.get(), kExpectedComplexTypeClientHeaderOutput);
+}
+
+TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSource) {
+  unique_ptr<AidlInterface> interface = Parse();
+  ASSERT_NE(interface, nullptr);
+  unique_ptr<Document> doc = internals::BuildClientSource(types_, *interface);
+  Compare(doc.get(), kExpectedComplexTypeClientSourceOutput);
+}
+
+TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerHeader) {
+  unique_ptr<AidlInterface> interface = Parse();
+  ASSERT_NE(interface, nullptr);
+  unique_ptr<Document> doc = internals::BuildServerHeader(types_, *interface);
+  Compare(doc.get(), kExpectedComplexTypeServerHeaderOutput);
+}
+
+TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSource) {
+  unique_ptr<AidlInterface> interface = Parse();
+  ASSERT_NE(interface, nullptr);
+  unique_ptr<Document> doc = internals::BuildServerSource(types_, *interface);
+  Compare(doc.get(), kExpectedComplexTypeServerSourceOutput);
+}
+
+TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceHeader) {
+  unique_ptr<AidlInterface> interface = Parse();
+  ASSERT_NE(interface, nullptr);
+  unique_ptr<Document> doc = internals::BuildInterfaceHeader(types_, *interface);
+  Compare(doc.get(), kExpectedComplexTypeInterfaceHeaderOutput);
+}
+
+TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceSource) {
+  unique_ptr<AidlInterface> interface = Parse();
+  ASSERT_NE(interface, nullptr);
+  unique_ptr<Document> doc = internals::BuildInterfaceSource(types_, *interface);
+  Compare(doc.get(), kExpectedComplexTypeInterfaceSourceOutput);
+}
+
+namespace test_io_handling {
+
+const char kInputPath[] = "a/IFoo.aidl";
+const char kOutputPath[] = "output.cpp";
+const char kHeaderDir[] = "headers";
+const char kInterfaceHeaderRelPath[] = "a/IFoo.h";
+
+}  // namespace test_io_handling
+
+class IoErrorHandlingTest : public ASTTest {
+ public:
+  IoErrorHandlingTest ()
+      : ASTTest(test_io_handling::kInputPath,
+                "package a; interface IFoo {}"),
+        options_(GetOptions()) {}
+
+  const unique_ptr<CppOptions> options_;
+
+ private:
+  static unique_ptr<CppOptions> GetOptions() {
+    using namespace test_io_handling;
+
+    const int argc = 4;
+    const char* cmdline[argc] = {
+      "aidl-cpp", kInputPath, kHeaderDir, kOutputPath
+    };
+    return CppOptions::Parse(argc, cmdline);
+  }
+};
+
+TEST_F(IoErrorHandlingTest, GenerateCorrectlyAbsentErrors) {
+  // Confirm that this is working correctly without I/O problems.
+  const unique_ptr<AidlInterface> interface = Parse();
+  ASSERT_NE(interface, nullptr);
+  ASSERT_TRUE(GenerateCpp(*options_, types_, *interface, io_delegate_));
+}
+
+TEST_F(IoErrorHandlingTest, HandlesBadHeaderWrite) {
+  using namespace test_io_handling;
+  const unique_ptr<AidlInterface> interface = Parse();
+  ASSERT_NE(interface, nullptr);
+
+  // Simulate issues closing the interface header.
+  const string header_path =
+      StringPrintf("%s%c%s", kHeaderDir, OS_PATH_SEPARATOR,
+                   kInterfaceHeaderRelPath);
+  io_delegate_.AddBrokenFilePath(header_path);
+  ASSERT_FALSE(GenerateCpp(*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.
+  ASSERT_TRUE(io_delegate_.PathWasRemoved(header_path));
+}
+
+TEST_F(IoErrorHandlingTest, HandlesBadCppWrite) {
+  using test_io_handling::kOutputPath;
+  const unique_ptr<AidlInterface> interface = Parse();
+  ASSERT_NE(interface, nullptr);
+
+  // Simulate issues closing the cpp file.
+  io_delegate_.AddBrokenFilePath(kOutputPath);
+  ASSERT_FALSE(GenerateCpp(*options_, types_, *interface, io_delegate_));
+  // We should remove partial results.
+  ASSERT_TRUE(io_delegate_.PathWasRemoved(kOutputPath));
+}
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/generate_java.cpp b/aidl/generate_java.cpp
new file mode 100644
index 0000000..14df353
--- /dev/null
+++ b/aidl/generate_java.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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 "generate_java.h"
+
+#include <memory>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <android-base/stringprintf.h>
+
+#include "code_writer.h"
+#include "type_java.h"
+
+using std::unique_ptr;
+using ::android::aidl::java::Variable;
+using std::string;
+using android::base::StringPrintf;
+
+namespace android {
+namespace aidl {
+
+// =================================================
+VariableFactory::VariableFactory(const string& base)
+    : base_(base),
+      index_(0) {
+}
+
+Variable* VariableFactory::Get(const Type* type) {
+  Variable* v = new Variable(
+      type, StringPrintf("%s%d", base_.c_str(), index_));
+  vars_.push_back(v);
+  index_++;
+  return v;
+}
+
+Variable* VariableFactory::Get(int index) {
+  return vars_[index];
+}
+
+namespace java {
+
+int generate_java(const string& filename, const string& originalSrc,
+                  AidlInterface* iface, JavaTypeNamespace* types,
+                  const IoDelegate& io_delegate) {
+  Class* cl = generate_binder_interface_class(iface, types);
+
+  Document* document = new Document(
+      "" /* no comment */,
+      (!iface->GetPackage().empty()) ? iface->GetPackage() : "",
+      originalSrc,
+      unique_ptr<Class>(cl));
+
+  CodeWriterPtr code_writer = io_delegate.GetCodeWriter(filename);
+  document->Write(code_writer.get());
+
+  return 0;
+}
+
+}  // namespace java
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/generate_java.h b/aidl/generate_java.h
new file mode 100644
index 0000000..ed04ba1
--- /dev/null
+++ b/aidl/generate_java.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_GENERATE_JAVA_H_
+#define AIDL_GENERATE_JAVA_H_
+
+#include <string>
+
+#include "aidl_language.h"
+#include "ast_java.h"
+#include "io_delegate.h"
+
+namespace android {
+namespace aidl {
+
+namespace java {
+
+class JavaTypeNamespace;
+
+int generate_java(const std::string& filename, const std::string& originalSrc,
+                  AidlInterface* iface, java::JavaTypeNamespace* types,
+                  const IoDelegate& io_delegate);
+
+android::aidl::java::Class* generate_binder_interface_class(
+    const AidlInterface* iface, java::JavaTypeNamespace* types);
+
+}  // namespace java
+
+class VariableFactory {
+ public:
+  using Variable = ::android::aidl::java::Variable;
+  using Type = ::android::aidl::java::Type;
+
+  explicit VariableFactory(const std::string& base); // base must be short
+  Variable* Get(const Type* type);
+  Variable* Get(int index);
+
+ private:
+  std::vector<Variable*> vars_;
+  std::string base_;
+  int index_;
+
+  DISALLOW_COPY_AND_ASSIGN(VariableFactory);
+};
+
+}  // namespace android
+}  // namespace aidl
+
+#endif // AIDL_GENERATE_JAVA_H_
diff --git a/aidl/generate_java_binder.cpp b/aidl/generate_java_binder.cpp
new file mode 100644
index 0000000..02a6922
--- /dev/null
+++ b/aidl/generate_java_binder.cpp
@@ -0,0 +1,552 @@
+/*
+ * 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 "generate_java.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string.h>
+
+#include <android-base/macros.h>
+
+#include "type_java.h"
+
+using std::string;
+
+namespace android {
+namespace aidl {
+namespace java {
+
+// =================================================
+class StubClass : public Class {
+ public:
+  StubClass(const Type* type, const InterfaceType* interfaceType,
+            JavaTypeNamespace* types);
+  virtual ~StubClass() = default;
+
+  Variable* transact_code;
+  Variable* transact_data;
+  Variable* transact_reply;
+  Variable* transact_flags;
+  SwitchStatement* transact_switch;
+
+ private:
+  void make_as_interface(const InterfaceType* interfaceType,
+                         JavaTypeNamespace* types);
+
+  DISALLOW_COPY_AND_ASSIGN(StubClass);
+};
+
+StubClass::StubClass(const Type* type, const InterfaceType* interfaceType,
+                     JavaTypeNamespace* types)
+    : Class() {
+  this->comment = "/** Local-side IPC implementation stub class. */";
+  this->modifiers = PUBLIC | ABSTRACT | STATIC;
+  this->what = Class::CLASS;
+  this->type = type;
+  this->extends = types->BinderNativeType();
+  this->interfaces.push_back(interfaceType);
+
+  // descriptor
+  Field* descriptor =
+      new Field(STATIC | FINAL | PRIVATE,
+                new Variable(types->StringType(), "DESCRIPTOR"));
+  descriptor->value = "\"" + interfaceType->JavaType() + "\"";
+  this->elements.push_back(descriptor);
+
+  // ctor
+  Method* ctor = new Method;
+  ctor->modifiers = PUBLIC;
+  ctor->comment =
+      "/** Construct the stub at attach it to the "
+      "interface. */";
+  ctor->name = "Stub";
+  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, types);
+
+  // asBinder
+  Method* asBinder = new Method;
+  asBinder->modifiers = PUBLIC | OVERRIDE;
+  asBinder->returnType = types->IBinderType();
+  asBinder->name = "asBinder";
+  asBinder->statements = new StatementBlock;
+  asBinder->statements->Add(new ReturnStatement(THIS_VALUE));
+  this->elements.push_back(asBinder);
+
+  // onTransact
+  this->transact_code = new Variable(types->IntType(), "code");
+  this->transact_data = new Variable(types->ParcelType(), "data");
+  this->transact_reply = new Variable(types->ParcelType(), "reply");
+  this->transact_flags = new Variable(types->IntType(), "flags");
+  Method* onTransact = new Method;
+  onTransact->modifiers = PUBLIC | OVERRIDE;
+  onTransact->returnType = types->BoolType();
+  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 = new StatementBlock;
+  onTransact->exceptions.push_back(types->RemoteExceptionType());
+  this->elements.push_back(onTransact);
+  this->transact_switch = new SwitchStatement(this->transact_code);
+
+  onTransact->statements->Add(this->transact_switch);
+  MethodCall* superCall = new MethodCall(
+      SUPER_VALUE, "onTransact", 4, this->transact_code, this->transact_data,
+      this->transact_reply, this->transact_flags);
+  onTransact->statements->Add(new ReturnStatement(superCall));
+}
+
+void StubClass::make_as_interface(const InterfaceType* interfaceType,
+                                  JavaTypeNamespace* types) {
+  Variable* obj = new Variable(types->IBinderType(), "obj");
+
+  Method* m = new Method;
+  m->comment = "/**\n * Cast an IBinder object into an ";
+  m->comment += interfaceType->JavaType();
+  m->comment += " interface,\n";
+  m->comment += " * generating a proxy if needed.\n */";
+  m->modifiers = PUBLIC | STATIC;
+  m->returnType = interfaceType;
+  m->name = "asInterface";
+  m->parameters.push_back(obj);
+  m->statements = new StatementBlock;
+
+  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)
+  MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
+  queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
+  IInterfaceType* iinType = new IInterfaceType(types);
+  Variable* iin = new Variable(iinType, "iin");
+  VariableDeclaration* iinVd =
+      new VariableDeclaration(iin, queryLocalInterface, NULL);
+  m->statements->Add(iinVd);
+
+  // Ensure the instance type of the local object is as expected.
+  // One scenario where this is needed is if another package (with a
+  // different class loader) runs in the same process as the service.
+
+  // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>)
+  // 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, iin)));
+  m->statements->Add(instOfStatement);
+
+  NewExpression* ne = new NewExpression(interfaceType->GetProxy());
+  ne->arguments.push_back(obj);
+  m->statements->Add(new ReturnStatement(ne));
+
+  this->elements.push_back(m);
+}
+
+// =================================================
+class ProxyClass : public Class {
+ public:
+  ProxyClass(const JavaTypeNamespace* types, const Type* type,
+             const InterfaceType* interfaceType);
+  virtual ~ProxyClass();
+
+  Variable* mRemote;
+  bool mOneWay;
+};
+
+ProxyClass::ProxyClass(const JavaTypeNamespace* types, const Type* type,
+                       const InterfaceType* interfaceType)
+    : Class() {
+  this->modifiers = PRIVATE | STATIC;
+  this->what = Class::CLASS;
+  this->type = type;
+  this->interfaces.push_back(interfaceType);
+
+  mOneWay = interfaceType->OneWay();
+
+  // IBinder mRemote
+  mRemote = new Variable(types->IBinderType(), "mRemote");
+  this->elements.push_back(new Field(PRIVATE, mRemote));
+
+  // Proxy()
+  Variable* remote = new Variable(types->IBinderType(), "remote");
+  Method* ctor = new Method;
+  ctor->name = "Proxy";
+  ctor->statements = new StatementBlock;
+  ctor->parameters.push_back(remote);
+  ctor->statements->Add(new Assignment(mRemote, remote));
+  this->elements.push_back(ctor);
+
+  // IBinder asBinder()
+  Method* asBinder = new Method;
+  asBinder->modifiers = PUBLIC | OVERRIDE;
+  asBinder->returnType = types->IBinderType();
+  asBinder->name = "asBinder";
+  asBinder->statements = new StatementBlock;
+  asBinder->statements->Add(new ReturnStatement(mRemote));
+  this->elements.push_back(asBinder);
+}
+
+ProxyClass::~ProxyClass() {}
+
+// =================================================
+static void generate_new_array(const Type* t, StatementBlock* addTo,
+                               Variable* v, Variable* parcel,
+                               JavaTypeNamespace* types) {
+  Variable* len = new Variable(types->IntType(), 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, len)));
+  addTo->Add(lencheck);
+}
+
+static void generate_write_to_parcel(const Type* t, StatementBlock* addTo,
+                                     Variable* v, Variable* parcel, int flags) {
+  t->WriteToParcel(addTo, v, parcel, flags);
+}
+
+static void generate_create_from_parcel(const Type* t, StatementBlock* addTo,
+                                        Variable* v, Variable* parcel,
+                                        Variable** cl) {
+  t->CreateFromParcel(addTo, v, parcel, cl);
+}
+
+static void generate_int_constant(const AidlIntConstant& constant,
+                                  Class* interface) {
+  IntConstant* decl = new IntConstant(constant.GetName(), constant.GetValue());
+  interface->elements.push_back(decl);
+}
+
+static void generate_string_constant(const AidlStringConstant& constant,
+                                     Class* interface) {
+  StringConstant* decl = new StringConstant(constant.GetName(),
+                                            constant.GetValue());
+  interface->elements.push_back(decl);
+}
+
+static void generate_method(const AidlMethod& method, Class* interface,
+                            StubClass* stubClass, ProxyClass* proxyClass,
+                            int index, JavaTypeNamespace* types) {
+  int i;
+
+  const bool oneway = proxyClass->mOneWay || method.IsOneway();
+
+  // == the TRANSACT_ constant =============================================
+  string transactCodeName = "TRANSACTION_";
+  transactCodeName += method.GetName();
+
+  char transactCodeValue[60];
+  sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)",
+          index);
+
+  Field* transactCode = new Field(
+      STATIC | FINAL, new Variable(types->IntType(), transactCodeName));
+  transactCode->value = transactCodeValue;
+  stubClass->elements.push_back(transactCode);
+
+  // == the declaration in the interface ===================================
+  Method* decl = new Method;
+  decl->comment = method.GetComments();
+  decl->modifiers = PUBLIC;
+  decl->returnType = method.GetType().GetLanguageType<Type>();
+  decl->returnTypeDimension = method.GetType().IsArray() ? 1 : 0;
+  decl->name = method.GetName();
+
+  for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
+    decl->parameters.push_back(
+        new Variable(arg->GetType().GetLanguageType<Type>(), arg->GetName(),
+                     arg->GetType().IsArray() ? 1 : 0));
+  }
+
+  decl->exceptions.push_back(types->RemoteExceptionType());
+
+  interface->elements.push_back(decl);
+
+  // == the stub method ====================================================
+
+  Case* c = new Case(transactCodeName);
+
+  MethodCall* realCall = new MethodCall(THIS_VALUE, method.GetName());
+
+  // interface token validation is the very first thing we do
+  c->statements->Add(new MethodCall(stubClass->transact_data,
+                                    "enforceInterface", 1,
+                                    new LiteralExpression("DESCRIPTOR")));
+
+  // args
+  Variable* cl = NULL;
+  VariableFactory stubArgs("_arg");
+  for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
+    const Type* t = arg->GetType().GetLanguageType<Type>();
+    Variable* v = stubArgs.Get(t);
+    v->dimension = arg->GetType().IsArray() ? 1 : 0;
+
+    c->statements->Add(new VariableDeclaration(v));
+
+    if (arg->GetDirection() & AidlArgument::IN_DIR) {
+      generate_create_from_parcel(t, c->statements, v, stubClass->transact_data,
+                                  &cl);
+    } else {
+      if (!arg->GetType().IsArray()) {
+        c->statements->Add(new Assignment(v, new NewExpression(v->type)));
+      } else {
+        generate_new_array(v->type, c->statements, v, stubClass->transact_data,
+                           types);
+      }
+    }
+
+    realCall->arguments.push_back(v);
+  }
+
+  // the real call
+  Variable* _result = NULL;
+  if (method.GetType().GetName() == "void") {
+    c->statements->Add(realCall);
+
+    if (!oneway) {
+      // report that there were no exceptions
+      MethodCall* ex =
+          new MethodCall(stubClass->transact_reply, "writeNoException", 0);
+      c->statements->Add(ex);
+    }
+  } else {
+    _result =
+        new Variable(decl->returnType, "_result", decl->returnTypeDimension);
+    c->statements->Add(new VariableDeclaration(_result, realCall));
+
+    if (!oneway) {
+      // report that there were no exceptions
+      MethodCall* ex =
+          new MethodCall(stubClass->transact_reply, "writeNoException", 0);
+      c->statements->Add(ex);
+    }
+
+    // marshall the return value
+    generate_write_to_parcel(decl->returnType, c->statements, _result,
+                             stubClass->transact_reply,
+                             Type::PARCELABLE_WRITE_RETURN_VALUE);
+  }
+
+  // out parameters
+  i = 0;
+  for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
+    const Type* t = arg->GetType().GetLanguageType<Type>();
+    Variable* v = stubArgs.Get(i++);
+
+    if (arg->GetDirection() & AidlArgument::OUT_DIR) {
+      generate_write_to_parcel(t, c->statements, v, stubClass->transact_reply,
+                               Type::PARCELABLE_WRITE_RETURN_VALUE);
+    }
+  }
+
+  // return true
+  c->statements->Add(new ReturnStatement(TRUE_VALUE));
+  stubClass->transact_switch->cases.push_back(c);
+
+  // == the proxy method ===================================================
+  Method* proxy = new Method;
+  proxy->comment = method.GetComments();
+  proxy->modifiers = PUBLIC | OVERRIDE;
+  proxy->returnType = method.GetType().GetLanguageType<Type>();
+  proxy->returnTypeDimension = method.GetType().IsArray() ? 1 : 0;
+  proxy->name = method.GetName();
+  proxy->statements = new StatementBlock;
+  for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
+    proxy->parameters.push_back(
+        new Variable(arg->GetType().GetLanguageType<Type>(), arg->GetName(),
+                     arg->GetType().IsArray() ? 1 : 0));
+  }
+  proxy->exceptions.push_back(types->RemoteExceptionType());
+  proxyClass->elements.push_back(proxy);
+
+  // the parcels
+  Variable* _data = new Variable(types->ParcelType(), "_data");
+  proxy->statements->Add(new VariableDeclaration(
+      _data, new MethodCall(types->ParcelType(), "obtain")));
+  Variable* _reply = NULL;
+  if (!oneway) {
+    _reply = new Variable(types->ParcelType(), "_reply");
+    proxy->statements->Add(new VariableDeclaration(
+        _reply, new MethodCall(types->ParcelType(), "obtain")));
+  }
+
+  // the return value
+  _result = NULL;
+  if (method.GetType().GetName() != "void") {
+    _result = new Variable(proxy->returnType, "_result",
+                           method.GetType().IsArray() ? 1 : 0);
+    proxy->statements->Add(new VariableDeclaration(_result));
+  }
+
+  // try and finally
+  TryStatement* tryStatement = new TryStatement();
+  proxy->statements->Add(tryStatement);
+  FinallyStatement* finallyStatement = new FinallyStatement();
+  proxy->statements->Add(finallyStatement);
+
+  // the interface identifier token: the DESCRIPTOR constant, marshalled as a
+  // string
+  tryStatement->statements->Add(new MethodCall(
+      _data, "writeInterfaceToken", 1, new LiteralExpression("DESCRIPTOR")));
+
+  // the parameters
+  for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
+    const Type* t = arg->GetType().GetLanguageType<Type>();
+    Variable* v =
+        new Variable(t, arg->GetName(), arg->GetType().IsArray() ? 1 : 0);
+    AidlArgument::Direction dir = arg->GetDirection();
+    if (dir == AidlArgument::OUT_DIR && arg->GetType().IsArray()) {
+      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(t, tryStatement->statements, v, _data, 0);
+    } else {
+      delete v;
+    }
+  }
+
+  // the transact call
+  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"));
+  tryStatement->statements->Add(call);
+
+  // throw back exceptions.
+  if (_reply) {
+    MethodCall* ex = new MethodCall(_reply, "readException", 0);
+    tryStatement->statements->Add(ex);
+  }
+
+  // returning and cleanup
+  if (_reply != NULL) {
+    if (_result != NULL) {
+      generate_create_from_parcel(proxy->returnType, tryStatement->statements,
+                                  _result, _reply, &cl);
+    }
+
+    // the out/inout parameters
+    for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
+      const Type* t = arg->GetType().GetLanguageType<Type>();
+      if (arg->GetDirection() & AidlArgument::OUT_DIR) {
+        Variable* v =
+            new Variable(t, arg->GetName(), arg->GetType().IsArray() ? 1 : 0);
+        t->ReadFromParcel(tryStatement->statements, v, _reply, &cl);
+      }
+    }
+
+    finallyStatement->statements->Add(new MethodCall(_reply, "recycle"));
+  }
+  finallyStatement->statements->Add(new MethodCall(_data, "recycle"));
+
+  if (_result != NULL) {
+    proxy->statements->Add(new ReturnStatement(_result));
+  }
+}
+
+static void generate_interface_descriptors(StubClass* stub, ProxyClass* proxy,
+                                           const JavaTypeNamespace* types) {
+  // the interface descriptor transaction handler
+  Case* c = new Case("INTERFACE_TRANSACTION");
+  c->statements->Add(new MethodCall(stub->transact_reply, "writeString", 1,
+                                    new LiteralExpression("DESCRIPTOR")));
+  c->statements->Add(new ReturnStatement(TRUE_VALUE));
+  stub->transact_switch->cases.push_back(c);
+
+  // and the proxy-side method returning the descriptor directly
+  Method* getDesc = new Method;
+  getDesc->modifiers = PUBLIC;
+  getDesc->returnType = types->StringType();
+  getDesc->returnTypeDimension = 0;
+  getDesc->name = "getInterfaceDescriptor";
+  getDesc->statements = new StatementBlock;
+  getDesc->statements->Add(
+      new ReturnStatement(new LiteralExpression("DESCRIPTOR")));
+  proxy->elements.push_back(getDesc);
+}
+
+Class* generate_binder_interface_class(const AidlInterface* iface,
+                                       JavaTypeNamespace* types) {
+  const InterfaceType* interfaceType = iface->GetLanguageType<InterfaceType>();
+
+  // the interface class
+  Class* interface = new Class;
+  interface->comment = iface->GetComments();
+  interface->modifiers = PUBLIC;
+  interface->what = Class::INTERFACE;
+  interface->type = interfaceType;
+  interface->interfaces.push_back(types->IInterfaceType());
+
+  // the stub inner class
+  StubClass* stub =
+      new StubClass(interfaceType->GetStub(), interfaceType, types);
+  interface->elements.push_back(stub);
+
+  // the proxy inner class
+  ProxyClass* proxy =
+      new ProxyClass(types, interfaceType->GetProxy(), interfaceType);
+  stub->elements.push_back(proxy);
+
+  // stub and proxy support for getInterfaceDescriptor()
+  generate_interface_descriptors(stub, proxy, types);
+
+  // all the declared constants of the interface
+  for (const auto& item : iface->GetIntConstants()) {
+    generate_int_constant(*item, interface);
+  }
+  for (const auto& item : iface->GetStringConstants()) {
+    generate_string_constant(*item, interface);
+  }
+
+  // all the declared methods of the interface
+  for (const auto& item : iface->GetMethods()) {
+    generate_method(*item, interface, stub, proxy, item->GetId(), types);
+  }
+
+  return interface;
+}
+
+}  // namespace java
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/import_resolver.cpp b/aidl/import_resolver.cpp
new file mode 100644
index 0000000..4957c76
--- /dev/null
+++ b/aidl/import_resolver.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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 "import_resolver.h"
+
+#include <unistd.h>
+
+#ifdef _WIN32
+#include <io.h>
+#endif
+
+#include "os.h"
+
+using std::string;
+using std::vector;
+
+namespace android {
+namespace aidl {
+
+ImportResolver::ImportResolver(const IoDelegate& io_delegate,
+                               const vector<string>& import_paths)
+    : io_delegate_(io_delegate) {
+  for (string path : import_paths) {
+    if (path.empty()) {
+      path = ".";
+    }
+    if (path[path.size() - 1] != OS_PATH_SEPARATOR) {
+      path += OS_PATH_SEPARATOR;
+    }
+    import_paths_.push_back(std::move(path));
+  }
+}
+
+
+string ImportResolver::FindImportFile(const string& canonical_name) const {
+  // Convert the canonical name to a relative file path.
+  string relative_path = canonical_name;
+  for (char& c : relative_path) {
+    if (c == '.') {
+      c = OS_PATH_SEPARATOR;
+    }
+  }
+  relative_path += ".aidl";
+
+  // Look for that relative path at each of our import roots.
+  for (string path : import_paths_) {
+    path = path + relative_path;
+    if (io_delegate_.FileIsReadable(path)) {
+      return path;
+    }
+  }
+
+  return "";
+}
+
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/import_resolver.h b/aidl/import_resolver.h
new file mode 100644
index 0000000..e7562fb
--- /dev/null
+++ b/aidl/import_resolver.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_IMPORT_RESOLVER_H_
+#define AIDL_IMPORT_RESOLVER_H_
+
+#include <string>
+#include <vector>
+
+#include <android-base/macros.h>
+
+#include "io_delegate.h"
+
+namespace android {
+namespace aidl {
+
+class ImportResolver {
+ public:
+  ImportResolver(const IoDelegate& io_delegate,
+                 const std::vector<std::string>& import_paths);
+  virtual ~ImportResolver() = default;
+
+  // Resolve the canonical name for a class to a file that exists
+  // in one of the import paths given to the ImportResolver.
+  std::string FindImportFile(const std::string& canonical_name) const;
+
+ private:
+  const IoDelegate& io_delegate_;
+  std::vector<std::string> import_paths_;
+
+  DISALLOW_COPY_AND_ASSIGN(ImportResolver);
+};
+
+}  // namespace android
+}  // namespace aidl
+
+#endif // AIDL_IMPORT_RESOLVER_H_
diff --git a/aidl/io_delegate.cpp b/aidl/io_delegate.cpp
new file mode 100644
index 0000000..62be3f5
--- /dev/null
+++ b/aidl/io_delegate.cpp
@@ -0,0 +1,190 @@
+/*
+ * 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 "io_delegate.h"
+
+#include <cstring>
+#include <fstream>
+#include <vector>
+
+#ifdef _WIN32
+#include <direct.h>
+#else
+#include <sys/stat.h>
+#include <unistd.h>
+#endif
+
+#include <android-base/strings.h>
+
+#include "logging.h"
+#include "os.h"
+
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+using android::base::Split;
+
+namespace android {
+namespace aidl {
+
+bool IoDelegate::GetAbsolutePath(const string& path, string* absolute_path) {
+#ifdef _WIN32
+
+  char buf[4096];
+  DWORD path_len = GetFullPathName(path.c_str(), sizeof(buf), buf, nullptr);
+  if (path_len <= 0 || path_len >= sizeof(buf)) {
+    LOG(ERROR) << "Failed to GetFullPathName(" << path << ")";
+    return false;
+  }
+  *absolute_path = buf;
+
+  return true;
+
+#else
+
+  if (path.empty()) {
+    LOG(ERROR) << "Giving up on finding an absolute path to represent the "
+                  "empty string.";
+    return false;
+  }
+  if (path[0] == OS_PATH_SEPARATOR) {
+    *absolute_path = path;
+    return true;
+  }
+
+  char buf[4096];
+  if (getcwd(buf, sizeof(buf)) == nullptr) {
+    LOG(ERROR) << "Path of current working directory does not fit in "
+               << sizeof(buf) << " bytes";
+    return false;
+  }
+
+  *absolute_path = buf;
+  *absolute_path += OS_PATH_SEPARATOR;
+  *absolute_path += path;
+  return true;
+#endif
+}
+
+unique_ptr<string> IoDelegate::GetFileContents(
+    const string& filename,
+    const string& content_suffix) const {
+  unique_ptr<string> contents;
+  std::ifstream in(filename, std::ios::in | std::ios::binary);
+  if (!in) {
+    return contents;
+  }
+  contents.reset(new string);
+  in.seekg(0, std::ios::end);
+  ssize_t file_size = in.tellg();
+  contents->resize(file_size + content_suffix.length());
+  in.seekg(0, std::ios::beg);
+  // Read the file contents into the beginning of the string
+  in.read(&(*contents)[0], file_size);
+  // Drop the suffix in at the end.
+  contents->replace(file_size, content_suffix.length(), content_suffix);
+  in.close();
+
+  return contents;
+}
+
+unique_ptr<LineReader> IoDelegate::GetLineReader(
+    const string& file_path) const {
+  return LineReader::ReadFromFile(file_path);
+}
+
+bool IoDelegate::FileIsReadable(const string& path) const {
+#ifdef _WIN32
+  // check that the file exists and is not write-only
+  return (0 == _access(path.c_str(), 0)) &&  // mode 0=exist
+         (0 == _access(path.c_str(), 4));    // mode 4=readable
+#else
+  return (0 == access(path.c_str(), R_OK));
+#endif
+}
+
+bool IoDelegate::CreatedNestedDirs(
+    const string& caller_base_dir,
+    const vector<string>& nested_subdirs) const {
+  string base_dir = caller_base_dir;
+  if (base_dir.empty()) {
+    base_dir = ".";
+  }
+  for (const string& subdir : nested_subdirs) {
+    if (base_dir[base_dir.size() - 1] != OS_PATH_SEPARATOR) {
+      base_dir += OS_PATH_SEPARATOR;
+    }
+    base_dir += subdir;
+    bool success;
+#ifdef _WIN32
+    success = _mkdir(base_dir.c_str()) == 0;
+#else
+    success = mkdir(base_dir.c_str(),
+                    S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
+#endif
+    // On darwin when you try to mkdir("/", ...) we get EISDIR.
+    if (!success && (errno != EEXIST && errno != EISDIR)) {
+      LOG(ERROR) << "Error while creating " << base_dir << ": "
+                 << strerror(errno);
+      return false;
+    }
+  }
+  return true;
+}
+
+bool IoDelegate::CreatePathForFile(const string& path) const {
+  if (path.empty()) {
+    return true;
+  }
+
+  string absolute_path;
+  if (!GetAbsolutePath(path, &absolute_path)) {
+    return false;
+  }
+
+  auto directories = Split(absolute_path, string{1u, OS_PATH_SEPARATOR});
+
+  // The "base" directory is just the root of the file system.  On Windows,
+  // this will look like "C:\" but on Unix style file systems we get an empty
+  // string after splitting "/foo" with "/"
+  string base = directories[0];
+  if (base.empty()) {
+    base = "/";
+  }
+  directories.erase(directories.begin());
+
+  // Remove the actual file in question, we're just creating the directory path.
+  directories.pop_back();
+
+  return CreatedNestedDirs(base, directories);
+}
+
+unique_ptr<CodeWriter> IoDelegate::GetCodeWriter(
+    const string& file_path) const {
+  return GetFileWriter(file_path);
+}
+
+void IoDelegate::RemovePath(const std::string& file_path) const {
+#ifdef _WIN32
+  _unlink(file_path.c_str());
+#else
+  unlink(file_path.c_str());
+#endif
+}
+
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/io_delegate.h b/aidl/io_delegate.h
new file mode 100644
index 0000000..dc9a3e3
--- /dev/null
+++ b/aidl/io_delegate.h
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_IO_DELEGATE_H_
+#define AIDL_IO_DELEGATE_H_
+
+#include <android-base/macros.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "code_writer.h"
+#include "line_reader.h"
+
+namespace android {
+namespace aidl {
+
+class IoDelegate {
+ public:
+  IoDelegate() = default;
+  virtual ~IoDelegate() = default;
+
+  // Stores an absolute version of |path| to |*absolute_path|,
+  // possibly prefixing it with the current working directory.
+  // Returns false and does not set |*absolute_path| on error.
+  static bool GetAbsolutePath(const std::string& path,
+                              std::string* absolute_path);
+
+  // Returns a unique_ptr to the contents of |filename|.
+  // Will append the optional |content_suffix| to the returned contents.
+  virtual std::unique_ptr<std::string> GetFileContents(
+      const std::string& filename,
+      const std::string& content_suffix = "") const;
+
+  virtual std::unique_ptr<LineReader> GetLineReader(
+      const std::string& file_path) const;
+
+  virtual bool FileIsReadable(const std::string& path) const;
+
+  virtual bool CreatedNestedDirs(
+      const std::string& base_dir,
+      const std::vector<std::string>& nested_subdirs) const;
+
+  bool CreatePathForFile(const std::string& path) const;
+
+  virtual std::unique_ptr<CodeWriter> GetCodeWriter(
+      const std::string& file_path) const;
+
+  virtual void RemovePath(const std::string& file_path) const;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(IoDelegate);
+};  // class IoDelegate
+
+}  // namespace android
+}  // namespace aidl
+
+#endif // AIDL_IO_DELEGATE_H_
diff --git a/aidl/io_delegate_unittest.cpp b/aidl/io_delegate_unittest.cpp
new file mode 100644
index 0000000..5227d0b
--- /dev/null
+++ b/aidl/io_delegate_unittest.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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>
+
+#include <gtest/gtest.h>
+
+#include "io_delegate.h"
+
+using std::string;
+
+namespace android {
+namespace aidl {
+
+TEST(IoDelegateTest, CannotGetAbsolutePathFromEmptyString) {
+  string absolute_path;
+  EXPECT_FALSE(IoDelegate::GetAbsolutePath("", &absolute_path));
+  EXPECT_TRUE(absolute_path.empty());
+}
+
+TEST(IoDelegateTest, CurrentlyInfersLinuxAbsolutePath) {
+  string absolute_path;
+  EXPECT_TRUE(IoDelegate::GetAbsolutePath("foo", &absolute_path));
+  ASSERT_FALSE(absolute_path.empty());
+  // Should find our desired file at the end of |absolute_path|
+  // But we don't know the prefix, since it's the current working directory
+  EXPECT_TRUE(absolute_path.rfind("/foo") == absolute_path.length() - 4);
+  // Whatever our current working directory, the path is absolute.
+  EXPECT_EQ(absolute_path[0], '/');
+}
+
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/line_reader.cpp b/aidl/line_reader.cpp
new file mode 100644
index 0000000..0bcaa1d
--- /dev/null
+++ b/aidl/line_reader.cpp
@@ -0,0 +1,91 @@
+/*
+ * 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 "line_reader.h"
+
+#include <fstream>
+#include <sstream>
+
+using std::istringstream;
+using std::ifstream;
+using std::string;
+using std::unique_ptr;
+
+namespace android {
+namespace aidl {
+
+class FileLineReader : public LineReader {
+ public:
+  FileLineReader() = default;
+  virtual ~FileLineReader() {
+    input_stream_.close();
+  }
+
+  bool Init(const std::string& file_path) {
+    input_stream_.open(file_path, ifstream::in | ifstream::binary);
+    return input_stream_.is_open() && input_stream_.good();
+  }
+
+  bool ReadLine(string* line) override {
+    if (!input_stream_.good()) {
+      return false;
+    }
+    line->clear();
+    std::getline(input_stream_, *line);
+    return true;
+  }
+
+ private:
+  ifstream input_stream_;
+
+  DISALLOW_COPY_AND_ASSIGN(FileLineReader);
+};  // class FileLineReader
+
+class MemoryLineReader : public LineReader {
+ public:
+  explicit MemoryLineReader(const string& contents) : input_stream_(contents) {}
+  virtual ~MemoryLineReader() = default;
+
+  bool ReadLine(string* line) override {
+    if (!input_stream_.good()) {
+      return false;
+    }
+    line->clear();
+    std::getline(input_stream_, *line);
+    return true;
+  }
+
+ private:
+  istringstream input_stream_;
+
+  DISALLOW_COPY_AND_ASSIGN(MemoryLineReader);
+};  // class MemoryLineReader
+
+unique_ptr<LineReader> LineReader::ReadFromFile(const string& file_path) {
+  unique_ptr<FileLineReader> file_reader(new FileLineReader());
+  unique_ptr<LineReader> ret;
+  if (file_reader->Init(file_path)) {
+    ret.reset(file_reader.release());
+  }
+  return ret;
+}
+
+unique_ptr<LineReader> LineReader::ReadFromMemory(const string& contents) {
+  return unique_ptr<LineReader>(new MemoryLineReader(contents));
+}
+
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/line_reader.h b/aidl/line_reader.h
new file mode 100644
index 0000000..885327e
--- /dev/null
+++ b/aidl/line_reader.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_LINE_READER_H_
+#define AIDL_LINE_READER_H_
+
+#include <memory>
+#include <string>
+
+#include <android-base/macros.h>
+
+namespace android {
+namespace aidl {
+
+class LineReader {
+ public:
+  LineReader() = default;
+  virtual ~LineReader() = default;
+  virtual bool ReadLine(std::string* line) = 0;
+
+  static std::unique_ptr<LineReader> ReadFromFile(
+      const std::string& file_path);
+  static std::unique_ptr<LineReader> ReadFromMemory(
+      const std::string& contents);
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(LineReader);
+};  // class LineReader
+
+}  // namespace android
+}  // namespace aidl
+
+#endif // AIDL_LINE_READER_H_
diff --git a/aidl/logging.h b/aidl/logging.h
new file mode 100644
index 0000000..f76c4e0
--- /dev/null
+++ b/aidl/logging.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_LOGGING_H_
+#define AIDL_LOGGING_H_
+
+// We must include windows.h before android-base/logging.h on Windows.
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
+#include <android-base/logging.h>
+
+#endif // AIDL_LOGGING_H_
diff --git a/aidl/main_cpp.cpp b/aidl/main_cpp.cpp
new file mode 100644
index 0000000..790efdc
--- /dev/null
+++ b/aidl/main_cpp.cpp
@@ -0,0 +1,37 @@
+/*
+ * 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 "aidl.h"
+#include "io_delegate.h"
+#include "logging.h"
+#include "options.h"
+
+using android::aidl::CppOptions;
+
+int main(int argc, char** argv) {
+  android::base::InitLogging(argv);
+  LOG(DEBUG) << "aidl starting";
+
+  std::unique_ptr<CppOptions> options = CppOptions::Parse(argc, argv);
+  if (!options) {
+    return 1;
+  }
+
+  android::aidl::IoDelegate io_delegate;
+  return android::aidl::compile_aidl_to_cpp(*options, io_delegate);
+}
diff --git a/aidl/main_java.cpp b/aidl/main_java.cpp
new file mode 100644
index 0000000..7d32b24
--- /dev/null
+++ b/aidl/main_java.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 <iostream>
+#include <memory>
+
+#include "aidl.h"
+#include "io_delegate.h"
+#include "logging.h"
+#include "options.h"
+
+using android::aidl::JavaOptions;
+
+int main(int argc, char** argv) {
+  android::base::InitLogging(argv);
+  LOG(DEBUG) << "aidl starting";
+  std::unique_ptr<JavaOptions> options = JavaOptions::Parse(argc, argv);
+  if (!options) {
+    return 1;
+  }
+
+  android::aidl::IoDelegate io_delegate;
+  switch (options->task) {
+    case JavaOptions::COMPILE_AIDL_TO_JAVA:
+      return android::aidl::compile_aidl_to_java(*options, io_delegate);
+    case JavaOptions::PREPROCESS_AIDL:
+      if (android::aidl::preprocess_aidl(*options, io_delegate))
+        return 0;
+      return 1;
+  }
+  std::cerr << "aidl: internal error" << std::endl;
+  return 1;
+}
diff --git a/aidl/options.cpp b/aidl/options.cpp
new file mode 100644
index 0000000..c7cef5c
--- /dev/null
+++ b/aidl/options.cpp
@@ -0,0 +1,267 @@
+/*
+ * 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 "options.h"
+
+#include <cstring>
+#include <iostream>
+#include <stdio.h>
+
+#include "logging.h"
+#include "os.h"
+
+using std::cerr;
+using std::endl;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+namespace android {
+namespace aidl {
+namespace {
+
+unique_ptr<JavaOptions> java_usage() {
+  fprintf(stderr,
+          "usage: aidl OPTIONS INPUT [OUTPUT]\n"
+          "       aidl --preprocess OUTPUT INPUT...\n"
+          "\n"
+          "OPTIONS:\n"
+          "   -I<DIR>    search path for import statements.\n"
+          "   -d<FILE>   generate dependency file.\n"
+          "   -a         generate dependency file next to the output file with "
+          "the name based on the input file.\n"
+          "   -p<FILE>   file created by --preprocess to import.\n"
+          "   -o<FOLDER> base output folder for generated files.\n"
+          "   -b         fail when trying to compile a parcelable.\n"
+          "\n"
+          "INPUT:\n"
+          "   An aidl interface file.\n"
+          "\n"
+          "OUTPUT:\n"
+          "   The generated interface files.\n"
+          "   If omitted and the -o option is not used, the input filename is "
+          "used, with the .aidl extension changed to a .java extension.\n"
+          "   If the -o option is used, the generated files will be placed in "
+          "the base output folder, under their package folder\n");
+  return unique_ptr<JavaOptions>(nullptr);
+}
+
+}  // namespace
+
+unique_ptr<JavaOptions> JavaOptions::Parse(int argc, const char* const* argv) {
+  unique_ptr<JavaOptions> options(new JavaOptions());
+  int i = 1;
+
+  if (argc >= 2 && 0 == strcmp(argv[1], "--preprocess")) {
+    if (argc < 4) {
+      return java_usage();
+    }
+    options->output_file_name_ = argv[2];
+    for (int i = 3; i < argc; i++) {
+      options->files_to_preprocess_.push_back(argv[i]);
+    }
+    options->task = PREPROCESS_AIDL;
+    return options;
+  }
+
+  options->task = COMPILE_AIDL_TO_JAVA;
+  // OPTIONS
+  while (i < argc) {
+    const char* s = argv[i];
+    const size_t len = strlen(s);
+    if (s[0] != '-') {
+      break;
+    }
+    if (len <= 1) {
+      fprintf(stderr, "unknown option (%d): %s\n", i, s);
+      return java_usage();
+    }
+    // -I<system-import-path>
+    if (s[1] == 'I') {
+      if (len > 2) {
+        options->import_paths_.push_back(s + 2);
+      } else {
+        fprintf(stderr, "-I option (%d) requires a path.\n", i);
+        return java_usage();
+      }
+    } else if (s[1] == 'd') {
+      if (len > 2) {
+        options->dep_file_name_ = s + 2;
+      } else {
+        fprintf(stderr, "-d option (%d) requires a file.\n", i);
+        return java_usage();
+      }
+    } else if (strcmp(s, "-a") == 0) {
+      options->auto_dep_file_ = true;
+    } else if (s[1] == 'p') {
+      if (len > 2) {
+        options->preprocessed_files_.push_back(s + 2);
+      } else {
+        fprintf(stderr, "-p option (%d) requires a file.\n", i);
+        return java_usage();
+      }
+    } else if (s[1] == 'o') {
+      if (len > 2) {
+        options->output_base_folder_= s + 2;
+      } else {
+        fprintf(stderr, "-o option (%d) requires a path.\n", i);
+        return java_usage();
+      }
+    } else if (strcmp(s, "-b") == 0) {
+      options->fail_on_parcelable_ = true;
+    } else {
+      // s[1] is not known
+      fprintf(stderr, "unknown option (%d): %s\n", i, s);
+      return java_usage();
+    }
+    i++;
+  }
+  // INPUT
+  if (i < argc) {
+    options->input_file_name_ = argv[i];
+    i++;
+  } else {
+    fprintf(stderr, "INPUT required\n");
+    return java_usage();
+  }
+  if (!EndsWith(options->input_file_name_, ".aidl")) {
+    cerr << "Expected .aidl file for input but got "
+         << options->input_file_name_ << endl;
+    return java_usage();
+  }
+
+  // OUTPUT
+  if (i < argc) {
+    options->output_file_name_ = argv[i];
+    i++;
+  } else if (options->output_base_folder_.empty()) {
+    // copy input into output and change the extension from .aidl to .java
+    options->output_file_name_= options->input_file_name_;
+    if (!ReplaceSuffix(".aidl", ".java", &options->output_file_name_)) {
+      // we should never get here since we validated the suffix.
+      LOG(FATAL) << "Internal aidl error.";
+      return java_usage();
+    }
+  }
+
+  // anything remaining?
+  if (i != argc) {
+    fprintf(stderr, "unknown option%s:",
+            (i == argc - 1 ? (const char*)"" : (const char*)"s"));
+    for (; i < argc - 1; i++) {
+      fprintf(stderr, " %s", argv[i]);
+    }
+    fprintf(stderr, "\n");
+    return java_usage();
+  }
+
+  return options;
+}
+
+string JavaOptions::DependencyFilePath() const {
+  if (auto_dep_file_) {
+    return output_file_name_ + ".d";
+  }
+  return dep_file_name_;
+}
+
+namespace {
+
+unique_ptr<CppOptions> cpp_usage() {
+  cerr << "usage: aidl-cpp INPUT_FILE HEADER_DIR OUTPUT_FILE" << endl
+       << endl
+       << "OPTIONS:" << endl
+       << "   -I<DIR>   search path for import statements" << endl
+       << "   -d<FILE>  generate dependency file" << endl
+       << endl
+       << "INPUT_FILE:" << endl
+       << "   an aidl interface file" << endl
+       << "HEADER_DIR:" << endl
+       << "   empty directory to put generated headers" << endl
+       << "OUTPUT_FILE:" << endl
+       << "   path to write generated .cpp code" << endl;
+  return unique_ptr<CppOptions>(nullptr);
+}
+
+}  // namespace
+
+unique_ptr<CppOptions> CppOptions::Parse(int argc, const char* const* argv) {
+  unique_ptr<CppOptions> options(new CppOptions());
+  int i = 1;
+
+  // Parse flags, all of which start with '-'
+  for ( ; i < argc; ++i) {
+    const size_t len = strlen(argv[i]);
+    const char *s = argv[i];
+    if (s[0] != '-') {
+      break;  // On to the positional arguments.
+    }
+    if (len < 2) {
+      cerr << "Invalid argument '" << s << "'." << endl;
+      return cpp_usage();
+    }
+    const string the_rest = s + 2;
+    if (s[1] == 'I') {
+      options->import_paths_.push_back(the_rest);
+    } else if (s[1] == 'd') {
+      options->dep_file_name_ = the_rest;
+    } else {
+      cerr << "Invalid argument '" << s << "'." << endl;
+      return cpp_usage();
+    }
+  }
+
+  // There are exactly three positional arguments.
+  const int remaining_args = argc - i;
+  if (remaining_args != 3) {
+    cerr << "Expected 3 positional arguments but got " << remaining_args << "." << endl;
+    return cpp_usage();
+  }
+
+  options->input_file_name_ = argv[i];
+  options->output_header_dir_ = argv[i + 1];
+  options->output_file_name_ = argv[i + 2];
+
+  if (!EndsWith(options->input_file_name_, ".aidl")) {
+    cerr << "Expected .aidl file for input but got " << options->input_file_name_ << endl;
+    return cpp_usage();
+  }
+
+  return options;
+}
+
+bool EndsWith(const string& str, const string& suffix) {
+  if (str.length() < suffix.length()) {
+    return false;
+  }
+  return std::equal(str.crbegin(), str.crbegin() + suffix.length(),
+                    suffix.crbegin());
+}
+
+bool ReplaceSuffix(const string& old_suffix,
+                   const string& new_suffix,
+                   string* str) {
+  if (!EndsWith(*str, old_suffix)) return false;
+  str->replace(str->length() - old_suffix.length(),
+               old_suffix.length(),
+               new_suffix);
+  return true;
+}
+
+
+
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/options.h b/aidl/options.h
new file mode 100644
index 0000000..6f32c62
--- /dev/null
+++ b/aidl/options.h
@@ -0,0 +1,107 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_OPTIONS_H_
+#define AIDL_OPTIONS_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <android-base/macros.h>
+#include <gtest/gtest_prod.h>
+
+namespace android {
+namespace aidl {
+
+// This object represents the parsed options to the Java generating aidl.
+class JavaOptions final {
+ public:
+  enum {
+      COMPILE_AIDL_TO_JAVA,
+      PREPROCESS_AIDL,
+  };
+
+  ~JavaOptions() = default;
+
+  // Parses the command line and returns a non-null pointer to an JavaOptions
+  // object on success.
+  // Prints the usage statement on failure.
+  static std::unique_ptr<JavaOptions> Parse(int argc, const char* const* argv);
+
+  std::string DependencyFilePath() const;
+
+  int task{COMPILE_AIDL_TO_JAVA};
+  bool fail_on_parcelable_{false};
+  std::vector<std::string> import_paths_;
+  std::vector<std::string> preprocessed_files_;
+  std::string input_file_name_;
+  std::string output_file_name_;
+  std::string output_base_folder_;
+  std::string dep_file_name_;
+  bool auto_dep_file_{false};
+  std::vector<std::string> files_to_preprocess_;
+
+ private:
+  JavaOptions() = default;
+
+  FRIEND_TEST(EndToEndTest, IExampleInterface);
+  FRIEND_TEST(AidlTest, FailOnParcelable);
+  FRIEND_TEST(AidlTest, WritePreprocessedFile);
+  FRIEND_TEST(AidlTest, WritesCorrectDependencyFile);
+  FRIEND_TEST(AidlTest, WritesTrivialDependencyFileForParcelable);
+
+  DISALLOW_COPY_AND_ASSIGN(JavaOptions);
+};
+
+class CppOptions final {
+ public:
+
+  ~CppOptions() = default;
+
+  // Parses the command line and returns a non-null pointer to an CppOptions
+  // object on success.
+  // Prints the usage statement on failure.
+  static std::unique_ptr<CppOptions> Parse(int argc, const char* const* argv);
+
+  std::string InputFileName() const { return input_file_name_; }
+  std::string OutputHeaderDir() const { return output_header_dir_; }
+  std::string OutputCppFilePath() const { return output_file_name_; }
+
+  std::vector<std::string> ImportPaths() const { return import_paths_; }
+  std::string DependencyFilePath() const { return dep_file_name_; }
+
+ private:
+  CppOptions() = default;
+
+  std::string input_file_name_;
+  std::vector<std::string> import_paths_;
+  std::string output_header_dir_;
+  std::string output_file_name_;
+  std::string dep_file_name_;
+
+  FRIEND_TEST(CppOptionsTests, ParsesCompileCpp);
+  DISALLOW_COPY_AND_ASSIGN(CppOptions);
+};
+
+bool EndsWith(const std::string& str, const std::string& suffix);
+bool ReplaceSuffix(const std::string& old_suffix,
+                   const std::string& new_suffix,
+                   std::string* str);
+
+}  // namespace android
+}  // namespace aidl
+
+#endif // AIDL_OPTIONS_H_
diff --git a/aidl/options_unittest.cpp b/aidl/options_unittest.cpp
new file mode 100644
index 0000000..568765b
--- /dev/null
+++ b/aidl/options_unittest.cpp
@@ -0,0 +1,161 @@
+/*
+ * 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 <iostream>
+#include <string>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include "options.h"
+
+using std::cerr;
+using std::endl;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+namespace android {
+namespace aidl {
+namespace {
+
+const char kPreprocessCommandOutputFile[] = "output_file_name";
+const char kPreprocessCommandInput1[] = "input1";
+const char kPreprocessCommandInput2[] = "input2";
+const char kPreprocessCommandInput3[] = "input3";
+const char* kPreprocessCommand[] = {
+    "aidl", "--preprocess",
+    kPreprocessCommandOutputFile,
+    kPreprocessCommandInput1,
+    kPreprocessCommandInput2,
+    kPreprocessCommandInput3,
+    nullptr,
+};
+
+const char kCompileCommandInput[] = "directory/ITool.aidl";
+const char kCompileCommandIncludePath[] = "-Iinclude_path";
+const char* kCompileJavaCommand[] = {
+    "aidl",
+    "-b",
+    kCompileCommandIncludePath,
+    kCompileCommandInput,
+    nullptr,
+};
+const char kCompileCommandJavaOutput[] = "directory/ITool.java";
+
+const char kCompileDepFile[] = "-doutput.deps";
+const char kCompileCommandHeaderDir[] = "output/dir";
+const char kCompileCommandCppOutput[] = "some/file.cpp";
+const char* kCompileCppCommand[] = {
+    "aidl-cpp",
+    kCompileCommandIncludePath,
+    kCompileDepFile,
+    kCompileCommandInput,
+    kCompileCommandHeaderDir,
+    kCompileCommandCppOutput,
+    nullptr,
+};
+
+template <typename T>
+unique_ptr<T> GetOptions(const char* command[]) {
+  int argc = 0;
+  const char** command_part = command;
+  for (; *command_part; ++argc, ++command_part) {}
+  unique_ptr<T> options(T::Parse(argc, command));
+  if (!options) {
+    cerr << "Failed to parse command line:";
+    for (int i = 0; i < argc; ++i) {
+      cerr << " " << command[i];
+      cerr << endl;
+    }
+  }
+  EXPECT_NE(options, nullptr) << "Failed to parse options!";
+  return options;
+}
+
+}  // namespace
+
+TEST(JavaOptionsTests, ParsesPreprocess) {
+  unique_ptr<JavaOptions> options = GetOptions<JavaOptions>(kPreprocessCommand);
+  EXPECT_EQ(JavaOptions::PREPROCESS_AIDL, options->task);
+  EXPECT_EQ(false, options->fail_on_parcelable_);
+  EXPECT_EQ(0u, options->import_paths_.size());
+  EXPECT_EQ(0u, options->preprocessed_files_.size());
+  EXPECT_EQ(string{}, options->input_file_name_);
+  EXPECT_EQ(string{kPreprocessCommandOutputFile}, options->output_file_name_);
+  EXPECT_EQ(false, options->auto_dep_file_);
+  const vector<string> expected_input{kPreprocessCommandInput1,
+                                      kPreprocessCommandInput2,
+                                      kPreprocessCommandInput3};
+  EXPECT_EQ(expected_input, options->files_to_preprocess_);
+}
+
+TEST(JavaOptionsTests, ParsesCompileJava) {
+  unique_ptr<JavaOptions> options =
+      GetOptions<JavaOptions>(kCompileJavaCommand);
+  EXPECT_EQ(JavaOptions::COMPILE_AIDL_TO_JAVA, options->task);
+  EXPECT_EQ(true, options->fail_on_parcelable_);
+  EXPECT_EQ(1u, options->import_paths_.size());
+  EXPECT_EQ(0u, options->preprocessed_files_.size());
+  EXPECT_EQ(string{kCompileCommandInput}, options->input_file_name_);
+  EXPECT_EQ(string{kCompileCommandJavaOutput}, options->output_file_name_);
+  EXPECT_EQ(false, options->auto_dep_file_);
+}
+
+TEST(CppOptionsTests, ParsesCompileCpp) {
+  unique_ptr<CppOptions> options = GetOptions<CppOptions>(kCompileCppCommand);
+  ASSERT_EQ(1u, options->import_paths_.size());
+  EXPECT_EQ(string{kCompileCommandIncludePath}.substr(2),
+            options->import_paths_[0]);
+  EXPECT_EQ(string{kCompileDepFile}.substr(2), options->dep_file_name_);
+  EXPECT_EQ(kCompileCommandInput, options->InputFileName());
+  EXPECT_EQ(kCompileCommandHeaderDir, options->OutputHeaderDir());
+  EXPECT_EQ(kCompileCommandCppOutput, options->OutputCppFilePath());
+}
+
+TEST(OptionsTests, EndsWith) {
+  EXPECT_TRUE(EndsWith("foo", ""));
+  EXPECT_TRUE(EndsWith("foo", "o"));
+  EXPECT_TRUE(EndsWith("foo", "foo"));
+  EXPECT_FALSE(EndsWith("foo", "fooo"));
+  EXPECT_FALSE(EndsWith("", "o"));
+  EXPECT_TRUE(EndsWith("", ""));
+}
+
+TEST(OptionsTests, ReplaceSuffix) {
+  struct test_case_t {
+    const char* input;
+    const char* old_suffix;
+    const char* new_suffix;
+    const char* result;
+  };
+  const size_t kNumCases = 3;
+  test_case_t kTestInput[kNumCases] = {
+    {"foo.bar", "bar", "foo", "foo.foo"},
+    {"whole", "whole", "new", "new"},
+    {"", "", "", ""},
+  };
+  for (const auto& test_case : kTestInput) {
+    string mutated = test_case.input;
+    EXPECT_TRUE(ReplaceSuffix(test_case.old_suffix,
+                              test_case.new_suffix,
+                              &mutated));
+    EXPECT_EQ(mutated, test_case.result);
+  }
+}
+
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/os.h b/aidl/os.h
new file mode 100644
index 0000000..752ed47
--- /dev/null
+++ b/aidl/os.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef AIDL_OS_H_
+#define AIDL_OS_H_
+
+#if defined(_WIN32)
+#define OS_PATH_SEPARATOR '\\'
+#else
+#define OS_PATH_SEPARATOR '/'
+#endif
+
+#endif  // AIDL_OS_H_
diff --git a/aidl/runtests.sh b/aidl/runtests.sh
new file mode 100755
index 0000000..05809f9
--- /dev/null
+++ b/aidl/runtests.sh
@@ -0,0 +1,41 @@
+#!/usr/bin/env bash
+
+# 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.
+
+if [ -z $ANDROID_BUILD_TOP ]; then
+  echo "You need to source and lunch before you can use this script"
+  exit 1
+fi
+
+echo "Running tests"
+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 -j32 $ANDROID_BUILD_TOP/system/tools/aidl"
+make -j32 -C $ANDROID_BUILD_TOP -f build/core/main.mk \
+    MODULES-IN-system-tools-aidl
+
+set -x # print commands
+
+${ANDROID_HOST_OUT}/nativetest64/aidl_unittests/aidl_unittests
+
+adb root
+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/aidl/tests/aidl_test_client.cpp b/aidl/tests/aidl_test_client.cpp
new file mode 100644
index 0000000..84c8183
--- /dev/null
+++ b/aidl/tests/aidl_test_client.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 <iostream>
+
+#include <android-base/logging.h>
+#include <binder/IServiceManager.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+#include "android/aidl/tests/ITestService.h"
+
+#include "aidl_test_client_file_descriptors.h"
+#include "aidl_test_client_nullables.h"
+#include "aidl_test_client_parcelables.h"
+#include "aidl_test_client_primitives.h"
+#include "aidl_test_client_service_exceptions.h"
+#include "aidl_test_client_utf8_strings.h"
+
+// libutils:
+using android::OK;
+using android::sp;
+using android::status_t;
+using android::String16;
+
+// libbinder:
+using android::getService;
+
+// generated
+using android::aidl::tests::ITestService;
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+const char kServiceName[] = "android.aidl.tests.ITestService";
+
+bool GetService(sp<ITestService>* service) {
+  cout << "Retrieving test service binder" << endl;
+  status_t status = getService(String16(kServiceName), service);
+  if (status != OK) {
+    cerr << "Failed to get service binder: '" << kServiceName
+         << "' status=" << status << endl;
+    return false;
+  }
+  return true;
+}
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+
+/* Runs all the test cases in aidl_test_client_*.cpp files. */
+int main(int /* argc */, char * argv []) {
+  android::base::InitLogging(argv, android::base::StderrLogger);
+  sp<ITestService> service;
+  namespace client_tests = android::aidl::tests::client;
+
+
+  if (!client_tests::GetService(&service)) return 1;
+
+  if (!client_tests::ConfirmPrimitiveRepeat(service)) return 1;
+
+  if (!client_tests::ConfirmReverseArrays(service)) return 1;
+
+  if (!client_tests::ConfirmReverseLists(service)) return 1;
+
+  if (!client_tests::ConfirmReverseBinderLists(service)) return 1;
+
+  if (!client_tests::ConfirmSimpleParcelables(service)) return 1;
+
+  if (!client_tests::ConfirmPersistableBundles(service)) return 1;
+
+  if (!client_tests::ConfirmFileDescriptors(service)) return 1;
+
+  if (!client_tests::ConfirmFileDescriptorArrays(service)) return 1;
+
+  if (!client_tests::ConfirmServiceSpecificExceptions(service)) return 1;
+
+  if (!client_tests::ConfirmNullables(service)) return 1;
+
+  if (!client_tests::ConfirmUtf8InCppStringRepeat(service)) return 1;
+
+  if (!client_tests::ConfirmUtf8InCppStringArrayReverse(service)) return 1;
+
+  if (!client_tests::ConfirmUtf8InCppStringListReverse(service)) return 1;
+
+  return 0;
+}
diff --git a/aidl/tests/aidl_test_client_file_descriptors.cpp b/aidl/tests/aidl_test_client_file_descriptors.cpp
new file mode 100644
index 0000000..b5913a3
--- /dev/null
+++ b/aidl/tests/aidl_test_client_file_descriptors.cpp
@@ -0,0 +1,171 @@
+/*
+ * 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_test_client_file_descriptors.h"
+
+#include <iostream>
+#include <vector>
+
+ #include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <android-base/unique_fd.h>
+
+// libbase
+using android::base::unique_fd;
+
+// libutils:
+using android::sp;
+
+// libbinder:
+using android::binder::Status;
+
+// generated
+using android::aidl::tests::ITestService;
+
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::string;
+using std::vector;
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+#define FdByName(_fd) #_fd, _fd
+
+bool DoWrite(const string& name, const unique_fd& fd, const string& buf) {
+  int wrote;
+
+  while ((wrote = write(fd.get(), buf.data(), buf.size())) < 0 && errno == EINTR);
+
+  if (wrote == (signed)buf.size()) {
+    return true;
+  }
+
+  if (wrote < 0) {
+    cerr << "Error writing to file descriptor '" << name << "': "
+        << strerror(errno) << endl;
+  } else {
+    cerr << "File descriptor '" << name << "'accepted short data." << endl;
+  }
+
+  return false;
+}
+
+bool DoRead(const string& name, const unique_fd& fd, const string& expected) {
+  size_t length = expected.size();
+  int got;
+  string buf;
+  buf.resize(length);
+
+  while ((got = read(fd.get(), &buf[0], length)) < 0 && errno == EINTR);
+
+  if (got < 0) {
+    cerr << "Error reading from '" << name << "': " << strerror(errno) << endl;
+    return false;
+  }
+
+  if (buf != expected) {
+    cerr << "Expected '" << expected << "' got '" << buf << "'" << endl;
+    return false;
+  }
+
+  return true;
+}
+
+bool DoPipe(unique_fd* read_side, unique_fd* write_side) {
+  int fds[2];
+  unique_fd return_fd;
+
+  if (pipe(fds)) {
+    cout << "Error creating pipes: " << strerror(errno) << endl;
+    return false;
+  }
+
+  read_side->reset(fds[0]);
+  write_side->reset(fds[1]);
+  return true;
+}
+
+bool ConfirmFileDescriptors(const sp<ITestService>& s) {
+  Status status;
+  cout << "Confirming passing and returning file descriptors works." << endl;
+
+  unique_fd return_fd;
+  unique_fd read_fd;
+  unique_fd write_fd;
+
+  if (!DoPipe(&read_fd, &write_fd)) {
+    return false;
+  }
+
+  status = s->RepeatFileDescriptor(write_fd, &return_fd);
+
+  if (!status.isOk()) {
+    cerr << "Could not repeat file descriptors." << endl;
+    return false;
+  }
+
+  /* A note on some of the spookier stuff going on here: IIUC writes to pipes
+   * should be atomic and non-blocking so long as the total size doesn't exceed
+   * PIPE_BUF. We thus play a bit fast and loose with failure modes here.
+   */
+
+  bool ret =
+      DoWrite(FdByName(return_fd), "ReturnString") &&
+      DoRead(FdByName(read_fd), "ReturnString");
+
+  return ret;
+}
+
+bool ConfirmFileDescriptorArrays(const sp<ITestService>& s) {
+  Status status;
+  cout << "Confirming passing and returning file descriptor arrays works." << endl;
+
+  vector<unique_fd> array;
+  array.resize(2);
+
+  if (!DoPipe(&array[0], &array[1])) {
+    return false;
+  }
+
+  vector<unique_fd> repeated;
+  vector<unique_fd> reversed;
+
+  status = s->ReverseFileDescriptorArray(array, &repeated, &reversed);
+
+  if (!status.isOk()) {
+    cerr << "Could not reverse file descriptor array." << endl;
+    return false;
+  }
+
+  bool ret =
+      DoWrite(FdByName(array[1]), "First") &&
+      DoWrite(FdByName(repeated[1]), "Second") &&
+      DoWrite(FdByName(reversed[0]), "Third") &&
+      DoRead(FdByName(reversed[1]), "FirstSecondThird");
+
+  return ret;
+}
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/aidl_test_client_file_descriptors.h b/aidl/tests/aidl_test_client_file_descriptors.h
new file mode 100644
index 0000000..306e551
--- /dev/null
+++ b/aidl/tests/aidl_test_client_file_descriptors.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AIDL_TESTS_CLIENT_FILE_DESCRIPTORS_H
+#define ANDROID_AIDL_TESTS_CLIENT_FILE_DESCRIPTORS_H
+
+#include <utils/StrongPointer.h>
+
+#include "android/aidl/tests/ITestService.h"
+
+// Tests for passing and returning file descriptors.
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+bool ConfirmFileDescriptors(const sp<ITestService>& s);
+bool ConfirmFileDescriptorArrays(const sp<ITestService>& s);
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+
+#endif  // ANDROID_AIDL_TESTS_CLIENT_FILE_DESCRIPTORS_H
diff --git a/aidl/tests/aidl_test_client_nullables.cpp b/aidl/tests/aidl_test_client_nullables.cpp
new file mode 100644
index 0000000..805827c
--- /dev/null
+++ b/aidl/tests/aidl_test_client_nullables.cpp
@@ -0,0 +1,280 @@
+/*
+ * 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_test_client_nullables.h"
+
+#include <utils/String16.h>
+
+#include <iostream>
+#include <memory>
+#include <string>
+#include <vector>
+
+// libutils:
+using android::sp;
+using android::String16;
+
+// libbinder:
+using android::binder::Status;
+
+// generated
+using android::aidl::tests::ITestService;
+using android::aidl::tests::SimpleParcelable;
+
+using std::string;
+using std::unique_ptr;
+using std::vector;
+using std::cout;
+using std::cerr;
+using std::endl;
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+namespace {
+template<typename T>
+bool ValuesEqual(const unique_ptr<T>& in, const unique_ptr<T>& out) {
+  return *in == *out;
+}
+
+template<>
+bool ValuesEqual<vector<unique_ptr<String16>>>(
+    const unique_ptr<vector<unique_ptr<String16>>>& in,
+    const unique_ptr<vector<unique_ptr<String16>>>& out) {
+  if (!in) {
+    return !out;
+  }
+
+  if (!out) {
+    return false;
+  }
+
+  if (in->size() != out->size()) {
+    return false;
+  }
+
+  for (size_t i = 0; i < in->size(); i++) {
+    const unique_ptr<String16>& a = (*in)[i];
+    const unique_ptr<String16>& b = (*out)[i];
+
+    if (!(a || b)) {
+      continue;
+    }
+
+    if (!(a && b)) {
+      return false;
+    }
+
+    if (*a != *b) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+template<typename T>
+bool ConfirmNullableType(const sp<ITestService>& s, const string& type_name,
+                         unique_ptr<T> in,
+                         Status(ITestService::*func)(const unique_ptr<T>&,
+                                                     unique_ptr<T>*)) {
+  cout << "... Confirming nullables for " << type_name << " ..." << endl;
+  Status status;
+  unique_ptr<T> out;
+
+  status = (*s.*func)(in, &out);
+
+  if (!status.isOk()) {
+    cerr << "Could not repeat nullable " << type_name << "." << endl;
+    return false;
+  }
+
+  if (!out) {
+    cerr << "Got back null when repeating " << type_name << "." << endl;
+    return false;
+  }
+
+  if (!ValuesEqual(in, out)) {
+    cerr << "Got back a non-matching value when repeating " << type_name
+         << "." << endl;
+    return false;
+  }
+
+  in.reset();
+  status = (*s.*func)(in, &out);
+
+  if (!status.isOk()) {
+    cerr << "Could not repeat null as " << type_name << "." << endl;
+    return false;
+  }
+
+  if (out) {
+    cerr << "Got back a value when sent null for " << type_name << "."
+         << endl;
+    return false;
+  }
+
+  return true;
+}
+
+bool CheckAppropriateIBinderHandling(const sp<ITestService>& s) {
+
+  Status status;
+  sp<IBinder> binder = new BBinder();
+  sp<IBinder> null_binder = nullptr;
+  unique_ptr<vector<sp<IBinder>>> list_with_nulls(
+      new vector<sp<IBinder>>{binder, null_binder});
+  unique_ptr<vector<sp<IBinder>>> list_without_nulls(
+      new vector<sp<IBinder>>{binder, binder});
+
+  // Methods without @nullable throw up when given null binders
+  if (s->TakesAnIBinder(null_binder).exceptionCode() !=
+      binder::Status::EX_NULL_POINTER) {
+    cerr << "Did not receive expected null exception on line: "
+         << __LINE__ << endl;
+    return false;
+  }
+  if (s->TakesAnIBinderList(*list_with_nulls).exceptionCode() !=
+      binder::Status::EX_NULL_POINTER) {
+    cerr << "Did not receive expected null exception on line: "
+         << __LINE__ << endl;
+    return false;
+  }
+
+  // But those same methods are fine with valid binders
+  if (!s->TakesAnIBinder(binder).isOk()) {
+    cerr << "Received unexpected exception on line "
+         << __LINE__ << endl;
+    return false;
+  }
+  if (!s->TakesAnIBinderList(*list_without_nulls).isOk()) {
+    cerr << "Received unexpected exception on line "
+         << __LINE__ << endl;
+    return false;
+  }
+
+  // And methods with @nullable don't care.
+  if (!s->TakesANullableIBinder(null_binder).isOk()) {
+    cerr << "Received unexpected exception on line "
+         << __LINE__ << endl;
+    return false;
+  }
+  if (!s->TakesANullableIBinder(binder).isOk()) {
+    cerr << "Received unexpected exception on line "
+         << __LINE__ << endl;
+    return false;
+  }
+  if (!s->TakesANullableIBinderList(list_with_nulls).isOk()) {
+    cerr << "Received unexpected exception on line "
+         << __LINE__ << endl;
+    return false;
+  }
+  if (!s->TakesANullableIBinderList(list_without_nulls).isOk()) {
+    cerr << "Received unexpected exception on line "
+         << __LINE__ << endl;
+    return false;
+  }
+
+  return true;
+}
+
+bool CheckAppropriateIInterfaceHandling(const sp<ITestService>& s) {
+
+  sp<INamedCallback> callback;
+  if (!s->GetCallback(false, &callback).isOk()) {
+    cerr << "Received unexpected exception on line "
+         << __LINE__ << endl;
+    return false;
+  }
+  if (callback.get() == nullptr) {
+    cerr << "Expected to receive a non-null binder on line: "
+         << __LINE__ << endl;
+    return false;
+  }
+  if (!s->GetCallback(true, &callback).isOk()) {
+    cerr << "Received unexpected exception on line "
+         << __LINE__ << endl;
+    return false;
+  }
+  if (callback.get() != nullptr) {
+    cerr << "Expected to receive a null binder on line: "
+         << __LINE__ << endl;
+    return false;
+  }
+  return true;
+}
+
+}  // namespace
+
+bool ConfirmNullables(const sp<ITestService>& s) {
+  Status status;
+  cout << "Confirming passing and returning nullable values works." << endl;
+
+  if (!ConfirmNullableType(s, "integer array",
+                           unique_ptr<vector<int32_t>>(
+                               new vector<int32_t>({1,2,3})),
+                           &ITestService::RepeatNullableIntArray)) {
+    return false;
+  }
+
+  if (!ConfirmNullableType(s, "string",
+                           unique_ptr<String16>(new String16("Blooob")),
+                           &ITestService::RepeatNullableString)) {
+    return false;
+  }
+
+  unique_ptr<vector<unique_ptr<String16>>> test_string_array(
+      new vector<unique_ptr<String16>>());
+  test_string_array->push_back(unique_ptr<String16>(new String16("Wat")));
+  test_string_array->push_back(unique_ptr<String16>(
+      new String16("Blooob")));
+  test_string_array->push_back(unique_ptr<String16>(new String16("Wat")));
+  test_string_array->push_back(unique_ptr<String16>(nullptr));
+  test_string_array->push_back(unique_ptr<String16>(new String16("YEAH")));
+  test_string_array->push_back(unique_ptr<String16>(
+      new String16("OKAAAAY")));
+
+  if (!ConfirmNullableType(s, "string array", std::move(test_string_array),
+                           &ITestService::RepeatNullableStringList)) {
+    return false;
+  }
+
+  if (!ConfirmNullableType(s, "parcelable",
+                           unique_ptr<SimpleParcelable>(
+                               new SimpleParcelable("Booya", 42)),
+                           &ITestService::RepeatNullableParcelable)) {
+    return false;
+  }
+
+  if (!CheckAppropriateIBinderHandling(s)) {
+    cerr << "Handled null IBinders poorly." << endl;
+    return false;
+  }
+
+  if (!CheckAppropriateIInterfaceHandling(s)) {
+    cerr << "Handled nullable IInterface instances poorly." << endl;
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/aidl_test_client_nullables.h b/aidl/tests/aidl_test_client_nullables.h
new file mode 100644
index 0000000..807aa4e
--- /dev/null
+++ b/aidl/tests/aidl_test_client_nullables.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AIDL_TESTS_CLIENT_NULLABLES_H
+#define ANDROID_AIDL_TESTS_CLIENT_NULLABLES_H
+
+#include <utils/StrongPointer.h>
+
+#include "android/aidl/tests/ITestService.h"
+
+// Tests for passing and returning file descriptors.
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+bool ConfirmNullables(const sp<ITestService>& s);
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+
+#endif  // ANDROID_AIDL_TESTS_CLIENT_NULLABLES_H
diff --git a/aidl/tests/aidl_test_client_parcelables.cpp b/aidl/tests/aidl_test_client_parcelables.cpp
new file mode 100644
index 0000000..09e7f0a
--- /dev/null
+++ b/aidl/tests/aidl_test_client_parcelables.cpp
@@ -0,0 +1,151 @@
+/*
+ * 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_test_client_parcelables.h"
+
+#include <iostream>
+#include <vector>
+
+// libutils:
+using android::sp;
+
+// libbinder:
+using android::binder::Status;
+
+// generated
+using android::aidl::tests::ITestService;
+using android::aidl::tests::SimpleParcelable;
+using android::os::PersistableBundle;
+
+using std::cout;
+using std::endl;
+using std::vector;
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+bool ConfirmSimpleParcelables(const sp<ITestService>& s) {
+  cout << "Confirming passing and returning SimpleParcelable objects works."
+       << endl;
+
+  SimpleParcelable input("Booya", 42);
+  SimpleParcelable out_param, returned;
+  Status status = s->RepeatSimpleParcelable(input, &out_param, &returned);
+  if (!status.isOk()) {
+    cout << "Binder call failed." << endl;
+    return false;
+  }
+  if (input != out_param || input != returned) {
+    cout << "Failed to repeat SimpleParcelable objects." << endl;
+    return false;
+  }
+
+  cout << "Attempting to reverse an array of SimpleParcelable objects." << endl;
+  const vector<SimpleParcelable> original{SimpleParcelable("first", 0),
+                                          SimpleParcelable("second", 1),
+                                          SimpleParcelable("third", 2)};
+  vector<SimpleParcelable> repeated;
+  vector<SimpleParcelable> reversed;
+  status = s->ReverseSimpleParcelables(original, &repeated, &reversed);
+  if (!status.isOk()) {
+    cout << "Binder call failed." << endl;
+    return false;
+  }
+  std::reverse(reversed.begin(), reversed.end());
+  if (repeated != original || reversed != original) {
+    cout << "Failed to reverse an array of SimpleParcelable objects." << endl;
+    return false;
+  }
+
+  return true;
+}
+
+bool ConfirmPersistableBundles(const sp<ITestService>& s) {
+  cout << "Confirming passing and returning PersistableBundle objects works."
+       << endl;
+
+  PersistableBundle empty_bundle, returned;
+  Status status = s->RepeatPersistableBundle(empty_bundle, &returned);
+  if (!status.isOk()) {
+    cout << "Binder call failed for empty PersistableBundle." << endl;
+    return false;
+  }
+  if (empty_bundle != returned) {
+    cout << "Failed to repeat empty PersistableBundle." << endl;
+    return false;
+  }
+
+  PersistableBundle non_empty_bundle;
+  non_empty_bundle.putBoolean(String16("test_bool"), false);
+  non_empty_bundle.putInt(String16("test_int"), 33);
+  non_empty_bundle.putLong(String16("test_long"), 34359738368l);
+  non_empty_bundle.putDouble(String16("test_double"), 1.1);
+  non_empty_bundle.putString(String16("test_string"), String16("Woot!"));
+  non_empty_bundle.putBooleanVector(String16("test_bool_vector"),
+                                    {true, false, true});
+  non_empty_bundle.putIntVector(String16("test_int_vector"), {33, 44, 55, 142});
+  non_empty_bundle.putLongVector(String16("test_long_vector"),
+                                 {34l, 8371l, 34359738375l});
+  non_empty_bundle.putDoubleVector(String16("test_double_vector"), {2.2, 5.4});
+  non_empty_bundle.putStringVector(String16("test_string_vector"),
+                                   {String16("hello"), String16("world!")});
+  PersistableBundle nested_bundle;
+  nested_bundle.putInt(String16("test_nested_int"), 345);
+  non_empty_bundle.putPersistableBundle(String16("test_persistable_bundle"),
+                                        nested_bundle);
+
+  status = s->RepeatPersistableBundle(non_empty_bundle, &returned);
+  if (!status.isOk()) {
+    cout << "Binder call failed. " << endl;
+    return false;
+  }
+  if (non_empty_bundle != returned) {
+    cout << "Failed to repeat PersistableBundle object." << endl;
+    return false;
+  }
+
+  cout << "Attempting to reverse an array of PersistableBundle objects."
+       << endl;
+  PersistableBundle first;
+  PersistableBundle second;
+  PersistableBundle third;
+  first.putInt(String16("test_int"), 1231);
+  second.putLong(String16("test_long"), 222222l);
+  third.putDouble(String16("test_double"), 10.8);
+  const vector<PersistableBundle> original{first, second, third};
+
+  vector<PersistableBundle> repeated;
+  vector<PersistableBundle> reversed;
+  status = s->ReversePersistableBundles(original, &repeated, &reversed);
+  if (!status.isOk()) {
+    cout << "Binder call failed." << endl;
+    return false;
+  }
+  std::reverse(reversed.begin(), reversed.end());
+  if (repeated != original || reversed != original) {
+    cout << "Failed to reverse an array of PersistableBundle objects." << endl;
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/aidl_test_client_parcelables.h b/aidl/tests/aidl_test_client_parcelables.h
new file mode 100644
index 0000000..9616e02
--- /dev/null
+++ b/aidl/tests/aidl_test_client_parcelables.h
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AIDL_TESTS_CLIENT_PARCELABLES_H
+#define ANDROID_AIDL_TESTS_CLIENT_PARCELABLES_H
+
+#include <utils/StrongPointer.h>
+
+#include "android/aidl/tests/ITestService.h"
+
+// Tests for passing and returning parcelable types.
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+bool ConfirmSimpleParcelables(const sp<ITestService>& s);
+bool ConfirmPersistableBundles(const sp<ITestService>& s);
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+
+#endif  // ANDROID_AIDL_TESTS_CLIENT_PARCELABLES_H
diff --git a/aidl/tests/aidl_test_client_primitives.cpp b/aidl/tests/aidl_test_client_primitives.cpp
new file mode 100644
index 0000000..6f70f43
--- /dev/null
+++ b/aidl/tests/aidl_test_client_primitives.cpp
@@ -0,0 +1,231 @@
+/*
+ * 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_test_client_primitives.h"
+
+#include <iostream>
+#include <vector>
+
+#include <utils/String16.h>
+#include <utils/String8.h>
+
+#include "android/aidl/tests/INamedCallback.h"
+
+#include "test_helpers.h"
+
+// libutils:
+using android::sp;
+using android::String16;
+using android::String8;
+
+// libbinder:
+using android::binder::Status;
+
+// generated
+using android::aidl::tests::ITestService;
+using android::aidl::tests::INamedCallback;
+
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::vector;
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+bool ConfirmPrimitiveRepeat(const sp<ITestService>& s) {
+  cout << "Confirming passing and returning primitives works." << endl;
+
+  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)
+      ) {
+    return false;
+  }
+
+  vector<String16> inputs = {
+      String16("Deliver us from evil."),
+      String16(),
+      String16("\0\0", 2),
+      // This is actually two unicode code points:
+      //   U+10437: The 'small letter yee' character in the deseret alphabet
+      //   U+20AC: A euro sign
+      String16("\xD8\x01\xDC\x37\x20\xAC"),
+      ITestService::STRING_TEST_CONSTANT(),
+      ITestService::STRING_TEST_CONSTANT2(),
+  };
+  for (const auto& input : inputs) {
+    String16 reply;
+    Status status = s->RepeatString(input, &reply);
+    if (!status.isOk() || input != reply) {
+      cerr << "Failed while requesting service to repeat String16=\""
+           << String8(input).string()
+           << "\". Got status=" << status.toString8() << endl;
+      return false;
+    }
+  }
+  return true;
+}
+
+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}) ||
+      !ReverseArray(s, &ITestService::ReverseString,
+                    {String16{"f"}, String16{"a"}, String16{"b"}})) {
+    return false;
+  }
+
+  return true;
+}
+
+bool ConfirmReverseLists(const sp<ITestService>& s) {
+  cout << "Confirming passing and returning List<T> works." << endl;
+
+  if (!ReverseArray(s, &ITestService::ReverseStringList,
+                    {String16{"f"}, String16{"a"}, String16{"b"}})) {
+    return false;
+  }
+
+  return true;
+}
+
+bool ConfirmReverseBinderLists(const sp<ITestService>& s) {
+  Status status;
+  cout << "Confirming passing and returning List<T> works with binders." << endl;
+
+  vector<String16> names = {
+    String16{"Larry"},
+    String16{"Curly"},
+    String16{"Moe"}
+  };
+
+  vector<sp<IBinder>> input;
+
+  for (int i = 0; i < 3; i++) {
+    sp<INamedCallback> got;
+
+    status = s->GetOtherTestService(names[i], &got);
+    if (!status.isOk()) {
+      cerr << "Could not retrieve service for test." << endl;
+      return false;
+    }
+
+    input.push_back(INamedCallback::asBinder(got));
+  }
+
+  vector<sp<IBinder>> output;
+  vector<sp<IBinder>> reversed;
+
+  status = s->ReverseNamedCallbackList(input, &output, &reversed);
+  if (!status.isOk()) {
+    cerr << "Failed to reverse named callback list." << endl;
+  }
+
+  if (output.size() != 3) {
+    cerr << "ReverseNamedCallbackList gave repetition with wrong length." << endl;
+    return false;
+  }
+
+  if (reversed.size() != 3) {
+    cerr << "ReverseNamedCallbackList gave reversal with wrong length." << endl;
+    return false;
+  }
+
+  for (int i = 0; i < 3; i++) {
+    String16 ret;
+    sp<INamedCallback> named_callback =
+        android::interface_cast<INamedCallback>(output[i]);
+    status = named_callback->GetName(&ret);
+
+    if (!status.isOk()) {
+      cerr << "Could not query INamedCallback from output" << endl;
+      return false;
+    }
+
+    if (ret != names[i]) {
+      cerr << "Output had wrong INamedCallback" << endl;
+      return false;
+    }
+  }
+
+  for (int i = 0; i < 3; i++) {
+    String16 ret;
+    sp<INamedCallback> named_callback =
+        android::interface_cast<INamedCallback>(reversed[i]);
+    status = named_callback->GetName(&ret);
+
+    if (!status.isOk()) {
+      cerr << "Could not query INamedCallback from reversed output" << endl;
+      return false;
+    }
+
+    if (ret != names[2 - i]) {
+      cerr << "Reversed output had wrong INamedCallback" << endl;
+      return false;
+    }
+  }
+
+  return true;
+}
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/aidl_test_client_primitives.h b/aidl/tests/aidl_test_client_primitives.h
new file mode 100644
index 0000000..f9b39da
--- /dev/null
+++ b/aidl/tests/aidl_test_client_primitives.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AIDL_TESTS_CLIENT_PRIMITIVES_H
+#define ANDROID_AIDL_TESTS_CLIENT_PRIMITIVES_H
+
+#include <utils/StrongPointer.h>
+
+#include "android/aidl/tests/ITestService.h"
+
+// Tests for passing and returning primitive types defined in the AIDL docs.
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+bool ConfirmPrimitiveRepeat(const sp<ITestService>& s);
+bool ConfirmReverseArrays(const android::sp<ITestService>& s);
+bool ConfirmReverseLists(const android::sp<ITestService>& s);
+bool ConfirmReverseBinderLists(const android::sp<ITestService>& s);
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+
+#endif  // ANDROID_AIDL_TESTS_CLIENT_PRIMITIVES_H
diff --git a/aidl/tests/aidl_test_client_service_exceptions.cpp b/aidl/tests/aidl_test_client_service_exceptions.cpp
new file mode 100644
index 0000000..3f1f374
--- /dev/null
+++ b/aidl/tests/aidl_test_client_service_exceptions.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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_test_client_service_exceptions.h"
+
+#include <iostream>
+
+#include "binder/Status.h"
+
+using android::binder::Status;
+using std::cout;
+using std::endl;
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+bool ConfirmServiceSpecificExceptions(const sp<ITestService>& s) {
+  cout << "Confirming application exceptions work" << endl;
+
+  for (int32_t i = -1; i < 2; ++i) {
+    Status status = s->ThrowServiceException(i);
+    if (status.exceptionCode() != Status::EX_SERVICE_SPECIFIC ||
+        status.serviceSpecificErrorCode() != i) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/aidl_test_client_service_exceptions.h b/aidl/tests/aidl_test_client_service_exceptions.h
new file mode 100644
index 0000000..e4a1dd3
--- /dev/null
+++ b/aidl/tests/aidl_test_client_service_exceptions.h
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AIDL_TESTS_CLIENT_SERVICE_EXCEPTIONS_H
+#define ANDROID_AIDL_TESTS_CLIENT_SERVICE_EXCEPTIONS_H
+
+#include <utils/StrongPointer.h>
+
+#include "android/aidl/tests/ITestService.h"
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+// Tests for service specific exception support.
+bool ConfirmServiceSpecificExceptions(const sp<ITestService>& s);
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+
+#endif  // ANDROID_AIDL_TESTS_CLIENT_SERVICE_EXCEPTIONS_H
diff --git a/aidl/tests/aidl_test_client_utf8_strings.cpp b/aidl/tests/aidl_test_client_utf8_strings.cpp
new file mode 100644
index 0000000..216aef7
--- /dev/null
+++ b/aidl/tests/aidl_test_client_utf8_strings.cpp
@@ -0,0 +1,167 @@
+/*
+ * 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_test_client_utf8_strings.h"
+
+#include <android-base/logging.h>
+#include <binder/Status.h>
+#include <utils/StrongPointer.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "android/aidl/tests/ITestService.h"
+#include "test_helpers.h"
+
+// libutils:
+using android::sp;
+
+// libbinder:
+using android::binder::Status;
+
+// generated
+using android::aidl::tests::ITestService;
+
+using std::unique_ptr;
+using std::string;
+using std::vector;
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+bool ConfirmUtf8InCppStringRepeat(const sp<ITestService>& s) {
+  const vector<string> utf8_inputs = {
+    string("Deliver us from evil."),
+    string(),
+    string("\0\0", 2),
+    // Similarly, the utf8 encodings of the small letter yee and euro sign.
+    string("\xF0\x90\x90\xB7\xE2\x82\xAC"),
+  };
+  LOG(INFO) << "Confirming repeating utf8 strings works.";
+
+  for (const auto& input : utf8_inputs) {
+    string reply;
+    Status status = s->RepeatUtf8CppString(input, &reply);
+    if (!status.isOk() || input != reply) {
+      LOG(ERROR) << "Failed while requesting service to repeat utf8 string=\""
+                 << input
+                 << "\". Got status=" << status.toString8()
+                 << " and output=" << reply;
+      return false;
+    }
+  }
+
+  unique_ptr<string> ret;
+  Status repeat_null_status = s->RepeatNullableUtf8CppString(nullptr, &ret);
+  if (!repeat_null_status.isOk() || ret) {
+    LOG(ERROR) << "RepeatNullableUtf8CppString(null) did not return null";
+    return false;
+  }
+
+  for (const auto& input : utf8_inputs) {
+    unique_ptr<string> reply;
+    Status status = s->RepeatNullableUtf8CppString(
+        unique_ptr<string>(new string(input)), &reply);
+    if (!status.isOk()) {
+      LOG(ERROR) << "Got status=" << status.toString8() << " while repeating "
+                    "nullable utf8 string " << input;
+      return false;
+    }
+    if (!reply) {
+      LOG(ERROR) << "Got null reply while repeating nullable utf8 string "
+                 << input;
+      return false;
+    }
+    if (input != *reply) {
+      LOG(ERROR) << "Failed while requesting service to repeat utf8 string=\""
+                 << input
+                 << "\". Got status=" << status.toString8()
+                 << " and output=" << *reply;
+      return false;
+    }
+  }
+
+  return true;
+}
+
+bool ConfirmUtf8InCppStringArrayReverse(const sp<ITestService>& s) {
+  LOG(INFO) << "Confirming passing and returning utf8 string arrays works.";
+  if (!ReverseArray(s, &ITestService::ReverseUtf8CppString,
+                    {string{"a"}, string{}, string{"\xc3\xb8"}})) {
+    return false;
+  }
+
+  return true;
+}
+
+bool ConfirmUtf8InCppStringListReverse(const sp<ITestService>& s) {
+  LOG(INFO) << "Confirming reversing a list of utf8 strings works";
+  unique_ptr<vector<unique_ptr<string>>> input, reversed, repeated;
+  Status status = s->ReverseUtf8CppStringList(input, &reversed, &repeated);
+  if (!status.isOk() || reversed || repeated) {
+    LOG(ERROR) << "Reversing null list of utf8 strings failed.";
+    return false;
+  }
+
+  input.reset(new vector<unique_ptr<string>>);
+  input->emplace_back(new string("Deliver us from evil."));
+  input->emplace_back(nullptr);
+  input->emplace_back(new string("\xF0\x90\x90\xB7\xE2\x82\xAC"));
+
+  status = s->ReverseUtf8CppStringList(input, &repeated, &reversed);
+  if (!status.isOk() || !reversed || !repeated) {
+    LOG(ERROR) << "Reversing list of utf8 strings failed.";
+    return false;
+  }
+  if (reversed->size() != input->size() || repeated->size() != input->size()) {
+    LOG(ERROR) << "Bad output sizes.";
+    return false;
+  }
+
+  for (size_t i = 0; i < input->size(); ++i) {
+    const string* input_str = (*input)[i].get();
+    const string* repeated_str = (*repeated)[i].get();
+    const string* reversed_str = (*reversed)[(reversed->size() - 1) - i].get();
+    if (!input_str) {
+      if(repeated_str || reversed_str) {
+        LOG(ERROR) << "Expected null values, but got non-null.";
+        return false;
+      }
+      // 3 nullptrs to strings.  No need to compare values.
+      continue;
+    }
+    if (!repeated_str || !reversed_str) {
+      LOG(ERROR) << "Expected non-null values, but got null.";
+      return false;
+    }
+    if (*input_str != *repeated_str || *input_str != *reversed_str) {
+      LOG(ERROR) << "Expected '" << *input_str << "' but got "
+                 << "repeated='" << *repeated_str << "' and "
+                 << "reversed='" << *reversed_str;
+      return false;
+    }
+  }
+  return true;
+}
+
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/aidl_test_client_utf8_strings.h b/aidl/tests/aidl_test_client_utf8_strings.h
new file mode 100644
index 0000000..a362fd5
--- /dev/null
+++ b/aidl/tests/aidl_test_client_utf8_strings.h
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_AIDL_TESTS_CLIENT_UTF8_STRINGS_H
+#define ANDROID_AIDL_TESTS_CLIENT_UTF8_STRINGS_H
+
+#include <utils/StrongPointer.h>
+
+#include "android/aidl/tests/ITestService.h"
+
+// Tests for passing and returning utf8 strings.
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+bool ConfirmUtf8InCppStringRepeat(
+    const android::sp<android::aidl::tests::ITestService>& s);
+bool ConfirmUtf8InCppStringArrayReverse(
+    const android::sp<android::aidl::tests::ITestService>& s);
+bool ConfirmUtf8InCppStringListReverse(
+    const android::sp<android::aidl::tests::ITestService>& s);
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+
+#endif  // ANDROID_AIDL_TESTS_CLIENT_UTF8_STRINGS_H
+
diff --git a/aidl/tests/aidl_test_sentinel_searcher.cpp b/aidl/tests/aidl_test_sentinel_searcher.cpp
new file mode 100644
index 0000000..e260366
--- /dev/null
+++ b/aidl/tests/aidl_test_sentinel_searcher.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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 <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <errno.h>
+#include <time.h>
+#include <unistd.h>
+
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::getline;
+using std::ifstream;
+using std::string;
+using std::vector;
+
+namespace {
+
+bool ReadLines(const string& input_file_path, vector<string>* lines) {
+  ifstream watched_file(input_file_path);
+  if (!watched_file.is_open()) {
+    cerr << "Unable to open input file: " << input_file_path << endl;
+    return false;
+  }
+
+  string line;
+  while (getline(watched_file, line)) {
+    lines->push_back(line);
+  }
+  watched_file.close();
+  return true;
+}
+
+bool HasSentinel(const vector<string>& lines, const string& sentinel) {
+  for (const auto& line : lines) {
+    if (line.find(sentinel) != string::npos) {
+      return true;
+    }
+  }
+  return false;
+}
+
+}  // namespace
+
+int main(int argc, const char* argv[]) {
+  if (argc != 5) {
+    cerr << "Invalid usage." << endl;
+    cerr << argv[0]
+         << " <timeout in seconds>"
+         << " <input file path>"
+         << " <success sentinel>"
+         << " <failure sentinel>" << endl;
+    return -EINVAL;
+  }
+  const string timeout_as_str = argv[1];
+  const string input_file_path = argv[2];
+  const string success_sentinel = argv[3];
+  const string failure_sentinel = argv[4];
+
+  const int timeout_seconds = atoi(timeout_as_str.c_str());
+  if (timeout_seconds <= 0) {
+    cerr << "Invalid timeout value (in seconds): " << timeout_as_str << endl;
+    return -EINVAL;
+  }
+
+  int exit_code = 1;
+  const time_t start_time = time(nullptr);
+  vector<string> lines;
+  while (true) {
+    sleep(1);
+    if (time(nullptr) - start_time > timeout_seconds) {
+      cerr << "Timed out waiting for success/failure sentinel." << endl;
+      break;
+    }
+    // Ignore errors when reading lines.  The file may not immediately exist
+    // because it takes the Java process some time to create it.
+    lines.clear();
+    ReadLines(input_file_path, &lines);
+
+    if (HasSentinel(lines, success_sentinel)) {
+      exit_code = 0;
+      break;
+    }
+    if (HasSentinel(lines, failure_sentinel)) {
+      break;
+    }
+  }
+
+  cout << "Found output:" << endl;
+  for (const auto& line : lines) {
+    cout << "  " << line << endl;
+  }
+  return exit_code;
+}
diff --git a/aidl/tests/aidl_test_service.cpp b/aidl/tests/aidl_test_service.cpp
new file mode 100644
index 0000000..9e2304e
--- /dev/null
+++ b/aidl/tests/aidl_test_service.cpp
@@ -0,0 +1,459 @@
+/*
+ * 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 <map>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <unistd.h>
+
+#include <android-base/unique_fd.h>
+#include <binder/IInterface.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <binder/Status.h>
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/Looper.h>
+#include <utils/StrongPointer.h>
+
+#include "android/aidl/tests/BnTestService.h"
+#include "android/aidl/tests/ITestService.h"
+
+#include "android/aidl/tests/BnNamedCallback.h"
+#include "android/aidl/tests/INamedCallback.h"
+
+// Used implicitly.
+#undef LOG_TAG
+#define LOG_TAG "aidl_native_service"
+
+// libbase
+using android::base::unique_fd;
+
+// libutils:
+using android::Looper;
+using android::LooperCallback;
+using android::OK;
+using android::sp;
+using android::String16;
+
+// libbinder:
+using android::BnInterface;
+using android::defaultServiceManager;
+using android::IInterface;
+using android::IPCThreadState;
+using android::Parcel;
+using android::ProcessState;
+using android::binder::Status;
+
+// Generated code:
+using android::aidl::tests::BnNamedCallback;
+using android::aidl::tests::BnTestService;
+using android::aidl::tests::INamedCallback;
+using android::aidl::tests::SimpleParcelable;
+using android::os::PersistableBundle;
+
+// Standard library
+using std::map;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+namespace {
+
+class BinderCallback : public LooperCallback {
+ public:
+  BinderCallback() {}
+  ~BinderCallback() override {}
+
+  int handleEvent(int /* fd */, int /* events */, void* /* data */) override {
+    IPCThreadState::self()->handlePolledCommands();
+    return 1;  // Continue receiving callbacks.
+  }
+};
+
+class NamedCallback : public BnNamedCallback {
+ public:
+  explicit NamedCallback(String16 name) : name_(name) {}
+
+  Status GetName(String16* ret) {
+    *ret = name_;
+    return Status::ok();
+  }
+
+ private:
+  String16 name_;
+};
+
+class NativeService : public BnTestService {
+ public:
+  NativeService() {}
+  virtual ~NativeService() = default;
+
+  void LogRepeatedStringToken(const String16& token) {
+    ALOGI("Repeating '%s' of length=%zu", android::String8(token).string(),
+          token.size());
+  }
+
+  template <typename T>
+  void LogRepeatedToken(const T& token) {
+    std::ostringstream token_str;
+    token_str << token;
+    ALOGI("Repeating token %s", token_str.str().c_str());
+  }
+
+  Status RepeatBoolean(bool token, bool* _aidl_return) override {
+    LogRepeatedToken(token ? 1 : 0);
+    *_aidl_return = token;
+    return Status::ok();
+  }
+  Status RepeatByte(int8_t token, int8_t* _aidl_return) override {
+    LogRepeatedToken(token);
+    *_aidl_return = token;
+    return Status::ok();
+  }
+  Status RepeatChar(char16_t token, char16_t* _aidl_return) override {
+    LogRepeatedStringToken(String16(&token, 1));
+    *_aidl_return = token;
+    return Status::ok();
+  }
+  Status RepeatInt(int32_t token, int32_t* _aidl_return) override {
+    LogRepeatedToken(token);
+    *_aidl_return = token;
+    return Status::ok();
+  }
+  Status RepeatLong(int64_t token, int64_t* _aidl_return) override {
+    LogRepeatedToken(token);
+    *_aidl_return = token;
+    return Status::ok();
+  }
+  Status RepeatFloat(float token, float* _aidl_return) override {
+    LogRepeatedToken(token);
+    *_aidl_return = token;
+    return Status::ok();
+  }
+  Status RepeatDouble(double token, double* _aidl_return) override {
+    LogRepeatedToken(token);
+    *_aidl_return = token;
+    return Status::ok();
+  }
+  Status RepeatString(const String16& token, String16* _aidl_return) override {
+    LogRepeatedStringToken(token);
+    *_aidl_return = token;
+    return Status::ok();
+  }
+
+  Status RepeatSimpleParcelable(const SimpleParcelable& input,
+                                SimpleParcelable* repeat,
+                                SimpleParcelable* _aidl_return) override {
+    ALOGI("Repeated a SimpleParcelable %s", input.toString().c_str());
+    *repeat = input;
+    *_aidl_return = input;
+    return Status::ok();
+  }
+
+  Status RepeatPersistableBundle(const PersistableBundle& input,
+                                 PersistableBundle* _aidl_return) override {
+    ALOGI("Repeated a PersistableBundle");
+    *_aidl_return = input;
+    return Status::ok();
+  }
+
+  template <typename T>
+  Status ReverseArray(const vector<T>& input, vector<T>* repeated,
+                      vector<T>* _aidl_return) {
+    ALOGI("Reversing array of length %zu", input.size());
+    *repeated = input;
+    *_aidl_return = input;
+    std::reverse(_aidl_return->begin(), _aidl_return->end());
+    return Status::ok();
+  }
+
+  template<typename T>
+  Status RepeatNullable(const unique_ptr<T>& input,
+                        unique_ptr<T>* _aidl_return) {
+    ALOGI("Repeating nullable value");
+
+    _aidl_return->reset();
+    if (input) {
+      _aidl_return->reset(new T(*input));
+    }
+
+    return Status::ok();
+  }
+
+  Status ReverseBoolean(const vector<bool>& input,
+                        vector<bool>* repeated,
+                        vector<bool>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+  Status ReverseByte(const vector<uint8_t>& input,
+                     vector<uint8_t>* repeated,
+                     vector<uint8_t>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+  Status ReverseChar(const vector<char16_t>& input,
+                     vector<char16_t>* repeated,
+                     vector<char16_t>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+  Status ReverseInt(const vector<int32_t>& input,
+                    vector<int32_t>* repeated,
+                    vector<int32_t>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+  Status ReverseLong(const vector<int64_t>& input,
+                     vector<int64_t>* repeated,
+                     vector<int64_t>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+  Status ReverseFloat(const vector<float>& input,
+                      vector<float>* repeated,
+                      vector<float>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+  Status ReverseDouble(const vector<double>& input,
+                       vector<double>* repeated,
+                       vector<double>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+  Status ReverseString(const vector<String16>& input,
+                       vector<String16>* repeated,
+                       vector<String16>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+  Status ReverseSimpleParcelables(
+      const vector<SimpleParcelable>& input,
+      vector<SimpleParcelable>* repeated,
+      vector<SimpleParcelable>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+  Status ReversePersistableBundles(
+      const vector<PersistableBundle>& input,
+      vector<PersistableBundle>* repeated,
+      vector<PersistableBundle>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+
+  Status GetOtherTestService(const String16& name,
+                             sp<INamedCallback>* returned_service) override {
+    if (service_map_.find(name) == service_map_.end()) {
+      sp<INamedCallback> new_item(new NamedCallback(name));
+      service_map_[name] = new_item;
+    }
+
+    *returned_service = service_map_[name];
+    return Status::ok();
+  }
+
+  Status VerifyName(const sp<INamedCallback>& service, const String16& name,
+                    bool* returned_value) override {
+    String16 foundName;
+    Status status = service->GetName(&foundName);
+
+    if (status.isOk()) {
+      *returned_value = foundName == name;
+    }
+
+    return status;
+  }
+
+  Status ReverseStringList(const vector<String16>& input,
+                           vector<String16>* repeated,
+                           vector<String16>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+
+  Status ReverseNamedCallbackList(const vector<sp<IBinder>>& input,
+                                  vector<sp<IBinder>>* repeated,
+                                  vector<sp<IBinder>>* _aidl_return) override {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+
+  Status RepeatFileDescriptor(const unique_fd& read,
+                              unique_fd* _aidl_return) override {
+    ALOGE("Repeating file descriptor");
+    *_aidl_return = unique_fd(dup(read.get()));
+    return Status::ok();
+  }
+
+  Status ReverseFileDescriptorArray(const vector<unique_fd>& input,
+                                    vector<unique_fd>* repeated,
+                                    vector<unique_fd>* _aidl_return) override {
+    ALOGI("Reversing descriptor array of length %zu", input.size());
+    for (const auto& item : input) {
+      repeated->push_back(unique_fd(dup(item.get())));
+      _aidl_return->push_back(unique_fd(dup(item.get())));
+    }
+    std::reverse(_aidl_return->begin(), _aidl_return->end());
+    return Status::ok();
+  }
+
+  Status ThrowServiceException(int code) override {
+    return Status::fromServiceSpecificError(code);
+  }
+
+  Status RepeatNullableIntArray(const unique_ptr<vector<int32_t>>& input,
+                                unique_ptr<vector<int32_t>>* _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) {
+    ALOGI("Repeating nullable string list");
+    if (!input) {
+      _aidl_return->reset();
+      return Status::ok();
+    }
+
+    _aidl_return->reset(new vector<unique_ptr<String16>>);
+
+    for (const auto& item : *input) {
+      if (!item) {
+        (*_aidl_return)->emplace_back(nullptr);
+      } else {
+        (*_aidl_return)->emplace_back(new String16(*item));
+      }
+    }
+
+    return Status::ok();
+  }
+
+  Status RepeatNullableString(const unique_ptr<String16>& input,
+                              unique_ptr<String16>* _aidl_return) {
+    return RepeatNullable(input, _aidl_return);
+  }
+
+  Status RepeatNullableParcelable(const unique_ptr<SimpleParcelable>& input,
+                              unique_ptr<SimpleParcelable>* _aidl_return) {
+    return RepeatNullable(input, _aidl_return);
+  }
+
+  Status TakesAnIBinder(const sp<IBinder>& input) override {
+    (void)input;
+    return Status::ok();
+  }
+  Status TakesAnIBinderList(const vector<sp<IBinder>>& input) override {
+    (void)input;
+    return Status::ok();
+  }
+  Status TakesANullableIBinder(const sp<IBinder>& input) {
+    (void)input;
+    return Status::ok();
+  }
+  Status TakesANullableIBinderList(const unique_ptr<vector<sp<IBinder>>>& input) {
+    (void)input;
+    return Status::ok();
+  }
+
+  Status RepeatUtf8CppString(const string& token,
+                             string* _aidl_return) override {
+    ALOGI("Repeating utf8 string '%s' of length=%zu", token.c_str(), token.size());
+    *_aidl_return = token;
+    return Status::ok();
+  }
+
+  Status RepeatNullableUtf8CppString(
+      const unique_ptr<string>& token,
+      unique_ptr<string>* _aidl_return) override {
+    if (!token) {
+      ALOGI("Received null @utf8InCpp string");
+      return Status::ok();
+    }
+    ALOGI("Repeating utf8 string '%s' of length=%zu",
+          token->c_str(), token->size());
+    _aidl_return->reset(new string(*token));
+    return Status::ok();
+  }
+
+  Status ReverseUtf8CppString(const vector<string>& input,
+                              vector<string>* repeated,
+                              vector<string>* _aidl_return) {
+    return ReverseArray(input, repeated, _aidl_return);
+  }
+
+  Status ReverseUtf8CppStringList(
+      const unique_ptr<vector<unique_ptr<::string>>>& input,
+      unique_ptr<vector<unique_ptr<string>>>* repeated,
+      unique_ptr<vector<unique_ptr<string>>>* _aidl_return) {
+    if (!input) {
+      ALOGI("Received null list of utf8 strings");
+      return Status::ok();
+    }
+    _aidl_return->reset(new vector<unique_ptr<string>>);
+    repeated->reset(new vector<unique_ptr<string>>);
+
+    for (const auto& item : *input) {
+      (*repeated)->emplace_back(nullptr);
+      (*_aidl_return)->emplace_back(nullptr);
+      if (item) {
+        (*repeated)->back().reset(new string(*item));
+        (*_aidl_return)->back().reset(new string(*item));
+      }
+    }
+    std::reverse((*_aidl_return)->begin(), (*_aidl_return)->end());
+
+    return Status::ok();
+  }
+
+  Status GetCallback(bool return_null, sp<INamedCallback>* ret) {
+    if (!return_null) {
+      return GetOtherTestService(String16("ABT: always be testing"), ret);
+    }
+    return Status::ok();
+  }
+
+ private:
+  map<String16, sp<INamedCallback>> service_map_;
+};
+
+int Run() {
+  android::sp<NativeService> service = new NativeService;
+  sp<Looper> looper(Looper::prepare(0 /* opts */));
+
+  int binder_fd = -1;
+  ProcessState::self()->setThreadPoolMaxThreadCount(0);
+  IPCThreadState::self()->disableBackgroundScheduling(true);
+  IPCThreadState::self()->setupPolling(&binder_fd);
+  ALOGI("Got binder FD %d", binder_fd);
+  if (binder_fd < 0) return -1;
+
+  sp<BinderCallback> cb(new BinderCallback);
+  if (looper->addFd(binder_fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, cb,
+                    nullptr) != 1) {
+    ALOGE("Failed to add binder FD to Looper");
+    return -1;
+  }
+
+  defaultServiceManager()->addService(service->getInterfaceDescriptor(),
+                                      service);
+
+  ALOGI("Entering loop");
+  while (true) {
+    const int result = looper->pollAll(-1 /* timeoutMillis */);
+    ALOGI("Looper returned %d", result);
+  }
+  return 0;
+}
+
+}  // namespace
+
+int main(int /* argc */, char* /* argv */ []) {
+  return Run();
+}
diff --git a/aidl/tests/android/aidl/tests/INamedCallback.aidl b/aidl/tests/android/aidl/tests/INamedCallback.aidl
new file mode 100644
index 0000000..c295fef
--- /dev/null
+++ b/aidl/tests/android/aidl/tests/INamedCallback.aidl
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+package android.aidl.tests;
+
+interface INamedCallback {
+  String GetName();
+}
diff --git a/aidl/tests/android/aidl/tests/ITestService.aidl b/aidl/tests/android/aidl/tests/ITestService.aidl
new file mode 100644
index 0000000..4de6925
--- /dev/null
+++ b/aidl/tests/android/aidl/tests/ITestService.aidl
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+package android.aidl.tests;
+
+import android.aidl.tests.INamedCallback;
+import android.aidl.tests.SimpleParcelable;
+import android.os.PersistableBundle;
+
+interface ITestService {
+  // Test that constants are accessible
+  const int TEST_CONSTANT = 42;
+  const int TEST_CONSTANT2 = -42;
+  const int TEST_CONSTANT3 = +42;
+  const int TEST_CONSTANT4 = +4;
+  const int TEST_CONSTANT5 = -4;
+  const int TEST_CONSTANT6 = -0;
+  const int TEST_CONSTANT7 = +0;
+  const int TEST_CONSTANT8 = 0;
+  const int TEST_CONSTANT9 = 0x56;
+  const int TEST_CONSTANT10 = 0xa5;
+  const int TEST_CONSTANT11 = 0xFA;
+  const int TEST_CONSTANT12 = 0xffffffff;
+
+  const String STRING_TEST_CONSTANT = "foo";
+  const String STRING_TEST_CONSTANT2 = "bar";
+
+  // Test that primitives work as parameters and return types.
+  boolean RepeatBoolean(boolean token);
+  byte RepeatByte(byte token);
+  char RepeatChar(char token);
+  int RepeatInt(int token);
+  long RepeatLong(long token);
+  float RepeatFloat(float token);
+  double RepeatDouble(double token);
+  String RepeatString(String 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);
+
+  SimpleParcelable[]  ReverseSimpleParcelables(in SimpleParcelable[] input,
+                                               out SimpleParcelable[] repeated);
+  PersistableBundle[] ReversePersistableBundles(
+      in PersistableBundle[] input, out PersistableBundle[] repeated);
+
+  // Test that clients can send and receive Binders.
+  INamedCallback GetOtherTestService(String name);
+  boolean VerifyName(INamedCallback service, String name);
+
+  // Test that List<T> types work correctly.
+  List<String> ReverseStringList(in List<String> input,
+                                 out List<String> repeated);
+  List<IBinder> ReverseNamedCallbackList(in List<IBinder> input,
+                                         out List<IBinder> repeated);
+
+  FileDescriptor RepeatFileDescriptor(in FileDescriptor read);
+  FileDescriptor[] ReverseFileDescriptorArray(in FileDescriptor[] input,
+                                              out FileDescriptor[] repeated);
+
+  // Test that service specific exceptions work correctly.
+  void ThrowServiceException(int code);
+
+  // Test nullability
+  @nullable int[] RepeatNullableIntArray(in @nullable int[] input);
+  @nullable String RepeatNullableString(in @nullable String input);
+  @nullable List<String> RepeatNullableStringList(in @nullable List<String> input);
+  @nullable SimpleParcelable RepeatNullableParcelable(in @nullable SimpleParcelable input);
+
+  void TakesAnIBinder(in IBinder input);
+  void TakesAnIBinderList(in List<IBinder> input);
+  void TakesANullableIBinder(in @nullable IBinder input);
+  void TakesANullableIBinderList(in @nullable List<IBinder> input);
+
+  // Test utf8 decoding from utf16 wire format
+  @utf8InCpp String RepeatUtf8CppString(@utf8InCpp String token);
+  @nullable @utf8InCpp String RepeatNullableUtf8CppString(
+      @nullable @utf8InCpp String token);
+
+  @utf8InCpp String[]  ReverseUtf8CppString (in @utf8InCpp String[] input,
+                                             out @utf8InCpp String[] repeated);
+
+  @nullable @utf8InCpp List<String> ReverseUtf8CppStringList(
+      in @nullable @utf8InCpp List<String> input,
+      out @nullable @utf8InCpp List<String> repeated);
+
+  @nullable INamedCallback GetCallback(boolean return_null);
+}
diff --git a/aidl/tests/android/aidl/tests/SimpleParcelable.aidl b/aidl/tests/android/aidl/tests/SimpleParcelable.aidl
new file mode 100644
index 0000000..8573999
--- /dev/null
+++ b/aidl/tests/android/aidl/tests/SimpleParcelable.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.aidl.tests;
+
+parcelable SimpleParcelable cpp_header "tests/simple_parcelable.h";
diff --git a/aidl/tests/end_to_end_tests.cpp b/aidl/tests/end_to_end_tests.cpp
new file mode 100644
index 0000000..480bfd9
--- /dev/null
+++ b/aidl/tests/end_to_end_tests.cpp
@@ -0,0 +1,165 @@
+/*
+ * 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 <vector>
+
+#include <android-base/logging.h>
+#include <gtest/gtest.h>
+
+#include "aidl.h"
+#include "options.h"
+#include "tests/fake_io_delegate.h"
+#include "tests/test_data.h"
+#include "tests/test_util.h"
+
+using android::aidl::test::CanonicalNameToPath;
+using android::aidl::test::FakeIoDelegate;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+namespace android {
+namespace aidl {
+
+class EndToEndTest : public ::testing::Test {
+ protected:
+  virtual void SetUp() {
+  }
+
+  void AddStubAidls(const char** parcelables, const char** interfaces,
+                    const char* cpp_header=nullptr) {
+    for ( ; *parcelables; ++parcelables) {
+      io_delegate_.AddStubParcelable(
+          *parcelables, (cpp_header) ? cpp_header : "");
+    }
+    for ( ; *interfaces; ++interfaces) {
+      io_delegate_.AddStubInterface(*interfaces);
+    }
+  }
+
+  void CheckFileContents(const string& rel_path,
+                         const string& expected_content) {
+    string actual_content;
+    ASSERT_TRUE(io_delegate_.GetWrittenContents(rel_path, &actual_content))
+        << "Expected aidl to write to " << rel_path << " but it did not.";
+
+    if (actual_content == expected_content) {
+      return;  // success!
+    }
+
+    test::PrintDiff(expected_content, actual_content);
+    FAIL() << "Actual contents of " << rel_path
+           << " did not match expected content";
+  }
+
+  FakeIoDelegate io_delegate_;
+};
+
+TEST_F(EndToEndTest, IExampleInterface) {
+  using namespace ::android::aidl::test_data::example_interface;
+
+  JavaOptions options;
+  options.fail_on_parcelable_ = true;
+  options.import_paths_.push_back("");
+  options.input_file_name_ = CanonicalNameToPath(kCanonicalName, ".aidl");
+  options.output_file_name_ = kJavaOutputPath;
+  options.dep_file_name_ = "an/arbitrary/path/to/deps.P";
+
+  // Load up our fake file system with data.
+  io_delegate_.SetFileContents(options.input_file_name_, kInterfaceDefinition);
+  io_delegate_.AddCompoundParcelable("android.test.CompoundParcelable",
+                                     {"Subclass1", "Subclass2"});
+  AddStubAidls(kImportedParcelables, kImportedInterfaces);
+
+  // Check that we parse correctly.
+  EXPECT_EQ(android::aidl::compile_aidl_to_java(options, io_delegate_), 0);
+  CheckFileContents(kJavaOutputPath, kExpectedJavaOutput);
+  CheckFileContents(options.DependencyFilePath(), kExpectedJavaDepsOutput);
+}
+
+TEST_F(EndToEndTest, IPingResponderCpp) {
+  using namespace ::android::aidl::test_data::ping_responder;
+
+  const string input_path = CanonicalNameToPath(kCanonicalName, ".aidl");
+  const string output_file = kCppOutputPath;
+  const size_t argc = 6;
+  const char* cmdline[argc + 1] = {
+      "aidl-cpp", "-ddeps.P", "-I.", input_path.c_str(), kGenHeaderDir,
+      output_file.c_str(), nullptr
+  };
+  auto options = CppOptions::Parse(argc, cmdline);
+
+  // Set up input paths.
+  io_delegate_.SetFileContents(input_path, kInterfaceDefinition);
+  AddStubAidls(kImportedParcelables, kImportedInterfaces, kCppParcelableHeader);
+
+  // Check that we parse and generate code correctly.
+  EXPECT_EQ(android::aidl::compile_aidl_to_cpp(*options, io_delegate_), 0);
+  CheckFileContents(output_file, kExpectedCppOutput);
+  CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutput);
+  CheckFileContents(kGenClientHeaderPath, kExpectedBpHeaderOutput);
+  CheckFileContents(kGenServerHeaderPath, kExpectedBnHeaderOutput);
+  CheckFileContents(options->DependencyFilePath(), kExpectedCppDepsOutput);
+}
+
+TEST_F(EndToEndTest, StringConstantsInCpp) {
+  using namespace ::android::aidl::test_data::string_constants;
+
+  const string input_path = CanonicalNameToPath(kCanonicalName, ".aidl");
+  const string output_file = kCppOutputPath;
+  const size_t argc = 4;
+  const char* cmdline[argc + 1] = {
+      "aidl-cpp", input_path.c_str(), kGenHeaderDir,
+      output_file.c_str(), nullptr
+  };
+  auto options = CppOptions::Parse(argc, cmdline);
+
+  // Set up input paths.
+  io_delegate_.SetFileContents(input_path, kInterfaceDefinition);
+
+  // Check that we parse and generate code correctly.
+  EXPECT_EQ(android::aidl::compile_aidl_to_cpp(*options, io_delegate_), 0);
+  CheckFileContents(output_file, kExpectedCppOutput);
+  CheckFileContents(kGenInterfaceHeaderPath, kExpectedIHeaderOutput);
+}
+
+TEST_F(EndToEndTest, StringConstantsInJava) {
+  using namespace ::android::aidl::test_data::string_constants;
+
+  const string input_path = CanonicalNameToPath(kCanonicalName, ".aidl");
+  const string output_file = kJavaOutputPath;
+  const size_t argc = 4;
+  const char* cmdline[argc + 1] = {
+    "aidl",
+    "-b",
+    input_path.c_str(),
+    output_file.c_str(),
+    nullptr,
+};
+  auto options = JavaOptions::Parse(argc, cmdline);
+
+  // Load up our fake file system with data.
+  io_delegate_.SetFileContents(input_path, kInterfaceDefinition);
+
+  // Check that we parse correctly.
+  EXPECT_EQ(android::aidl::compile_aidl_to_java(*options, io_delegate_), 0);
+  CheckFileContents(kJavaOutputPath, kExpectedJavaOutput);
+}
+
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/tests/fake_io_delegate.cpp b/aidl/tests/fake_io_delegate.cpp
new file mode 100644
index 0000000..c5575f6
--- /dev/null
+++ b/aidl/tests/fake_io_delegate.cpp
@@ -0,0 +1,168 @@
+/*
+ * 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 "fake_io_delegate.h"
+
+#include <android-base/stringprintf.h>
+
+#include "logging.h"
+#include "os.h"
+#include "tests/test_util.h"
+
+using android::base::StringAppendF;
+using android::base::StringPrintf;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+namespace android {
+namespace aidl {
+namespace test {
+
+// Claims to always write successfully, but can't close the file.
+class BrokenCodeWriter : public CodeWriter {
+  bool Write(const char* /* format */, ...) override {  return true; }
+  bool Close() override { return false; }
+  virtual ~BrokenCodeWriter() = default;
+};  // class BrokenCodeWriter
+
+unique_ptr<string> FakeIoDelegate::GetFileContents(
+    const string& relative_filename,
+    const string& content_suffix) const {
+  string filename = CleanPath(relative_filename);
+  unique_ptr<string> contents;
+  auto it = file_contents_.find(filename);
+  if (it == file_contents_.end()) {
+    return contents;
+  }
+  contents.reset(new string);
+  *contents = it->second;
+  contents->append(content_suffix);
+
+  return contents;
+}
+
+unique_ptr<LineReader> FakeIoDelegate::GetLineReader(
+    const string& file_path) const {
+  unique_ptr<LineReader> ret;
+  const auto& it = file_contents_.find(CleanPath(file_path));
+  if (it != file_contents_.cend()) {
+    ret = LineReader::ReadFromMemory(it->second);
+  }
+  return ret;
+}
+
+bool FakeIoDelegate::FileIsReadable(const string& path) const {
+  return file_contents_.find(CleanPath(path)) != file_contents_.end();
+}
+
+bool FakeIoDelegate::CreatedNestedDirs(
+    const std::string& /* base_dir */,
+    const std::vector<std::string>& /* nested_subdirs */) const {
+  // We don't test directory creation explicitly.
+  return true;
+}
+
+std::unique_ptr<CodeWriter> FakeIoDelegate::GetCodeWriter(
+    const std::string& file_path) const {
+  if (broken_files_.count(file_path) > 0) {
+    return unique_ptr<CodeWriter>(new BrokenCodeWriter);
+  }
+  removed_files_.erase(file_path);
+  written_file_contents_[file_path] = "";
+  return GetStringWriter(&written_file_contents_[file_path]);
+}
+
+void FakeIoDelegate::RemovePath(const std::string& file_path) const {
+  removed_files_.insert(file_path);
+}
+
+void FakeIoDelegate::SetFileContents(const string& filename,
+                                     const string& contents) {
+  file_contents_[filename] = contents;
+}
+
+void FakeIoDelegate::AddStubParcelable(const string& canonical_name,
+                                       const string& cpp_header) {
+  string package, class_name, rel_path;
+  SplitPackageClass(canonical_name, &rel_path, &package, &class_name);
+  string contents;
+  if (cpp_header.empty()) {
+    contents = StringPrintf("package %s;\nparcelable %s;",
+                            package.c_str(), class_name.c_str());
+  } else {
+    contents = StringPrintf("package %s;\nparcelable %s cpp_header \"%s\";",
+                            package.c_str(), class_name.c_str(),
+                            cpp_header.c_str());
+  }
+  SetFileContents(rel_path, contents);
+}
+
+void FakeIoDelegate::AddStubInterface(const string& canonical_name) {
+  string package, class_name, rel_path;
+  SplitPackageClass(canonical_name, &rel_path, &package, &class_name);
+  string contents = StringPrintf("package %s;\ninterface %s { }",
+                                 package.c_str(), class_name.c_str());
+  SetFileContents(rel_path, contents);
+}
+
+void FakeIoDelegate::AddCompoundParcelable(const string& canonical_name,
+                                           const vector<string>& subclasses) {
+  string package, class_name, rel_path;
+  SplitPackageClass(canonical_name, &rel_path, &package, &class_name);
+  string contents = StringPrintf("package %s;\n", package.c_str());
+  for (const string& subclass : subclasses) {
+    StringAppendF(&contents, "parcelable %s.%s;\n",
+                  class_name.c_str(), subclass.c_str());
+  }
+  SetFileContents(rel_path, contents);
+}
+
+void FakeIoDelegate::AddBrokenFilePath(const std::string& path) {
+  broken_files_.insert(path);
+}
+
+bool FakeIoDelegate::GetWrittenContents(const string& path, string* content) {
+  const auto it = written_file_contents_.find(path);
+  if (it == written_file_contents_.end()) {
+    return false;
+  }
+  if (content) {
+    *content = it->second;
+  }
+  return true;
+}
+
+bool FakeIoDelegate::PathWasRemoved(const std::string& path) {
+  if (removed_files_.count(path) > 0) {
+    return true;
+  }
+  return false;
+}
+
+string FakeIoDelegate::CleanPath(const string& path) const {
+  string clean_path = path;
+  while (clean_path.length() >= 2 &&
+         clean_path[0] == '.' &&
+         clean_path[1] == OS_PATH_SEPARATOR) {
+    clean_path = clean_path.substr(2);
+  }
+  return clean_path;
+}
+
+}  // namespace test
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/tests/fake_io_delegate.h b/aidl/tests/fake_io_delegate.h
new file mode 100644
index 0000000..aae2091
--- /dev/null
+++ b/aidl/tests/fake_io_delegate.h
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_TESTS_FAKE_IO_DELEGATE_H_
+#define AIDL_TESTS_FAKE_IO_DELEGATE_H_
+
+#include <android-base/macros.h>
+
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "io_delegate.h"
+
+namespace android {
+namespace aidl {
+namespace test {
+
+class FakeIoDelegate : public IoDelegate {
+ public:
+  FakeIoDelegate() = default;
+  virtual ~FakeIoDelegate() = default;
+
+  // Overrides from the real IoDelegate
+  std::unique_ptr<std::string> GetFileContents(
+      const std::string& filename,
+      const std::string& append_content_suffix = "") const override;
+  std::unique_ptr<LineReader> GetLineReader(
+      const std::string& file_path) const override;
+  bool FileIsReadable(const std::string& path) const override;
+  bool CreatedNestedDirs(
+      const std::string& base_dir,
+      const std::vector<std::string>& nested_subdirs) const override;
+  std::unique_ptr<CodeWriter> GetCodeWriter(
+      const std::string& file_path) const override;
+  void RemovePath(const std::string& file_path) const override;
+
+  // Methods added to facilitate testing.
+  void SetFileContents(const std::string& filename,
+                       const std::string& contents);
+  void AddStubParcelable(const std::string& canonical_name,
+                         const std::string& cpp_header);
+  void AddStubInterface(const std::string& canonical_name);
+  void AddCompoundParcelable(const std::string& canonical_name,
+                             const std::vector<std::string>& subclasses);
+  void AddBrokenFilePath(const std::string& path);
+  // 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);
+
+  bool PathWasRemoved(const std::string& path);
+
+ private:
+  // Remove leading "./" from |path|.
+  std::string CleanPath(const std::string& path) const;
+
+  std::map<std::string, std::string> file_contents_;
+  // Normally, writing to files leaves the IoDelegate unchanged, so
+  // GetCodeWriter is a const method.  However, for tests, we break this
+  // intentionally by storing the written strings.
+  mutable std::map<std::string, std::string> written_file_contents_;
+
+  // We normally just write to strings in |written_file_contents_| but for
+  // files in this list, we simulate I/O errors.
+  std::set<std::string> broken_files_;
+  mutable std::set<std::string> removed_files_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeIoDelegate);
+};  // class FakeIoDelegate
+
+}  // namespace test
+}  // namespace android
+}  // namespace aidl
+
+#endif // AIDL_TESTS_FAKE_IO_DELEGATE_H_
diff --git a/aidl/tests/integration-test.py b/aidl/tests/integration-test.py
new file mode 100755
index 0000000..0079ba9
--- /dev/null
+++ b/aidl/tests/integration-test.py
@@ -0,0 +1,192 @@
+#!/usr/bin/env python
+
+"""
+Test that aidl generates functional code by running it on an Android device.
+"""
+
+import argparse
+import pipes
+import subprocess
+import shlex
+
+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'
+TEST_FILTER_NATIVE = 'native'
+
+JAVA_CLIENT_TIMEOUT_SECONDS = 30
+JAVA_LOG_FILE = '/data/data/android.aidl.tests/files/test-client.log'
+JAVA_SUCCESS_SENTINEL = '>>> Java Client Success <<<'
+JAVA_FAILURE_SENTINEL = '>>> Java Client Failure <<<'
+
+class TestFail(Exception):
+    """Raised on test failures."""
+    pass
+
+
+class ShellResult(object):
+    """Represents the result of running a shell command."""
+
+    def __init__(self, exit_status, stdout, stderr):
+        """Construct an instance.
+
+        Args:
+            exit_status: integer exit code of shell command
+            stdout: string stdout of shell command
+            stderr: string stderr of shell command
+        """
+        self.stdout = stdout
+        self.stderr = stderr
+        self.exit_status = exit_status
+
+    def printable_string(self):
+        """Get a string we could print to the logs and understand."""
+        output = []
+        output.append('stdout:')
+        for line in self.stdout.splitlines():
+            output.append('  > %s' % line)
+        output.append('stderr:')
+        for line in self.stderr.splitlines():
+            output.append('  > %s' % line)
+        return '\n'.join(output)
+
+
+class AdbHost(object):
+    """Represents a device connected via ADB."""
+
+    def __init__(self, device_serial=None, verbose=None):
+        """Construct an instance.
+
+        Args:
+            device_serial: options string serial number of attached device.
+            verbose: True iff we should print out ADB commands we run.
+        """
+        self._device_serial = device_serial
+        self._verbose = verbose
+
+    def run(self, command, background=False, ignore_status=False):
+        """Run a command on the device via adb shell.
+
+        Args:
+            command: string containing a shell command to run.
+            background: True iff we should run this command in the background.
+            ignore_status: True iff we should ignore the command's exit code.
+
+        Returns:
+            instance of ShellResult.
+
+        Raises:
+            subprocess.CalledProcessError on command exit != 0.
+        """
+        if background:
+            command = '( %s ) </dev/null >/dev/null 2>&1 &' % command
+        return self.adb('shell %s' % pipes.quote(command),
+                        ignore_status=ignore_status)
+
+    def mktemp(self):
+        """Make a temp file on the device.
+
+        Returns:
+            path to created file as a string
+
+        Raises:
+            subprocess.CalledProcessError on failure.
+        """
+        # Work around b/19635681
+        result = self.run('source /system/etc/mkshrc && mktemp')
+        return result.stdout.strip()
+
+    def adb(self, command, ignore_status=False):
+        """Run an ADB command (e.g. `adb sync`).
+
+        Args:
+            command: string containing command to run
+            ignore_status: True iff we should ignore the command's exit code.
+
+        Returns:
+            instance of ShellResult.
+
+        Raises:
+            subprocess.CalledProcessError on command exit != 0.
+        """
+        command = 'adb %s' % command
+        if self._verbose:
+            print(command)
+        p = subprocess.Popen(command, shell=True, close_fds=True,
+                             stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                             universal_newlines=True)
+        stdout, stderr = p.communicate()
+        if not ignore_status and p.returncode:
+            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 shoudl test Java Binder clients.
+    """
+
+    print('Starting aidl integration testing...')
+
+    # Kill any previous test context
+    host.run('rm -f %s' % JAVA_LOG_FILE, 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('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())
+            raise TestFail('%s returned status code %d' %
+                           (NATIVE_TEST_CLIENT, result.exit_status))
+
+    if test_java:
+        host.run('am start -S -a android.intent.action.MAIN '
+                 '-n android.aidl.tests/.TestServiceClient '
+                 '--es sentinel.success "%s" '
+                 '--es sentinel.failure "%s"' %
+                 (JAVA_SUCCESS_SENTINEL, JAVA_FAILURE_SENTINEL))
+        result = host.run('%s %d %s "%s" "%s"' %
+                          (JAVA_OUTPUT_READER, JAVA_CLIENT_TIMEOUT_SECONDS,
+                           JAVA_LOG_FILE, JAVA_SUCCESS_SENTINEL,
+                           JAVA_FAILURE_SENTINEL),
+                          ignore_status=True)
+        if result.exit_status:
+            print(result.printable_string())
+            raise TestFail('Java client did not complete successfully.')
+
+    print('Success!')
+
+
+def main():
+    """Main entry point."""
+    parser = argparse.ArgumentParser(description=__doc__)
+    parser.add_argument(
+            '--test-filter', default=TEST_FILTER_ALL,
+            choices=[TEST_FILTER_ALL, TEST_FILTER_JAVA, TEST_FILTER_NATIVE])
+    parser.add_argument('--verbose', '-v', action='store_true', default=False)
+    args = parser.parse_args()
+    host = AdbHost(verbose=args.verbose)
+    try:
+        # Tragically, SELinux interferes with our testing
+        host.run('setenforce 0')
+        run_test(host,
+                 args.test_filter in (TEST_FILTER_ALL, TEST_FILTER_NATIVE),
+                 args.test_filter in (TEST_FILTER_ALL, TEST_FILTER_JAVA))
+    finally:
+        host.run('setenforce 1')
+
+
+if __name__ == '__main__':
+    main()
diff --git a/aidl/tests/java_app/AndroidManifest.xml b/aidl/tests/java_app/AndroidManifest.xml
new file mode 100644
index 0000000..9093892
--- /dev/null
+++ b/aidl/tests/java_app/AndroidManifest.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.aidl.tests">
+
+  <application android:label="@string/application_title">
+
+    <activity android:name="android.aidl.tests.TestServiceClient">
+      <intent-filter>
+        <action android:name="android.intent.action.MAIN" />
+        <category android:name="android.intent.category.LAUNCHER" />
+      </intent-filter>
+    </activity>
+  </application>
+</manifest>
diff --git a/aidl/tests/java_app/README b/aidl/tests/java_app/README
new file mode 100644
index 0000000..a3dfceb
--- /dev/null
+++ b/aidl/tests/java_app/README
@@ -0,0 +1,17 @@
+To use this APK do something like:
+
+1) Build your favorite AOSP flavor.
+2) Start an emulator:
+    $ emulator
+3) Push over hellod binary:
+    $ adb remount && adb sync
+4) Install the Java client:
+    $ adb install -r <path-to-APK-in-out-directory>
+5) Put selinux in permissive mode.
+6) Start hellod:
+    $ adb shell "(hellod ) </dev/null >/dev/null 2>&1 &"
+7) Start Java client:
+    $ adb shell am start -S -a android.intent.action.MAIN \
+                           -n "android.aidl.tests/.TestServiceClient"
+8) Watch output on logcat:
+    $ adb logcat -s TestServiceClient hellod
diff --git a/aidl/tests/java_app/resources/values/strings.xml b/aidl/tests/java_app/resources/values/strings.xml
new file mode 100644
index 0000000..d5ee63e
--- /dev/null
+++ b/aidl/tests/java_app/resources/values/strings.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Strictly speaking, we don't need this. However, without something in
+     resources/ the build rebuilds the APK despite having no changes to the
+     source code.  This seems to be because it fails to generate some
+     resources metafile (R.stamp?) -->
+<resources>
+  <string
+    name="application_title"
+    >AIDL Test Services</string>
+</resources>
diff --git a/aidl/tests/java_app/src/android/aidl/tests/NullableTests.java b/aidl/tests/java_app/src/android/aidl/tests/NullableTests.java
new file mode 100644
index 0000000..83a9877
--- /dev/null
+++ b/aidl/tests/java_app/src/android/aidl/tests/NullableTests.java
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+package android.aidl.tests;
+
+import android.aidl.tests.TestFailException;
+import android.os.IBinder;
+import java.util.ArrayList;
+import java.util.List;
+
+class NullableTests {
+    private static final String TAG = "TestServiceClient";
+    private ITestService mService;
+    private TestLogger mLog;
+
+    public NullableTests(ITestService service, TestLogger logger) {
+        mService = service;
+        mLog = logger;
+    }
+
+    public void checkNullHandling() throws TestFailException {
+        mLog.log("Checking that sending null strings reports an error...");
+        try {
+            String response = mService.RepeatString(null);
+            mLog.logAndThrow("Expected to fail on null string input!");
+        } catch (NullPointerException ex) {
+            mLog.log("Caught an exception on null string parameter (expected)");
+            mLog.log("null strings behave as expected");
+            return;
+        } catch (Exception ex) {
+            mLog.logAndThrow("Expected to receive NullPointerException on " +
+                             "null parameter, but got " + ex.toString());
+        }
+        mLog.logAndThrow("Expected to receive NullPointerException on " +
+                         "null parameter, but nothing was thrown??");
+    }
+
+    public void checkNullBinderDetection() throws TestFailException {
+        mLog.log("Checking that service handles @nullable IBinder...");
+        try {
+            mService.TakesAnIBinder(null);
+            mLog.logAndThrow("Expected to fail on null Binder!");
+        } catch (NullPointerException ex) {
+            mLog.log("Caught an exception on null Binder parameter (expected)");
+            return;
+        } catch (Exception ex) {
+            mLog.logAndThrow("Expected to receive NullPointerException," +
+                             "but got " + ex.toString());
+        }
+        mLog.logAndThrow("Expected to receive NullPointerException on " +
+                         "null parameter, but nothing was thrown??");
+    }
+
+    public void checkNullBinderInListDetection() throws TestFailException {
+        List<IBinder> listWithNulls = new ArrayList<IBinder>();
+        listWithNulls.add(null);
+        try {
+            mService.TakesAnIBinderList(listWithNulls);
+            mLog.logAndThrow("Expected to fail on list with null Binder!");
+        } catch (NullPointerException ex) {
+            mLog.log("Caught an exception on list with null Binder (expected)");
+            return;
+        } catch (Exception ex) {
+            mLog.logAndThrow("Expected to receive NullPointerException," +
+                             "but got " + ex.toString());
+        }
+        mLog.logAndThrow("Expected to receive NullPointerException on " +
+                         "null parameter, but nothing was thrown??");
+    }
+
+    public void checkNullInterfaceHandling() throws TestFailException {
+        mLog.log("Checking @nullable IInterface handling...");
+        try {
+            INamedCallback callback  = mService.GetCallback(false);
+            if (callback == null) {
+                mLog.logAndThrow("Expected to get non-null INamedCallback.");
+            }
+            callback  = mService.GetCallback(true);
+            if (callback != null) {
+                mLog.logAndThrow("Expected to get null INamedCallback.");
+            }
+        } catch (Exception ex) {
+            mLog.logAndThrow("Unexpected exception during @nullable IInterface test: " +
+                             ex.toString());
+        }
+        mLog.log("@nullable IInterface handling works as expected.");
+    }
+
+    public void runTests() throws TestFailException {
+        checkNullHandling();
+        checkNullBinderDetection();
+        checkNullBinderInListDetection();
+        checkNullInterfaceHandling();
+    }
+}
diff --git a/aidl/tests/java_app/src/android/aidl/tests/SimpleParcelable.java b/aidl/tests/java_app/src/android/aidl/tests/SimpleParcelable.java
new file mode 100644
index 0000000..1def98c
--- /dev/null
+++ b/aidl/tests/java_app/src/android/aidl/tests/SimpleParcelable.java
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+package android.aidl.tests;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class SimpleParcelable implements Parcelable {
+    private String mName;
+    private int mNumber;
+
+    SimpleParcelable() {}
+    SimpleParcelable(String name, int number) {
+        mName = name;
+        mNumber = number;
+    }
+
+    public int describeContents() { return 0; }
+
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mName);
+        dest.writeInt(mNumber);
+    }
+
+    public void readFromParcel(Parcel source) {
+        mName = source.readString();
+        mNumber = source.readInt();
+    }
+
+    public boolean equals(Object o) {
+        if (o == null) {
+            return false;
+        }
+        if (!(o instanceof SimpleParcelable)) {
+            return false;
+        }
+        SimpleParcelable p = (SimpleParcelable)o;
+        if ((mName == null && p.mName != null) ||
+            (mName != null && !mName.equals(p.mName))) {
+            return false;
+        }
+        return mNumber == p.mNumber;
+    }
+
+    public String toString() {
+        return "SimpleParcelable(" + mName + ", " + mNumber + ")";
+    }
+
+    public static final Parcelable.Creator<SimpleParcelable> CREATOR =
+            new Parcelable.Creator<SimpleParcelable>() {
+        public SimpleParcelable createFromParcel(Parcel source) {
+            String name = source.readString();
+            int number = source.readInt();
+            return new SimpleParcelable(name, number);
+        }
+
+        public SimpleParcelable[] newArray(int size) {
+            return new SimpleParcelable[size];
+        }
+    };
+}
diff --git a/aidl/tests/java_app/src/android/aidl/tests/TestFailException.java b/aidl/tests/java_app/src/android/aidl/tests/TestFailException.java
new file mode 100644
index 0000000..de000fa
--- /dev/null
+++ b/aidl/tests/java_app/src/android/aidl/tests/TestFailException.java
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package android.aidl.tests;
+
+public class TestFailException extends Exception {
+    public TestFailException(String message) {
+        super(message);
+    }
+}
+
diff --git a/aidl/tests/java_app/src/android/aidl/tests/TestLogger.java b/aidl/tests/java_app/src/android/aidl/tests/TestLogger.java
new file mode 100644
index 0000000..b2e400b
--- /dev/null
+++ b/aidl/tests/java_app/src/android/aidl/tests/TestLogger.java
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+package android.aidl.tests;
+
+import android.util.Log;
+import java.io.PrintWriter;
+import java.io.IOException;
+import android.content.Context;
+
+public class TestLogger {
+    private static final String TAG = "TestServiceClient";
+    private PrintWriter mLogFile;
+
+    public TestLogger(Context context) {
+        try {
+            mLogFile = new PrintWriter(context.openFileOutput(
+                    "test-client.log", Context.MODE_PRIVATE));
+        } catch (IOException ex) {
+            throw new RuntimeException("Failed to open log file for writing.");
+        }
+    }
+
+    public void log(String line) {
+        Log.i(TAG, line);
+        mLogFile.println(line);
+    }
+
+    public void logAndThrow(String line) throws TestFailException {
+        Log.e(TAG, line);
+        mLogFile.println(line);
+        throw new TestFailException(line);
+    }
+
+    public void close() {
+        if (mLogFile != null) {
+            mLogFile.close();
+        }
+    }
+}
diff --git a/aidl/tests/java_app/src/android/aidl/tests/TestServiceClient.java b/aidl/tests/java_app/src/android/aidl/tests/TestServiceClient.java
new file mode 100644
index 0000000..4af4aa0
--- /dev/null
+++ b/aidl/tests/java_app/src/android/aidl/tests/TestServiceClient.java
@@ -0,0 +1,685 @@
+/*
+ * 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.
+ */
+
+package android.aidl.tests;
+
+import android.aidl.tests.SimpleParcelable;
+import android.aidl.tests.TestFailException;
+import android.aidl.tests.TestLogger;
+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.PersistableBundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+// Generated
+import android.aidl.tests.INamedCallback;
+import android.aidl.tests.ITestService;
+
+public class TestServiceClient extends Activity {
+    private static final String TAG = "TestServiceClient";
+
+    private TestLogger mLog;
+    private String mSuccessSentinel;
+    private String mFailureSentinel;
+
+    private void init() {
+        Intent intent = getIntent();
+        mLog = new TestLogger(this);
+        mLog.log("Reading sentinels from intent...");
+        mSuccessSentinel = intent.getStringExtra("sentinel.success");
+        mFailureSentinel = intent.getStringExtra("sentinel.failure");
+        if (mSuccessSentinel == null || mFailureSentinel == null) {
+            String message = "Failed to read intent extra input.";
+            Log.e(TAG, message);
+            mLog.close();
+            throw new RuntimeException(message);
+        }
+    }
+
+    private ITestService getService() throws TestFailException {
+        IBinder service = new ServiceManager().getService(
+                ITestService.class.getName());
+        if (service == null) {
+            mLog.logAndThrow("Failed to obtain binder...");
+        }
+        ITestService ret = ITestService.Stub.asInterface(service);
+        if (ret == null) {
+            mLog.logAndThrow("Failed to cast IBinder instance.");
+        }
+        return ret;
+    }
+
+    private void checkPrimitiveRepeat(ITestService service)
+            throws TestFailException {
+        mLog.log("Checking that service can repeat primitives back...");
+        try {
+            {
+                boolean query = true;
+                boolean response = service.RepeatBoolean(query);
+                if (query != response) {
+                    mLog.logAndThrow("Repeat with " + query +
+                                     " responded " + response);
+                }
+            }
+            {
+                char query = 'A';
+                char response = service.RepeatChar(query);
+                if (query != response) {
+                    mLog.logAndThrow("Repeat with " + query +
+                                     " responded " + response);
+                }
+            }
+            {
+                byte query = -128;
+                byte response = service.RepeatByte(query);
+                if (query != response) {
+                    mLog.logAndThrow("Repeat with " + query +
+                                     " responded " + response);
+                }
+            }
+            {
+                int query = 1 << 30;
+                int response = service.RepeatInt(query);
+                if (query != response) {
+                    mLog.logAndThrow("Repeat with " + query +
+                                     " responded " + response);
+                }
+            }
+            {
+                int query[] = {ITestService.TEST_CONSTANT,
+                               ITestService.TEST_CONSTANT2,
+                               ITestService.TEST_CONSTANT3,
+                               ITestService.TEST_CONSTANT4,
+                               ITestService.TEST_CONSTANT5,
+                               ITestService.TEST_CONSTANT6,
+                               ITestService.TEST_CONSTANT7,
+                               ITestService.TEST_CONSTANT8};
+                for (int i = 0; i < query.length; i++) {
+                    int response = service.RepeatInt(query[i]);
+                    if (query[i] != response) {
+                        mLog.logAndThrow("Repeat with " + query[i] +
+                                " responded " + response);
+                    }
+                }
+            }
+            {
+                long query = 1L << 60;
+                long response = service.RepeatLong(query);
+                if (query != response) {
+                    mLog.logAndThrow("Repeat with " + query +
+                                     " responded " + response);
+                }
+            }
+            {
+                float query = 1.0f/3.0f;
+                float response = service.RepeatFloat(query);
+                if (query != response) {
+                    mLog.logAndThrow("Repeat with " + query +
+                                     " responded " + response);
+                }
+            }
+            {
+                double query = 1.0/3.0;
+                double response = service.RepeatDouble(query);
+                if (query != response) {
+                    mLog.logAndThrow("Repeat with " + query +
+                                     " responded " + response);
+                }
+            }
+
+            List<String> queries = Arrays.asList(
+                "not empty", "", "\0",
+                ITestService.STRING_TEST_CONSTANT,
+                ITestService.STRING_TEST_CONSTANT2);
+            for (String query : queries) {
+                String response = service.RepeatString(query);
+                if (!query.equals(response)) {
+                    mLog.logAndThrow("Repeat request with '" + query + "'" +
+                                     " of length " + query.length() +
+                                     " responded with '" + response + "'" +
+                                     " of length " + response.length());
+                }
+            }
+        } catch (RemoteException ex) {
+            mLog.log(ex.toString());
+            mLog.logAndThrow("Service failed to repeat a primitive back.");
+        }
+        mLog.log("...Basic primitive repeating works.");
+    }
+
+    private void checkArrayReversal(ITestService service)
+            throws TestFailException {
+        mLog.log("Checking that service can reverse and return arrays...");
+        try {
+            {
+                boolean[] input = {true, false, false, false};
+                boolean echoed[] = new boolean[input.length];
+                boolean[] reversed = service.ReverseBoolean(input, echoed);
+                if (!Arrays.equals(input, echoed)) {
+                    mLog.logAndThrow("Failed to echo input array back.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow("Reversed array is the wrong size.");
+                }
+                for (int i = 0; i < input.length; ++i) {
+                    int j = reversed.length - (1 + i);
+                    if (input[i] != reversed[j]) {
+                        mLog.logAndThrow(
+                                "input[" + i + "] = " + input[i] +
+                                " but reversed value = " + reversed[j]);
+                    }
+                }
+            }
+            {
+                byte[] input = {0, 1, 2};
+                byte echoed[] = new byte[input.length];
+                byte[] reversed = service.ReverseByte(input, echoed);
+                if (!Arrays.equals(input, echoed)) {
+                    mLog.logAndThrow("Failed to echo input array back.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow("Reversed array is the wrong size.");
+                }
+                for (int i = 0; i < input.length; ++i) {
+                    int j = reversed.length - (1 + i);
+                    if (input[i] != reversed[j]) {
+                        mLog.logAndThrow(
+                                "input[" + i + "] = " + input[i] +
+                                " but reversed value = " + reversed[j]);
+                    }
+                }
+            }
+            {
+                char[] input = {'A', 'B', 'C', 'D', 'E'};
+                char echoed[] = new char[input.length];
+                char[] reversed = service.ReverseChar(input, echoed);
+                if (!Arrays.equals(input, echoed)) {
+                    mLog.logAndThrow("Failed to echo input array back.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow("Reversed array is the wrong size.");
+                }
+                for (int i = 0; i < input.length; ++i) {
+                    int j = reversed.length - (1 + i);
+                    if (input[i] != reversed[j]) {
+                        mLog.logAndThrow(
+                                "input[" + i + "] = " + input[i] +
+                                " but reversed value = " + reversed[j]);
+                    }
+                }
+            }
+            {
+                int[] input = {-1, 0, 1, 2, 3, 4, 5, 6};
+                int echoed[] = new int[input.length];
+                int[] reversed = service.ReverseInt(input, echoed);
+                if (!Arrays.equals(input, echoed)) {
+                    mLog.logAndThrow("Failed to echo input array back.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow("Reversed array is the wrong size.");
+                }
+                for (int i = 0; i < input.length; ++i) {
+                    int j = reversed.length - (1 + i);
+                    if (input[i] != reversed[j]) {
+                        mLog.logAndThrow(
+                                "input[" + i + "] = " + input[i] +
+                                " but reversed value = " + reversed[j]);
+                    }
+                }
+            }
+            {
+                long[] input = {-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8};
+                long echoed[] = new long[input.length];
+                long[] reversed = service.ReverseLong(input, echoed);
+                if (!Arrays.equals(input, echoed)) {
+                    mLog.logAndThrow("Failed to echo input array back.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow("Reversed array is the wrong size.");
+                }
+                for (int i = 0; i < input.length; ++i) {
+                    int j = reversed.length - (1 + i);
+                    if (input[i] != reversed[j]) {
+                        mLog.logAndThrow(
+                                "input[" + i + "] = " + input[i] +
+                                " but reversed value = " + reversed[j]);
+                    }
+                }
+            }
+            {
+                float[] input = {0.0f, 1.0f, -0.3f};
+                float echoed[] = new float[input.length];
+                float[] reversed = service.ReverseFloat(input, echoed);
+                if (!Arrays.equals(input, echoed)) {
+                    mLog.logAndThrow("Failed to echo input array back.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow("Reversed array is the wrong size.");
+                }
+                for (int i = 0; i < input.length; ++i) {
+                    int j = reversed.length - (1 + i);
+                    if (input[i] != reversed[j]) {
+                        mLog.logAndThrow(
+                                "input[" + i + "] = " + input[i] +
+                                " but reversed value = " + reversed[j]);
+                    }
+                }
+            }
+            {
+                double[] input = {-1.0, -4.0, -2.0};
+                double echoed[] = new double[input.length];
+                double[] reversed = service.ReverseDouble(input, echoed);
+                if (!Arrays.equals(input, echoed)) {
+                    mLog.logAndThrow("Failed to echo input array back.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow("Reversed array is the wrong size.");
+                }
+                for (int i = 0; i < input.length; ++i) {
+                    int j = reversed.length - (1 + i);
+                    if (input[i] != reversed[j]) {
+                        mLog.logAndThrow(
+                                "input[" + i + "] = " + input[i] +
+                                " but reversed value = " + reversed[j]);
+                    }
+                }
+            }
+            {
+                String[] input = {"For", "relaxing", "times"};
+                String echoed[] = new String[input.length];
+                String[] reversed = service.ReverseString(input, echoed);
+                if (!Arrays.equals(input, echoed)) {
+                    mLog.logAndThrow("Failed to echo input array back.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow("Reversed array is the wrong size.");
+                }
+                for (int i = 0; i < input.length; ++i) {
+                    int j = reversed.length - (1 + i);
+                    if (!input[i].equals(reversed[j])) {
+                        mLog.logAndThrow(
+                                "input[" + i + "] = " + input[i] +
+                                " but reversed value = " + reversed[j]);
+                    }
+                }
+            }
+        } catch (RemoteException ex) {
+            mLog.log(ex.toString());
+            mLog.logAndThrow("Service failed to reverse an array.");
+        }
+        mLog.log("...service can reverse and return arrays.");
+    }
+
+    private void checkBinderExchange(
+                ITestService service) throws TestFailException {
+      mLog.log("Checking exchange of binders...");
+      try {
+          INamedCallback got = service.GetOtherTestService("Smythe");
+          mLog.log("Received test service");
+          String name = got.GetName();
+
+          if (!name.equals("Smythe")) {
+              mLog.logAndThrow("Tried to get service with name 'Smythe'" +
+                               " and found service with name '" + name + "'");
+          }
+
+          if (!service.VerifyName(got, "Smythe")) {
+              mLog.logAndThrow("Test service could not verify name of 'Smythe'");
+          }
+      } catch (RemoteException ex) {
+          mLog.log(ex.toString());
+          mLog.logAndThrow("Service failed to exchange binders.");
+      }
+      mLog.log("...Exchange of binders works");
+    }
+
+    private void checkListReversal(ITestService service)
+            throws TestFailException {
+        mLog.log("Checking that service can reverse and return lists...");
+        try {
+            {
+                List<String> input = Arrays.asList("Walk", "into", "Córdoba");
+                List<String> echoed = new ArrayList<String>();
+                List<String> reversed = service.ReverseStringList(input, echoed);
+                if (!input.equals(echoed)) {
+                    mLog.logAndThrow("Failed to echo input List<String> back.");
+                }
+                Collections.reverse(input);
+                if (!input.equals(reversed)) {
+                    mLog.logAndThrow("Reversed list is not correct.");
+                }
+            }
+        } catch (RemoteException ex) {
+            mLog.log(ex.toString());
+            mLog.logAndThrow("Service failed to reverse an List<String>.");
+        }
+        mLog.log("...service can reverse and return lists.");
+    }
+
+    private void checkSimpleParcelables(ITestService service)
+            throws TestFailException {
+        mLog.log("Checking that service can repeat and reverse SimpleParcelable objects...");
+        try {
+            {
+                SimpleParcelable input = new SimpleParcelable("foo", 42);
+                SimpleParcelable out_param = new SimpleParcelable();
+                SimpleParcelable returned =
+                        service.RepeatSimpleParcelable(input, out_param);
+                if (!input.equals(out_param)) {
+                    mLog.log(input.toString() + " != " + out_param.toString());
+                    mLog.logAndThrow("out param SimpleParcelable was not equivalent");
+                }
+                if (!input.equals(returned)) {
+                    mLog.log(input.toString() + " != " + returned.toString());
+                    mLog.logAndThrow("returned SimpleParcelable was not equivalent");
+                }
+            }
+            {
+                SimpleParcelable[] input = new SimpleParcelable[3];
+                input[0] = new SimpleParcelable("a", 1);
+                input[1] = new SimpleParcelable("b", 2);
+                input[2] = new SimpleParcelable("c", 3);
+                SimpleParcelable[] repeated = new SimpleParcelable[3];
+                SimpleParcelable[] reversed = service.ReverseSimpleParcelables(
+                        input, repeated);
+                if (!Arrays.equals(input, repeated)) {
+                    mLog.logAndThrow(
+                            "Repeated list of SimpleParcelable objects did not match.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow(
+                            "Reversed list of SimpleParcelable objects had wrong length.");
+                }
+                for (int i = 0, k = input.length - 1;
+                     i < input.length;
+                     ++i, --k) {
+                    if (!input[i].equals(reversed[k])) {
+                        mLog.log(input[i].toString() + " != " +
+                                 reversed[k].toString());
+                        mLog.logAndThrow("reversed SimpleParcelable was not equivalent");
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            mLog.log(ex.toString());
+            mLog.logAndThrow("Service failed to handle SimpleParcelable objects.");
+        }
+        mLog.log("...service can manipulate SimpleParcelable objects.");
+    }
+
+    private void checkPersistableBundles(ITestService service)
+            throws TestFailException {
+        mLog.log("Checking that service can repeat and reverse PersistableBundle objects...");
+        try {
+            {
+                PersistableBundle emptyBundle = new PersistableBundle();
+                PersistableBundle returned = service.RepeatPersistableBundle(emptyBundle);
+                if (emptyBundle.size() != 0 || returned.size() != 0) {
+                    mLog.log(emptyBundle.toString() + " != " + returned.toString());
+                    mLog.logAndThrow("returned empty PersistableBundle object was not equivalent");
+                }
+                mLog.log("...service can repeat and reverse empty PersistableBundle objects...");
+            }
+            {
+                final String testBoolKey = new String("testBool");
+                final String testIntKey = new String("testInt");
+                final String testNestedIntKey = new String("testNestedInt");
+                final String testLongKey = new String("testLong");
+                final String testDoubleKey = new String("testDouble");
+                final String testStringKey = new String("testString");
+                final String testBoolArrayKey = new String("testBoolArray");
+                final String testIntArrayKey = new String("testIntArray");
+                final String testLongArrayKey = new String("testLongArray");
+                final String testDoubleArrayKey = new String("testDoubleArray");
+                final String testStringArrayKey = new String("testStringArray");
+                final String testPersistableBundleKey = new String("testPersistableBundle");
+                PersistableBundle nonEmptyBundle = new PersistableBundle();
+                nonEmptyBundle.putBoolean(testBoolKey, false);
+                nonEmptyBundle.putInt(testIntKey, 33);
+                nonEmptyBundle.putLong(testLongKey, 34359738368L);
+                nonEmptyBundle.putDouble(testDoubleKey, 1.1);
+                nonEmptyBundle.putString(testStringKey, new String("Woot!"));
+                nonEmptyBundle.putBooleanArray(testBoolArrayKey, new boolean[] {true, false, true});
+                nonEmptyBundle.putIntArray(testIntArrayKey, new int[] {33, 44, 55, 142});
+                nonEmptyBundle.putLongArray(
+                    testLongArrayKey, new long[] {34L, 8371L, 34359738375L});
+                nonEmptyBundle.putDoubleArray(testDoubleArrayKey, new double[] {2.2, 5.4});
+                nonEmptyBundle.putStringArray(testStringArrayKey, new String[] {"hello", "world!"});
+                PersistableBundle testNestedPersistableBundle = new PersistableBundle();
+                testNestedPersistableBundle.putInt(testNestedIntKey, 345);
+                nonEmptyBundle.putPersistableBundle(
+                    testPersistableBundleKey, testNestedPersistableBundle);
+                PersistableBundle returned = service.RepeatPersistableBundle(nonEmptyBundle);
+                if (returned.size() != nonEmptyBundle.size()
+                    || returned.getBoolean(testBoolKey) != nonEmptyBundle.getBoolean(testBoolKey)
+                    || returned.getInt(testIntKey) != nonEmptyBundle.getInt(testIntKey)
+                    || returned.getLong(testLongKey) != nonEmptyBundle.getLong(testLongKey)
+                    || returned.getDouble(testDoubleKey) != nonEmptyBundle.getDouble(testDoubleKey)
+                    || !returned.getString(testStringKey)
+                                .equals(nonEmptyBundle.getString(testStringKey))
+                    || !Arrays.equals(nonEmptyBundle.getBooleanArray(testBoolArrayKey),
+                                      returned.getBooleanArray(testBoolArrayKey))
+                    || !Arrays.equals(nonEmptyBundle.getIntArray(testIntArrayKey),
+                                      returned.getIntArray(testIntArrayKey))
+                    || !Arrays.equals(nonEmptyBundle.getLongArray(testLongArrayKey),
+                                      returned.getLongArray(testLongArrayKey))
+                    || !Arrays.equals(nonEmptyBundle.getDoubleArray(testDoubleArrayKey),
+                                      returned.getDoubleArray(testDoubleArrayKey))
+                    || !Arrays.equals(nonEmptyBundle.getStringArray(testStringArrayKey),
+                                      returned.getStringArray(testStringArrayKey))) {
+                    PersistableBundle temp =
+                        returned.getPersistableBundle(testPersistableBundleKey);
+                    if (temp == null
+                        || temp.getInt(testNestedIntKey)
+                            != testNestedPersistableBundle.getInt(testNestedIntKey)) {
+                        mLog.log(nonEmptyBundle.toString() + " != " + returned.toString());
+                        mLog.logAndThrow("returned non-empty PersistableBundle " +
+                                         "object was not equivalent");
+                    }
+                }
+                mLog.log("...service can repeat and reverse non-empty " +
+                         "PersistableBundle objects...");
+            }
+            {
+                PersistableBundle[] input = new PersistableBundle[3];
+                PersistableBundle first = new PersistableBundle();
+                PersistableBundle second = new PersistableBundle();
+                PersistableBundle third = new PersistableBundle();
+                final String testIntKey = new String("testInt");
+                final String testLongKey = new String("testLong");
+                final String testDoubleKey = new String("testDouble");
+                first.putInt(testIntKey, 1231);
+                second.putLong(testLongKey, 222222L);
+                third.putDouble(testDoubleKey, 10.8);
+                input[0] = first;
+                input[1] = second;
+                input[2] = third;
+                final int original_input_size = input.length;
+                PersistableBundle[] repeated = new PersistableBundle[input.length];
+                PersistableBundle[] reversed = service.ReversePersistableBundles(input, repeated);
+                if (input.length != repeated.length || input.length != original_input_size) {
+                    mLog.logAndThrow("Repeated list of PersistableBundle objects had " +
+                                     "wrong length.");
+                }
+                if (input[0].getInt(testIntKey) != repeated[0].getInt(testIntKey)
+                    || input[1].getLong(testLongKey) != repeated[1].getLong(testLongKey)
+                    || input[2].getDouble(testDoubleKey) != repeated[2].getDouble(testDoubleKey)) {
+                    mLog.logAndThrow("Repeated list of PersistableBundle objects did not match.");
+                }
+                if (input.length != reversed.length || input.length != original_input_size) {
+                    mLog.logAndThrow("Reversed list of PersistableBundle objects had " +
+                                     "wrong length.");
+                }
+                if (input[0].getInt(testIntKey) != reversed[2].getInt(testIntKey)
+                    || input[1].getLong(testLongKey) != reversed[1].getLong(testLongKey)
+                    || input[2].getDouble(testDoubleKey) != reversed[0].getDouble(testDoubleKey)) {
+                    mLog.logAndThrow("reversed PersistableBundle objects were not equivalent");
+                }
+                mLog.log("...service can repeat and reverse arrays of " +
+                         "non-empty PersistableBundle objects...");
+            }
+        } catch (Exception ex) {
+            mLog.log(ex.toString());
+            mLog.logAndThrow("Service failed to handle PersistableBundle objects.");
+        }
+        mLog.log("...service can manipulate PersistableBundle objects.");
+    }
+
+    private void checkFileDescriptorPassing(ITestService service)
+            throws TestFailException {
+        mLog.log("Checking that service can receive and return file descriptors...");
+        try {
+            FileOutputStream fileOutputStream =
+                    openFileOutput("test-dummy", Context.MODE_PRIVATE);
+
+            FileDescriptor descriptor = fileOutputStream.getFD();
+            FileDescriptor journeyed = service.RepeatFileDescriptor(descriptor);
+            fileOutputStream.close();
+
+            FileOutputStream journeyedStream = new FileOutputStream(journeyed);
+
+            String testData = "FrazzleSnazzleFlimFlamFlibbityGumboChops";
+            byte[] output = testData.getBytes();
+            journeyedStream.write(output);
+            journeyedStream.close();
+
+            FileInputStream fileInputStream = openFileInput("test-dummy");
+            byte[] input = new byte[output.length];
+            if (fileInputStream.read(input) != input.length) {
+                mLog.logAndThrow("Read short count from file");
+            }
+
+            if (!Arrays.equals(input, output)) {
+                mLog.logAndThrow("Read incorrect data");
+            }
+        } catch (RemoteException ex) {
+            mLog.log(ex.toString());
+            mLog.logAndThrow("Service failed to repeat a file descriptor.");
+        } catch (IOException ex) {
+            mLog.log(ex.toString());
+            mLog.logAndThrow("Exception while operating on temporary file");
+        }
+        mLog.log("...service can receive and return file descriptors.");
+    }
+
+    private void checkServiceSpecificExceptions(
+                ITestService service) throws TestFailException {
+        mLog.log("Checking application exceptions...");
+        for (int i = -1; i < 2; ++i) {
+            try {
+                service.ThrowServiceException(i);
+            } catch (RemoteException ex) {
+                mLog.logAndThrow("Service threw RemoteException: " +
+                                 ex.toString());
+            } catch (ServiceSpecificException ex) {
+                if (ex.errorCode != i) {
+                    mLog.logAndThrow("Service threw wrong error code: " + i);
+                }
+            }
+        }
+        mLog.log("...application exceptions work");
+    }
+
+    private void checkUtf8Strings(ITestService service)
+            throws TestFailException {
+        mLog.log("Checking that service can work with UTF8 strings...");
+        // Note that Java's underlying encoding is UTF16.
+        final List<String> utf8_queries = Arrays.asList(
+              "typical string",
+              "",
+              "\0\0\0",
+              // Java doesn't handle unicode code points above U+FFFF well.
+              new String(Character.toChars(0x1F701)) + "\u03A9");
+        try {
+            for (String query : utf8_queries) {
+                String response = service.RepeatUtf8CppString(query);
+                if (!query.equals(response)) {
+                    mLog.logAndThrow("Repeat request with '" + query + "'" +
+                                     " of length " + query.length() +
+                                     " responded with '" + response + "'" +
+                                     " of length " + response.length());
+                }
+            }
+            {
+                String[] input = (String[])utf8_queries.toArray();
+                String echoed[] = new String[input.length];
+                String[] reversed = service.ReverseUtf8CppString(input, echoed);
+                if (!Arrays.equals(input, echoed)) {
+                    mLog.logAndThrow("Failed to echo utf8 input array back.");
+                }
+                if (input.length != reversed.length) {
+                    mLog.logAndThrow("Reversed utf8 array is the wrong size.");
+                }
+                for (int i = 0; i < input.length; ++i) {
+                    int j = reversed.length - (1 + i);
+                    if (!input[i].equals(reversed[j])) {
+                        mLog.logAndThrow(
+                                "input[" + i + "] = " + input[i] +
+                                " but reversed value = " + reversed[j]);
+                    }
+                }
+            }
+        } catch (RemoteException ex) {
+            mLog.log(ex.toString());
+            mLog.logAndThrow("Service failed to handle utf8 strings.");
+        }
+        mLog.log("...UTF8 annotations work.");
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "Starting!");
+        try {
+          init();
+          ITestService service = getService();
+          checkPrimitiveRepeat(service);
+          checkArrayReversal(service);
+          checkBinderExchange(service);
+          checkListReversal(service);
+          checkSimpleParcelables(service);
+          checkPersistableBundles(service);
+          checkFileDescriptorPassing(service);
+          checkServiceSpecificExceptions(service);
+          checkUtf8Strings(service);
+          new NullableTests(service, mLog).runTests();
+
+          mLog.log(mSuccessSentinel);
+        } catch (TestFailException e) {
+            mLog.log(mFailureSentinel);
+            throw new RuntimeException(e);
+        } finally {
+            if (mLog != null) {
+                mLog.close();
+            }
+        }
+    }
+}
diff --git a/aidl/tests/main.cpp b/aidl/tests/main.cpp
new file mode 100644
index 0000000..4d820af
--- /dev/null
+++ b/aidl/tests/main.cpp
@@ -0,0 +1,6 @@
+#include <gtest/gtest.h>
+
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/aidl/tests/simple_parcelable.cpp b/aidl/tests/simple_parcelable.cpp
new file mode 100644
index 0000000..e092d25
--- /dev/null
+++ b/aidl/tests/simple_parcelable.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 "tests/simple_parcelable.h"
+
+#include <android-base/stringprintf.h>
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace aidl {
+namespace tests {
+
+SimpleParcelable::SimpleParcelable(const std::string& name, int32_t number)
+    : name_(name.c_str(), name.length()),
+      number_(number) {}
+
+status_t SimpleParcelable::writeToParcel(Parcel* parcel) const {
+  status_t status = parcel->writeString16(name_);
+  if (status != OK) {
+    return status;
+  }
+  status = parcel->writeInt32(number_);
+  return status;
+}
+
+status_t SimpleParcelable::readFromParcel(const Parcel* parcel) {
+  status_t status = parcel->readString16(&name_);
+  if (status != OK) {
+    return status;
+  }
+  return parcel->readInt32(&number_);
+}
+
+std::string SimpleParcelable::toString() const {
+    return StringPrintf("%s(%d)", String8(name_).string(), number_);
+}
+
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/simple_parcelable.h b/aidl/tests/simple_parcelable.h
new file mode 100644
index 0000000..52a20de
--- /dev/null
+++ b/aidl/tests/simple_parcelable.h
@@ -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.
+ */
+
+#ifndef AIDL_TESTS_SIMPLE_PARCELABLE_H_
+#define AIDL_TESTS_SIMPLE_PARCELABLE_H_
+
+#include <cstdint>
+#include <string>
+
+#include <binder/Parcelable.h>
+#include <utils/Errors.h>
+#include <utils/String16.h>
+
+namespace android {
+namespace aidl {
+namespace tests {
+
+class SimpleParcelable : public Parcelable {
+ public:
+  SimpleParcelable() = default;
+  SimpleParcelable(const std::string& name, int32_t number);
+  virtual ~SimpleParcelable() = default;
+
+  // Write |this| parcelable to the given |parcel|.  Keep in mind that
+  // implementations of writeToParcel must be manually kept in sync
+  // with readFromParcel and the Java equivalent versions of these methods.
+  //
+  // Returns android::OK on success and an appropriate error otherwise.
+  status_t writeToParcel(Parcel* parcel) const override;
+
+  // Read data from the given |parcel| into |this|.  After readFromParcel
+  // completes, |this| should have equivalent state to the object that
+  // wrote itself to the parcel.
+  //
+  // Returns android::OK on success and an appropriate error otherwise.
+  status_t readFromParcel(const Parcel* parcel) override;
+
+  std::string toString() const;
+
+  friend bool operator==(const SimpleParcelable& lhs,
+                         const SimpleParcelable& rhs) {
+    return (lhs.name_ == rhs.name_) && (lhs.number_ == rhs.number_);
+  }
+  friend bool operator!=(const SimpleParcelable& lhs,
+                         const SimpleParcelable& rhs) {
+    return !(lhs == rhs);
+  }
+
+ private:
+  String16 name_;
+  int32_t number_ = 0;
+};  // class SimpleParcelable
+
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
+
+#endif  // AIDL_TESTS_SIMPLE_PARCELABLE_H_
diff --git a/aidl/tests/test_data.h b/aidl/tests/test_data.h
new file mode 100644
index 0000000..d3a5f6c
--- /dev/null
+++ b/aidl/tests/test_data.h
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_TESTS_TEST_DATA_H_
+#define AIDL_TESTS_TEST_DATA_H_
+
+namespace android {
+namespace aidl {
+namespace test_data {
+
+namespace example_interface {
+
+extern const char kCanonicalName[];
+extern const char kJavaOutputPath[];
+extern const char kInterfaceDefinition[];
+extern const char* kImportedParcelables[];
+extern const char* kImportedInterfaces[];
+
+extern const char kExpectedJavaDepsOutput[];
+extern const char kExpectedJavaOutput[];
+
+}  // namespace example_interface
+
+namespace ping_responder {
+
+extern const char kCanonicalName[];
+extern const char kInterfaceDefinition[];
+
+extern const char kCppOutputPath[];
+extern const char kCppParcelableHeader[];
+extern const char* kImportedParcelables[];
+extern const char* kImportedInterfaces[];
+
+extern const char kGenHeaderDir[];
+extern const char kGenInterfaceHeaderPath[];
+extern const char kGenClientHeaderPath[];
+extern const char kGenServerHeaderPath[];
+
+extern const char kExpectedCppDepsOutput[];
+
+extern const char kExpectedCppOutput[];
+extern const char kExpectedIHeaderOutput[];
+extern const char kExpectedBpHeaderOutput[];
+extern const char kExpectedBnHeaderOutput[];
+
+}  // namespace ping_responder
+
+namespace string_constants {
+
+extern const char kCanonicalName[];
+extern const char kInterfaceDefinition[];
+
+extern const char kJavaOutputPath[];
+extern const char kExpectedJavaOutput[];
+
+extern const char kCppOutputPath[];
+extern const char kGenHeaderDir[];
+extern const char kGenInterfaceHeaderPath[];
+extern const char kExpectedIHeaderOutput[];
+extern const char kExpectedCppOutput[];
+
+}  // namespace string_constants
+
+}  // namespace test_data
+}  // namespace aidl
+}  // namespace android
+
+#endif // AIDL_TESTS_TEST_DATA_H_
diff --git a/aidl/tests/test_data_example_interface.cpp b/aidl/tests/test_data_example_interface.cpp
new file mode 100644
index 0000000..81b919f
--- /dev/null
+++ b/aidl/tests/test_data_example_interface.cpp
@@ -0,0 +1,456 @@
+/*
+ * 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 "tests/test_data.h"
+
+namespace android {
+namespace aidl {
+namespace test_data {
+namespace example_interface {
+
+const char kCanonicalName[] = "android.test.IExampleInterface";
+
+const char kJavaOutputPath[] = "some/path/to/output.java";
+
+const char* kImportedParcelables[] = {
+  "android.foo.ExampleParcelable",
+  nullptr,
+};
+
+const char* kImportedInterfaces[] = {
+  "android.bar.IAuxInterface",
+  "android.test.IAuxInterface2",
+  nullptr,
+};
+
+const char kInterfaceDefinition[] = R"(
+package android.test;
+
+import android.foo.ExampleParcelable;
+import android.test.CompoundParcelable;
+import android.bar.IAuxInterface;
+import android.test.IAuxInterface2;
+
+interface IExampleInterface {
+    const int EXAMPLE_CONSTANT = 3;
+    boolean isEnabled();
+    int getState();
+    String getAddress();
+
+    /* Test long comment */
+    ExampleParcelable[] getParcelables();
+
+    // Test short comment
+    boolean setScanMode(int mode, int duration);
+
+    /* Test long comment */
+    // And short comment
+    void registerBinder(IAuxInterface foo);
+    IExampleInterface getRecursiveBinder();
+
+    int takesAnInterface(in IAuxInterface2 arg);
+    int takesAParcelable(in CompoundParcelable.Subclass1 arg,
+                         inout CompoundParcelable.Subclass2 arg2);
+}
+)";
+
+const char kExpectedJavaDepsOutput[] =
+R"(some/path/to/output.java : \
+  android/test/IExampleInterface.aidl \
+  ./android/foo/ExampleParcelable.aidl \
+  ./android/test/CompoundParcelable.aidl \
+  ./android/bar/IAuxInterface.aidl \
+  ./android/test/IAuxInterface2.aidl
+
+android/test/IExampleInterface.aidl :
+./android/foo/ExampleParcelable.aidl :
+./android/test/CompoundParcelable.aidl :
+./android/bar/IAuxInterface.aidl :
+./android/test/IAuxInterface2.aidl :
+)";
+
+const char kExpectedJavaOutput[] =
+R"(/*
+ * This file is auto-generated.  DO NOT MODIFY.
+ * Original file: android/test/IExampleInterface.aidl
+ */
+package android.test;
+public interface IExampleInterface extends android.os.IInterface
+{
+/** Local-side IPC implementation stub class. */
+public static abstract class Stub extends android.os.Binder implements android.test.IExampleInterface
+{
+private static final java.lang.String DESCRIPTOR = "android.test.IExampleInterface";
+/** Construct the stub at attach it to the interface. */
+public Stub()
+{
+this.attachInterface(this, DESCRIPTOR);
+}
+/**
+ * Cast an IBinder object into an android.test.IExampleInterface interface,
+ * generating a proxy if needed.
+ */
+public static android.test.IExampleInterface asInterface(android.os.IBinder obj)
+{
+if ((obj==null)) {
+return null;
+}
+android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+if (((iin!=null)&&(iin instanceof android.test.IExampleInterface))) {
+return ((android.test.IExampleInterface)iin);
+}
+return new android.test.IExampleInterface.Stub.Proxy(obj);
+}
+@Override public android.os.IBinder asBinder()
+{
+return this;
+}
+@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
+{
+switch (code)
+{
+case INTERFACE_TRANSACTION:
+{
+reply.writeString(DESCRIPTOR);
+return true;
+}
+case TRANSACTION_isEnabled:
+{
+data.enforceInterface(DESCRIPTOR);
+boolean _result = this.isEnabled();
+reply.writeNoException();
+reply.writeInt(((_result)?(1):(0)));
+return true;
+}
+case TRANSACTION_getState:
+{
+data.enforceInterface(DESCRIPTOR);
+int _result = this.getState();
+reply.writeNoException();
+reply.writeInt(_result);
+return true;
+}
+case TRANSACTION_getAddress:
+{
+data.enforceInterface(DESCRIPTOR);
+java.lang.String _result = this.getAddress();
+reply.writeNoException();
+reply.writeString(_result);
+return true;
+}
+case TRANSACTION_getParcelables:
+{
+data.enforceInterface(DESCRIPTOR);
+android.foo.ExampleParcelable[] _result = this.getParcelables();
+reply.writeNoException();
+reply.writeTypedArray(_result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+return true;
+}
+case TRANSACTION_setScanMode:
+{
+data.enforceInterface(DESCRIPTOR);
+int _arg0;
+_arg0 = data.readInt();
+int _arg1;
+_arg1 = data.readInt();
+boolean _result = this.setScanMode(_arg0, _arg1);
+reply.writeNoException();
+reply.writeInt(((_result)?(1):(0)));
+return true;
+}
+case TRANSACTION_registerBinder:
+{
+data.enforceInterface(DESCRIPTOR);
+android.bar.IAuxInterface _arg0;
+_arg0 = android.bar.IAuxInterface.Stub.asInterface(data.readStrongBinder());
+this.registerBinder(_arg0);
+reply.writeNoException();
+return true;
+}
+case TRANSACTION_getRecursiveBinder:
+{
+data.enforceInterface(DESCRIPTOR);
+android.test.IExampleInterface _result = this.getRecursiveBinder();
+reply.writeNoException();
+reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null)));
+return true;
+}
+case TRANSACTION_takesAnInterface:
+{
+data.enforceInterface(DESCRIPTOR);
+android.test.IAuxInterface2 _arg0;
+_arg0 = android.test.IAuxInterface2.Stub.asInterface(data.readStrongBinder());
+int _result = this.takesAnInterface(_arg0);
+reply.writeNoException();
+reply.writeInt(_result);
+return true;
+}
+case TRANSACTION_takesAParcelable:
+{
+data.enforceInterface(DESCRIPTOR);
+android.test.CompoundParcelable.Subclass1 _arg0;
+if ((0!=data.readInt())) {
+_arg0 = android.test.CompoundParcelable.Subclass1.CREATOR.createFromParcel(data);
+}
+else {
+_arg0 = null;
+}
+android.test.CompoundParcelable.Subclass2 _arg1;
+if ((0!=data.readInt())) {
+_arg1 = android.test.CompoundParcelable.Subclass2.CREATOR.createFromParcel(data);
+}
+else {
+_arg1 = null;
+}
+int _result = this.takesAParcelable(_arg0, _arg1);
+reply.writeNoException();
+reply.writeInt(_result);
+if ((_arg1!=null)) {
+reply.writeInt(1);
+_arg1.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+}
+else {
+reply.writeInt(0);
+}
+return true;
+}
+}
+return super.onTransact(code, data, reply, flags);
+}
+private static class Proxy implements android.test.IExampleInterface
+{
+private android.os.IBinder mRemote;
+Proxy(android.os.IBinder remote)
+{
+mRemote = remote;
+}
+@Override public android.os.IBinder asBinder()
+{
+return mRemote;
+}
+public java.lang.String getInterfaceDescriptor()
+{
+return DESCRIPTOR;
+}
+@Override public boolean isEnabled() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+boolean _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_isEnabled, _data, _reply, 0);
+_reply.readException();
+_result = (0!=_reply.readInt());
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public int getState() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+int _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getState, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readInt();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public java.lang.String getAddress() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+java.lang.String _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getAddress, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readString();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+/* Test long comment */
+@Override public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+android.foo.ExampleParcelable[] _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getParcelables, _data, _reply, 0);
+_reply.readException();
+_result = _reply.createTypedArray(android.foo.ExampleParcelable.CREATOR);
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+// Test short comment
+
+@Override public boolean setScanMode(int mode, int duration) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+boolean _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+_data.writeInt(mode);
+_data.writeInt(duration);
+mRemote.transact(Stub.TRANSACTION_setScanMode, _data, _reply, 0);
+_reply.readException();
+_result = (0!=_reply.readInt());
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+/* Test long comment */// And short comment
+
+@Override public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+_data.writeStrongBinder((((foo!=null))?(foo.asBinder()):(null)));
+mRemote.transact(Stub.TRANSACTION_registerBinder, _data, _reply, 0);
+_reply.readException();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+}
+@Override public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+android.test.IExampleInterface _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+mRemote.transact(Stub.TRANSACTION_getRecursiveBinder, _data, _reply, 0);
+_reply.readException();
+_result = android.test.IExampleInterface.Stub.asInterface(_reply.readStrongBinder());
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+int _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+_data.writeStrongBinder((((arg!=null))?(arg.asBinder()):(null)));
+mRemote.transact(Stub.TRANSACTION_takesAnInterface, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readInt();
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+@Override public int takesAParcelable(android.test.CompoundParcelable.Subclass1 arg, android.test.CompoundParcelable.Subclass2 arg2) throws android.os.RemoteException
+{
+android.os.Parcel _data = android.os.Parcel.obtain();
+android.os.Parcel _reply = android.os.Parcel.obtain();
+int _result;
+try {
+_data.writeInterfaceToken(DESCRIPTOR);
+if ((arg!=null)) {
+_data.writeInt(1);
+arg.writeToParcel(_data, 0);
+}
+else {
+_data.writeInt(0);
+}
+if ((arg2!=null)) {
+_data.writeInt(1);
+arg2.writeToParcel(_data, 0);
+}
+else {
+_data.writeInt(0);
+}
+mRemote.transact(Stub.TRANSACTION_takesAParcelable, _data, _reply, 0);
+_reply.readException();
+_result = _reply.readInt();
+if ((0!=_reply.readInt())) {
+arg2.readFromParcel(_reply);
+}
+}
+finally {
+_reply.recycle();
+_data.recycle();
+}
+return _result;
+}
+}
+static final int TRANSACTION_isEnabled = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
+static final int TRANSACTION_getState = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
+static final int TRANSACTION_getAddress = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
+static final int TRANSACTION_getParcelables = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
+static final int TRANSACTION_setScanMode = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
+static final int TRANSACTION_registerBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
+static final int TRANSACTION_getRecursiveBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
+static final int TRANSACTION_takesAnInterface = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
+static final int TRANSACTION_takesAParcelable = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
+}
+public static final int EXAMPLE_CONSTANT = 3;
+public boolean isEnabled() throws android.os.RemoteException;
+public int getState() throws android.os.RemoteException;
+public java.lang.String getAddress() throws android.os.RemoteException;
+/* Test long comment */
+public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
+// Test short comment
+
+public boolean setScanMode(int mode, int duration) throws android.os.RemoteException;
+/* Test long comment */// And short comment
+
+public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException;
+public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException;
+public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException;
+public int takesAParcelable(android.test.CompoundParcelable.Subclass1 arg, android.test.CompoundParcelable.Subclass2 arg2) throws android.os.RemoteException;
+}
+)";
+
+}  // namespace example_interface
+}  // namespace test_data
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/test_data_ping_responder.cpp b/aidl/tests/test_data_ping_responder.cpp
new file mode 100644
index 0000000..40cb602
--- /dev/null
+++ b/aidl/tests/test_data_ping_responder.cpp
@@ -0,0 +1,461 @@
+/*
+ * 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 "tests/test_data.h"
+
+namespace android {
+namespace aidl {
+namespace test_data {
+namespace ping_responder {
+
+const char kCanonicalName[] = "android.os.IPingResponder";
+const char kInterfaceDefinition[] = R"(
+package android.os;
+
+import bar.Unused;
+
+interface IPingResponder {
+  String Ping(String input);
+
+  @nullable
+  String NullablePing(@nullable String input);
+
+  @utf8InCpp
+  String Utf8Ping(@utf8InCpp String input);
+
+  @utf8InCpp @nullable
+  String NullableUtf8Ping(@utf8InCpp @nullable String input);
+}
+)";
+
+const char kCppOutputPath[] = "some/path/to/output.cpp";
+
+const char kCppParcelableHeader[] = "cpp-header-str";
+
+const char* kImportedParcelables[] = {
+  "bar.Unused",
+  nullptr,
+};
+
+const char* kImportedInterfaces[] = {
+  nullptr,
+};
+
+const char kGenHeaderDir[] = "some/path";
+const char kGenInterfaceHeaderPath[] = "some/path/android/os/IPingResponder.h";
+const char kGenClientHeaderPath[] = "some/path/android/os/BpPingResponder.h";
+const char kGenServerHeaderPath[] = "some/path/android/os/BnPingResponder.h";
+
+const char kExpectedCppDepsOutput[] =
+R"(some/path/to/output.cpp : \
+  android/os/IPingResponder.aidl \
+  ./bar/Unused.aidl
+
+android/os/IPingResponder.aidl :
+./bar/Unused.aidl :
+
+some/path/android/os/BpPingResponder.h \
+    some/path/android/os/BnPingResponder.h \
+    some/path/android/os/IPingResponder.h : \
+    android/os/IPingResponder.aidl \
+    ./bar/Unused.aidl
+)";
+
+const char kExpectedCppOutput[] =
+R"(#include <android/os/IPingResponder.h>
+#include <android/os/BpPingResponder.h>
+
+namespace android {
+
+namespace os {
+
+IMPLEMENT_META_INTERFACE(PingResponder, "android.os.IPingResponder")
+
+}  // namespace os
+
+}  // namespace android
+#include <android/os/BpPingResponder.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+namespace os {
+
+BpPingResponder::BpPingResponder(const ::android::sp<::android::IBinder>& _aidl_impl)
+    : BpInterface<IPingResponder>(_aidl_impl){
+}
+
+::android::binder::Status BpPingResponder::Ping(const ::android::String16& input, ::android::String16* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeString16(input);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IPingResponder::PING, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readString16(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpPingResponder::NullablePing(const ::std::unique_ptr<::android::String16>& input, ::std::unique_ptr<::android::String16>* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeString16(input);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IPingResponder::NULLABLEPING, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readString16(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpPingResponder::Utf8Ping(const ::std::string& input, ::std::string* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeUtf8AsUtf16(input);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IPingResponder::UTF8PING, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readUtf8FromUtf16(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+::android::binder::Status BpPingResponder::NullableUtf8Ping(const ::std::unique_ptr<::std::string>& input, ::std::unique_ptr<::std::string>* _aidl_return) {
+::android::Parcel _aidl_data;
+::android::Parcel _aidl_reply;
+::android::status_t _aidl_ret_status = ::android::OK;
+::android::binder::Status _aidl_status;
+_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_data.writeUtf8AsUtf16(input);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = remote()->transact(IPingResponder::NULLABLEUTF8PING, _aidl_data, &_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+if (!_aidl_status.isOk()) {
+return _aidl_status;
+}
+_aidl_ret_status = _aidl_reply.readUtf8FromUtf16(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+goto _aidl_error;
+}
+_aidl_error:
+_aidl_status.setFromStatusT(_aidl_ret_status);
+return _aidl_status;
+}
+
+}  // namespace os
+
+}  // namespace android
+#include <android/os/BnPingResponder.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+namespace os {
+
+::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) {
+case Call::PING:
+{
+::android::String16 in_input;
+::android::String16 _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readString16(&in_input);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(Ping(in_input, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeString16(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+case Call::NULLABLEPING:
+{
+::std::unique_ptr<::android::String16> in_input;
+::std::unique_ptr<::android::String16> _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readString16(&in_input);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(NullablePing(in_input, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeString16(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+case Call::UTF8PING:
+{
+::std::string in_input;
+::std::string _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_input);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(Utf8Ping(in_input, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeUtf8AsUtf16(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+case Call::NULLABLEUTF8PING:
+{
+::std::unique_ptr<::std::string> in_input;
+::std::unique_ptr<::std::string> _aidl_return;
+if (!(_aidl_data.checkInterface(this))) {
+_aidl_ret_status = ::android::BAD_TYPE;
+break;
+}
+_aidl_ret_status = _aidl_data.readUtf8FromUtf16(&in_input);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+::android::binder::Status _aidl_status(NullableUtf8Ping(in_input, &_aidl_return));
+_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+if (!_aidl_status.isOk()) {
+break;
+}
+_aidl_ret_status = _aidl_reply->writeUtf8AsUtf16(_aidl_return);
+if (((_aidl_ret_status) != (::android::OK))) {
+break;
+}
+}
+break;
+default:
+{
+_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
+}
+break;
+}
+if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
+_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
+}
+return _aidl_ret_status;
+}
+
+}  // namespace os
+
+}  // namespace android
+)";
+
+const char kExpectedIHeaderOutput[] =
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_PING_RESPONDER_H_
+#define AIDL_GENERATED_ANDROID_OS_I_PING_RESPONDER_H_
+
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <binder/Status.h>
+#include <memory>
+#include <string>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace os {
+
+class IPingResponder : public ::android::IInterface {
+public:
+DECLARE_META_INTERFACE(PingResponder)
+virtual ::android::binder::Status Ping(const ::android::String16& input, ::android::String16* _aidl_return) = 0;
+virtual ::android::binder::Status NullablePing(const ::std::unique_ptr<::android::String16>& input, ::std::unique_ptr<::android::String16>* _aidl_return) = 0;
+virtual ::android::binder::Status Utf8Ping(const ::std::string& input, ::std::string* _aidl_return) = 0;
+virtual ::android::binder::Status NullableUtf8Ping(const ::std::unique_ptr<::std::string>& input, ::std::unique_ptr<::std::string>* _aidl_return) = 0;
+enum Call {
+  PING = ::android::IBinder::FIRST_CALL_TRANSACTION + 0,
+  NULLABLEPING = ::android::IBinder::FIRST_CALL_TRANSACTION + 1,
+  UTF8PING = ::android::IBinder::FIRST_CALL_TRANSACTION + 2,
+  NULLABLEUTF8PING = ::android::IBinder::FIRST_CALL_TRANSACTION + 3,
+};
+};  // class IPingResponder
+
+}  // namespace os
+
+}  // namespace android
+
+#endif  // AIDL_GENERATED_ANDROID_OS_I_PING_RESPONDER_H_
+)";
+
+const char kExpectedBpHeaderOutput[] =
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_BP_PING_RESPONDER_H_
+#define AIDL_GENERATED_ANDROID_OS_BP_PING_RESPONDER_H_
+
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <utils/Errors.h>
+#include <android/os/IPingResponder.h>
+
+namespace android {
+
+namespace os {
+
+class BpPingResponder : public ::android::BpInterface<IPingResponder> {
+public:
+explicit BpPingResponder(const ::android::sp<::android::IBinder>& _aidl_impl);
+virtual ~BpPingResponder() = default;
+::android::binder::Status Ping(const ::android::String16& input, ::android::String16* _aidl_return) override;
+::android::binder::Status NullablePing(const ::std::unique_ptr<::android::String16>& input, ::std::unique_ptr<::android::String16>* _aidl_return) override;
+::android::binder::Status Utf8Ping(const ::std::string& input, ::std::string* _aidl_return) override;
+::android::binder::Status NullableUtf8Ping(const ::std::unique_ptr<::std::string>& input, ::std::unique_ptr<::std::string>* _aidl_return) override;
+};  // class BpPingResponder
+
+}  // namespace os
+
+}  // namespace android
+
+#endif  // AIDL_GENERATED_ANDROID_OS_BP_PING_RESPONDER_H_
+)";
+
+const char kExpectedBnHeaderOutput[] =
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
+#define AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
+
+#include <binder/IInterface.h>
+#include <android/os/IPingResponder.h>
+
+namespace android {
+
+namespace os {
+
+class BnPingResponder : public ::android::BnInterface<IPingResponder> {
+public:
+::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags = 0) override;
+};  // class BnPingResponder
+
+}  // namespace os
+
+}  // namespace android
+
+#endif  // AIDL_GENERATED_ANDROID_OS_BN_PING_RESPONDER_H_
+)";
+
+}  // namespace ping_responder
+}  // namespace test_data
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/test_data_string_constants.cpp b/aidl/tests/test_data_string_constants.cpp
new file mode 100644
index 0000000..4674843
--- /dev/null
+++ b/aidl/tests/test_data_string_constants.cpp
@@ -0,0 +1,195 @@
+/*
+ * 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 "tests/test_data.h"
+
+namespace android {
+namespace aidl {
+namespace test_data {
+namespace string_constants {
+
+const char kCanonicalName[] = "android.os.IStringConstants";
+const char kInterfaceDefinition[] = R"(
+package android.os;
+
+interface IStringConstants {
+  const String EXAMPLE_CONSTANT = "foo";
+}
+)";
+
+const char kJavaOutputPath[] = "some/path/to/output.java";
+const char kExpectedJavaOutput[] =
+R"(/*
+ * This file is auto-generated.  DO NOT MODIFY.
+ * Original file: android/os/IStringConstants.aidl
+ */
+package android.os;
+public interface IStringConstants extends android.os.IInterface
+{
+/** Local-side IPC implementation stub class. */
+public static abstract class Stub extends android.os.Binder implements android.os.IStringConstants
+{
+private static final java.lang.String DESCRIPTOR = "android.os.IStringConstants";
+/** Construct the stub at attach it to the interface. */
+public Stub()
+{
+this.attachInterface(this, DESCRIPTOR);
+}
+/**
+ * Cast an IBinder object into an android.os.IStringConstants interface,
+ * generating a proxy if needed.
+ */
+public static android.os.IStringConstants asInterface(android.os.IBinder obj)
+{
+if ((obj==null)) {
+return null;
+}
+android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
+if (((iin!=null)&&(iin instanceof android.os.IStringConstants))) {
+return ((android.os.IStringConstants)iin);
+}
+return new android.os.IStringConstants.Stub.Proxy(obj);
+}
+@Override public android.os.IBinder asBinder()
+{
+return this;
+}
+@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
+{
+switch (code)
+{
+case INTERFACE_TRANSACTION:
+{
+reply.writeString(DESCRIPTOR);
+return true;
+}
+}
+return super.onTransact(code, data, reply, flags);
+}
+private static class Proxy implements android.os.IStringConstants
+{
+private android.os.IBinder mRemote;
+Proxy(android.os.IBinder remote)
+{
+mRemote = remote;
+}
+@Override public android.os.IBinder asBinder()
+{
+return mRemote;
+}
+public java.lang.String getInterfaceDescriptor()
+{
+return DESCRIPTOR;
+}
+}
+}
+public static final String EXAMPLE_CONSTANT = "foo";
+}
+)";
+
+const char kCppOutputPath[] = "some/path/to/output.cpp";
+const char kGenHeaderDir[] = "output";
+const char kGenInterfaceHeaderPath[] = "output/android/os/IStringConstants.h";
+const char kExpectedIHeaderOutput[] =
+R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_STRING_CONSTANTS_H_
+#define AIDL_GENERATED_ANDROID_OS_I_STRING_CONSTANTS_H_
+
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <binder/Status.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace os {
+
+class IStringConstants : public ::android::IInterface {
+public:
+DECLARE_META_INTERFACE(StringConstants)
+static const ::android::String16& EXAMPLE_CONSTANT();
+};  // class IStringConstants
+
+}  // namespace os
+
+}  // namespace android
+
+#endif  // AIDL_GENERATED_ANDROID_OS_I_STRING_CONSTANTS_H_
+)";
+
+const char kExpectedCppOutput[] =
+R"(#include <android/os/IStringConstants.h>
+#include <android/os/BpStringConstants.h>
+
+namespace android {
+
+namespace os {
+
+IMPLEMENT_META_INTERFACE(StringConstants, "android.os.IStringConstants")
+
+const ::android::String16& IStringConstants::EXAMPLE_CONSTANT() {
+static const ::android::String16 value("foo");
+return value;
+}
+
+}  // namespace os
+
+}  // namespace android
+#include <android/os/BpStringConstants.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+namespace os {
+
+BpStringConstants::BpStringConstants(const ::android::sp<::android::IBinder>& _aidl_impl)
+    : BpInterface<IStringConstants>(_aidl_impl){
+}
+
+}  // namespace os
+
+}  // namespace android
+#include <android/os/BnStringConstants.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+namespace os {
+
+::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) {
+default:
+{
+_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
+}
+break;
+}
+if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
+_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
+}
+return _aidl_ret_status;
+}
+
+}  // namespace os
+
+}  // namespace android
+)";
+
+}  // namespace string_constants
+}  // namespace test_data
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/test_helpers.h b/aidl/tests/test_helpers.h
new file mode 100644
index 0000000..7d5145b
--- /dev/null
+++ b/aidl/tests/test_helpers.h
@@ -0,0 +1,78 @@
+/*
+ * 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 <algorithm>
+#include <vector>
+
+#include <android-base/logging.h>
+#include <binder/Status.h>
+#include <utils/StrongPointer.h>
+
+#include "android/aidl/tests/ITestService.h"
+
+namespace android {
+namespace aidl {
+namespace tests {
+namespace client {
+
+template <typename T, typename U>
+bool RepeatPrimitive(
+    const android::sp<android::aidl::tests::ITestService>& service,
+    android::binder::Status(android::aidl::tests::ITestService::*func)(T, T*),
+    U input) {
+  T reply;
+  android::binder::Status status = (*service.*func)(input, &reply);
+  if (!status.isOk() || input != reply) {
+    LOG(ERROR) << "Failed to repeat primitive. status=" << status.toString8()
+               << ".";
+    return false;
+  }
+  return true;
+}
+
+template <typename T>
+bool ReverseArray(
+    const android::sp<android::aidl::tests::ITestService>& service,
+    android::binder::Status(android::aidl::tests::ITestService::*func)(
+        const std::vector<T>&, std::vector<T>*, std::vector<T>*),
+        std::vector<T> input) {
+  std::vector<T> actual_reversed;
+  std::vector<T> actual_repeated;
+  android::binder::Status status = (*service.*func)(
+      input, &actual_repeated, &actual_reversed);
+  if (!status.isOk()) {
+    LOG(ERROR) << "Failed to repeat array. status=" << status.toString8()
+               << ".";
+    return false;
+  }
+  if (input != actual_repeated) {
+    LOG(ERROR) << "Repeated version of array did not match";
+    LOG(ERROR) << "input.size()=" << input.size()
+               << " repeated.size()=" << actual_repeated.size();
+    return false;
+  }
+  std::reverse(input.begin(), input.end());
+  if (input != actual_reversed) {
+    LOG(ERROR) << "Reversed version of array did not match";
+    return false;
+  }
+  return true;
+}
+
+}  // namespace client
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/tests/test_util.cpp b/aidl/tests/test_util.cpp
new file mode 100644
index 0000000..9cb52f3
--- /dev/null
+++ b/aidl/tests/test_util.cpp
@@ -0,0 +1,168 @@
+/*
+ * 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 <algorithm>
+#include <iostream>
+#include <iterator>
+
+#include <android-base/strings.h>
+
+#include "os.h"
+#include "tests/test_util.h"
+
+using android::base::Split;
+using android::base::Join;
+using std::string;
+using std::vector;
+using std::cout;
+using std::endl;
+using std::distance;
+
+namespace android {
+namespace aidl {
+namespace test {
+
+string CanonicalNameToPath(const char* package_class, const char* extension) {
+  string rel_path{package_class};
+  for (char& c : rel_path) {
+    if (c == '.') {
+      c = OS_PATH_SEPARATOR;
+    }
+  }
+  rel_path += extension;
+  return rel_path;
+}
+
+void SplitPackageClass(const string& package_class,
+                       string* rel_path,
+                       string* package,
+                       string* class_name) {
+  *package = string{package_class, 0, package_class.rfind('.')};
+  *class_name = string{package_class, package_class.rfind('.') + 1};
+  *rel_path = CanonicalNameToPath(package_class.c_str(), ".aidl");
+}
+
+void PrintDiff(const string& a, const string& b) {
+  const int LEFT = 1;
+  const int UP = 2;
+  const int UP_LEFT = 4;
+
+  auto a_lines = Split(a, "\n");
+  auto b_lines = Split(b, "\n");
+
+  struct diff_table_entry {
+    size_t longest_common_subsequence_length;
+    int propagation_directions;
+  };
+
+  diff_table_entry table[a_lines.size() + 1][b_lines.size() + 1];
+
+  for (size_t i = 0; i < a_lines.size() + 1; ++i) {
+    for (size_t j = 0; j < b_lines.size() + 1; ++j) {
+      if (i == 0 || j == 0) {
+        int directions = 0;
+
+        if (i) {
+          directions |= UP;
+        }
+
+        if (j) {
+          directions |= LEFT;
+        }
+
+        table[i][j].longest_common_subsequence_length = 0;
+        table[i][j].propagation_directions = directions;
+      } else if (a_lines[i-1] == b_lines[j-1]) {
+        table[i][j].longest_common_subsequence_length =
+            table[i-1][j-1].longest_common_subsequence_length + 1;
+        table[i][j].propagation_directions = UP_LEFT;
+      } else {
+        size_t length_up = table[i-1][j].longest_common_subsequence_length;
+        size_t length_left = table[i][j-1].longest_common_subsequence_length;
+        int directions = 0;
+        size_t length;
+
+        if (length_up >= length_left) {
+          directions |= UP;
+          length = length_up;
+        }
+
+        if (length_left >= length_up) {
+          directions |= LEFT;
+          length = length_left;
+        }
+
+        table[i][j].longest_common_subsequence_length = length;
+        table[i][j].propagation_directions = directions;
+      }
+    }
+  }
+
+  size_t i = a_lines.size();
+  size_t j = b_lines.size();
+  vector<string> output;
+
+  while (table[i][j].propagation_directions) {
+    if (table[i][j].propagation_directions & UP_LEFT) {
+      output.push_back(" " + a_lines[i-1]);
+      i--;
+      j--;
+    } else if (table[i][j].propagation_directions & UP) {
+      output.push_back("-" + a_lines[i-1]);
+      i--;
+    } else {
+      output.push_back("+" + b_lines[j-1]);
+      j--;
+    }
+  }
+
+  int print_mask = 0;
+  bool printed_last = false;
+  size_t line_number = 0;
+
+  for (auto it = output.crbegin(), frontier = output.crbegin();
+       it != output.crend(); ++it) {
+    while (frontier != output.crend() && distance(it, frontier) <= 3) {
+      print_mask <<= 1;
+      print_mask &= 0x7f;
+
+      if ((*frontier)[0] != ' ') {
+        print_mask |= 1;
+      }
+
+      frontier++;
+    }
+
+    if ((*it)[0] != '-') {
+      line_number++;
+    }
+
+    if (print_mask) {
+      if (!printed_last) {
+        cout << "Line: " << line_number << endl;
+      }
+
+      cout << *it << endl;
+      printed_last = true;
+    } else {
+      printed_last = false;
+    }
+  }
+}
+
+}  // namespace test
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/tests/test_util.h b/aidl/tests/test_util.h
new file mode 100644
index 0000000..34b9e5d
--- /dev/null
+++ b/aidl/tests/test_util.h
@@ -0,0 +1,40 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_TESTS_TEST_UTIL_H_
+#define AIDL_TESTS_TEST_UTIL_H_
+
+#include <string>
+
+namespace android {
+namespace aidl {
+namespace test {
+
+std::string CanonicalNameToPath(const char* package_class,
+                                const char* extension);
+
+void SplitPackageClass(const std::string& package_class,
+                       std::string* rel_path,
+                       std::string* package,
+                       std::string* class_name);
+
+void PrintDiff(const std::string& a, const std::string& b);
+
+}  // namespace test
+}  // namespace android
+}  // namespace aidl
+
+#endif // AIDL_TESTS_TEST_UTIL_H_
diff --git a/aidl/type_cpp.cpp b/aidl/type_cpp.cpp
new file mode 100644
index 0000000..2c0552d
--- /dev/null
+++ b/aidl/type_cpp.cpp
@@ -0,0 +1,567 @@
+/*
+ * 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 <vector>
+
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
+#include "logging.h"
+
+using std::cerr;
+using std::endl;
+using std::set;
+using std::string;
+using std::unique_ptr;
+using std::vector;
+
+using android::base::Split;
+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;
+
+bool is_cpp_keyword(const std::string& str) {
+  static const std::vector<std::string> kCppKeywords{
+    "alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor",
+    "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class",
+    "compl", "concept", "const", "constexpr", "const_cast", "continue",
+    "decltype", "default", "delete", "do", "double", "dynamic_cast", "else",
+    "enum", "explicit", "export", "extern", "false", "float", "for", "friend",
+    "goto", "if", "inline", "int", "long", "mutable", "namespace", "new",
+    "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
+    "private", "protected", "public", "register", "reinterpret_cast",
+    "requires", "return", "short", "signed", "sizeof", "static",
+    "static_assert", "static_cast", "struct", "switch", "template", "this",
+    "thread_local", "throw", "true", "try", "typedef", "typeid", "typename",
+    "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t",
+    "while", "xor", "xor_eq",
+  };
+  return std::find(kCppKeywords.begin(), kCppKeywords.end(), str) !=
+      kCppKeywords.end();
+}
+
+class VoidType : public Type {
+ public:
+  VoidType() : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "void",
+                    {}, "void", kNoValidMethod, kNoValidMethod) {}
+  virtual ~VoidType() = default;
+  bool CanBeOutParameter() const override { return false; }
+  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& 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,
+                                    read_method, write_method, true),
+             src_file_name) {}
+
+  bool CanBeOutParameter() const override { return true; }
+
+ 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,
+                              read_array_method, write_array_method,
+                              false)) {}
+
+  virtual ~PrimitiveType() = 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",
+                              "readByteVector", "writeByteVector",
+                              false)) {}
+
+  virtual ~ByteType() = default;
+  bool IsCppPrimitive() const override { return true; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ByteType);
+};  // class PrimitiveType
+
+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") {}
+  virtual ~BinderType() = 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, interface.GetLine()),
+        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;
+  }
+
+  static string GetCppHeader(const AidlInterface& interface) {
+    vector<string> name = interface.GetSplitPackage();
+    name.push_back(interface.GetName());
+    return Join(name, '/') + ".h";
+  }
+
+  std::string write_cast_;
+};
+
+class NullableParcelableType : public Type {
+ public:
+  NullableParcelableType(const AidlParcelable& parcelable,
+                         const std::string& src_file_name)
+      : Type(ValidatableType::KIND_PARCELABLE,
+             parcelable.GetPackage(), parcelable.GetName(),
+             {parcelable.GetCppHeader()}, GetCppName(parcelable),
+             "readParcelable", "writeNullableParcelable",
+             kNoArrayType, kNoNullableType,
+             src_file_name, parcelable.GetLine()) {}
+  virtual ~NullableParcelableType() = default;
+  bool CanBeOutParameter() const override { return true; }
+
+ private:
+  static string GetCppName(const AidlParcelable& parcelable) {
+    return "::std::unique_ptr<::" + Join(parcelable.GetSplitPackage(), "::") +
+        "::" + parcelable.GetName() + ">";
+  }
+};
+
+class ParcelableType : public Type {
+ public:
+  ParcelableType(const AidlParcelable& parcelable,
+                 const std::string& src_file_name)
+      : Type(ValidatableType::KIND_PARCELABLE,
+             parcelable.GetPackage(), parcelable.GetName(),
+             {parcelable.GetCppHeader()}, GetCppName(parcelable),
+             "readParcelable", "writeParcelable",
+             new CppArrayType(
+                 ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(),
+                 parcelable.GetName(), parcelable.GetCppHeader(),
+                 GetCppName(parcelable),
+                 "readParcelableVector", "writeParcelableVector", false,
+                 src_file_name),
+             new NullableParcelableType(parcelable, src_file_name),
+             src_file_name, parcelable.GetLine()) {}
+  virtual ~ParcelableType() = default;
+  bool CanBeOutParameter() const override { return true; }
+
+ private:
+  static string GetCppName(const AidlParcelable& parcelable) {
+    return "::" + Join(parcelable.GetSplitPackage(), "::") +
+        "::" + parcelable.GetName();
+  }
+};
+
+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") {}
+  virtual ~NullableStringListType() = default;
+  bool CanBeOutParameter() const override { return true; }
+
+ 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()) {}
+  virtual ~StringListType() = default;
+  bool CanBeOutParameter() const override { return true; }
+
+ 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") {}
+  virtual ~NullableUtf8InCppStringListType() = default;
+  bool CanBeOutParameter() const override { return true; }
+
+ 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()) {}
+  virtual ~Utf8InCppStringListType() = default;
+  bool CanBeOutParameter() const override { return true; }
+
+ 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") {}
+  virtual ~NullableBinderListType() = default;
+  bool CanBeOutParameter() const override { return true; }
+
+ 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()) {}
+  virtual ~BinderListType() = default;
+  bool CanBeOutParameter() const override { return true; }
+
+ 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(new ByteType());
+  Add(new PrimitiveType(
+      "int",
+      "cstdint", "int32_t", "readInt32", "writeInt32",
+      "readInt32Vector", "writeInt32Vector"));
+  Add(new PrimitiveType(
+      "long",
+      "cstdint", "int64_t", "readInt64", "writeInt64",
+      "readInt64Vector", "writeInt64Vector"));
+  Add(new PrimitiveType(
+      "float",
+      kNoHeader, "float", "readFloat", "writeFloat",
+      "readFloatVector", "writeFloatVector"));
+  Add(new PrimitiveType(
+      "double",
+      kNoHeader, "double", "readDouble", "writeDouble",
+      "readDoubleVector", "writeDoubleVector"));
+  Add(new PrimitiveType(
+      "boolean",
+      kNoHeader, "bool", "readBool", "writeBool",
+      "readBoolVector", "writeBoolVector"));
+  // C++11 defines the char16_t type as a built in for Unicode characters.
+  Add(new 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",
+      "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");
+
+  string_type_ = new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
+                          {"utils/String16.h"}, "::android::String16",
+                          "readString16", "writeString16",
+                          string_array_type, nullable_string_type);
+  Add(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",
+      "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
+      false);
+  Type* nullable_cpp_utf8_string_type = new Type(
+      ValidatableType::KIND_BUILT_IN,
+      kAidlReservedTypePackage, kUtf8InCppStringClass,
+      {"string", "memory"}, "::std::unique_ptr<::std::string>",
+      "readUtf8FromUtf16", "writeUtf8AsUtf16");
+  Add(new Type(
+      ValidatableType::KIND_BUILT_IN,
+      kAidlReservedTypePackage, kUtf8InCppStringClass,
+      {"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");
+  ibinder_type_ = new Type(
+      ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
+      {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
+      "readStrongBinder", "writeStrongBinder",
+      kNoArrayType, nullable_ibinder);
+  Add(ibinder_type_);
+
+  Add(new BinderListType());
+  Add(new StringListType());
+  Add(new Utf8InCppStringListType());
+
+  Type* fd_vector_type = new CppArrayType(
+      ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
+      "android-base/unique_fd.h",
+      "::android::base::unique_fd",
+      "readUniqueFileDescriptorVector", "writeUniqueFileDescriptorVector",
+      false);
+
+  Add(new Type(
+      ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
+      {"android-base/unique_fd.h"}, "::android::base::unique_fd",
+      "readUniqueFileDescriptor", "writeUniqueFileDescriptor",
+      fd_vector_type));
+
+  void_type_ = new class VoidType();
+  Add(void_type_);
+}
+
+bool TypeNamespace::AddParcelableType(const AidlParcelable& p,
+                                      const string& filename) {
+  if (p.GetCppHeader().empty()) {
+    LOG(ERROR) << "Parcelable " << p.GetCanonicalName()
+               << " has no C++ header defined.";
+    return false;
+  }
+  Add(new ParcelableType(p, filename));
+  return true;
+}
+
+bool TypeNamespace::AddBinderType(const AidlInterface& b,
+                                  const string& file_name) {
+  Add(new BinderType(b, file_name));
+  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;
+}
+
+bool TypeNamespace::IsValidPackage(const string& package) const {
+  if (package.empty()) {
+    return false;
+  }
+
+  auto pieces = Split(package, ".");
+  for (const string& piece : pieces) {
+    if (is_cpp_keyword(piece)) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a,
+    int arg_index,
+    const std::string& filename,
+    const AidlInterface& interface) const {
+  const string error_prefix = StringPrintf(
+      "In file %s line %d parameter %s (%d):\n    ",
+      filename.c_str(), a.GetLine(), a.GetName().c_str(), arg_index);
+
+  // check that the name doesn't match a keyword
+  if (is_cpp_keyword(a.GetName().c_str())) {
+    cerr << error_prefix << "Argument name is a C++ keyword"
+         << endl;
+    return nullptr;
+  }
+
+  return ::android::aidl::TypeNamespace::GetArgType(a, arg_index, filename,
+                                                    interface);
+}
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/type_cpp.h b/aidl/type_cpp.h
new file mode 100644
index 0000000..0a6a4a9
--- /dev/null
+++ b/aidl/type_cpp.h
@@ -0,0 +1,125 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_TYPE_CPP_H_
+#define AIDL_TYPE_CPP_H_
+
+#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 CanBeOutParameter() const override { return false; }
+  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;
+
+  bool IsValidPackage(const std::string& package) const override;
+  const ValidatableType* GetArgType(const AidlArgument& a,
+                             int arg_index,
+                             const std::string& filename,
+                             const AidlInterface& interface) const override;
+
+  const Type* VoidType() const { return void_type_; }
+  const Type* IBinderType() const { return ibinder_type_; }
+
+ private:
+  Type* void_type_ = nullptr;
+  Type* string_type_ = nullptr;
+  Type* ibinder_type_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(TypeNamespace);
+};  // class TypeNamespace
+
+}  // namespace cpp
+}  // namespace aidl
+}  // namespace android
+
+#endif  // AIDL_TYPE_NAMESPACE_CPP_H_
diff --git a/aidl/type_cpp_unittest.cpp b/aidl/type_cpp_unittest.cpp
new file mode 100644
index 0000000..35fc3d5
--- /dev/null
+++ b/aidl/type_cpp_unittest.cpp
@@ -0,0 +1,53 @@
+/*
+ * 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 "type_cpp.h"
+
+namespace android {
+namespace aidl {
+namespace cpp {
+
+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>"));
+}
+
+}  // namespace cpp
+}  // namespace android
+}  // namespace aidl
diff --git a/aidl/type_java.cpp b/aidl/type_java.cpp
new file mode 100644
index 0000000..18d27a2
--- /dev/null
+++ b/aidl/type_java.cpp
@@ -0,0 +1,908 @@
+/*
+ * 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 <android-base/strings.h>
+
+#include "aidl_language.h"
+#include "logging.h"
+
+using std::string;
+using android::base::Split;
+using android::base::Join;
+using android::base::Trim;
+
+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, bool canBeOut)
+    : Type(types, "", name, kind, canWriteToParcel, canBeOut, "", -1) {}
+
+Type::Type(const JavaTypeNamespace* types, const string& package,
+           const string& name, int kind, bool canWriteToParcel,
+           bool canBeOut, const string& declFile, int declLine)
+    : ValidatableType(kind, package, name, declFile, declLine),
+      m_types(types),
+      m_javaType((package.empty()) ? name : package + "." + name),
+      m_canWriteToParcel(canWriteToParcel),
+      m_canBeOut(canBeOut) {
+}
+
+string Type::CreatorName() const { return ""; }
+
+string Type::InstantiableName() const { return JavaType(); }
+
+void Type::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                         int flags) const {
+  fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%sn", __FILE__,
+          __LINE__, m_javaType.c_str());
+  addTo->Add(new LiteralExpression("/* WriteToParcel error " + m_javaType +
+                                   " */"));
+}
+
+void Type::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                            Variable* parcel, Variable**) const {
+  fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", __FILE__,
+          __LINE__, m_javaType.c_str());
+  addTo->Add(new LiteralExpression("/* CreateFromParcel error " +
+                                   m_javaType + " */"));
+}
+
+void Type::ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                          Variable**) const {
+  fprintf(stderr, "aidl:internal error %s:%d qualifiedName=%s\n", __FILE__,
+          __LINE__, m_javaType.c_str());
+  addTo->Add(new LiteralExpression("/* ReadFromParcel error " +
+                                   m_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(),
+                             "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, false),
+      m_marshallParcel(marshallParcel),
+      m_unmarshallParcel(unmarshallParcel) {
+  m_array_type.reset(new BasicArrayType(types, name, writeArrayParcel,
+                                        createArrayParcel, readArrayParcel));
+}
+
+void BasicType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                              Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, m_marshallParcel, 1, v));
+}
+
+void BasicType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                 Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, m_unmarshallParcel)));
+}
+
+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, true),
+      m_writeArrayParcel(writeArrayParcel),
+      m_createArrayParcel(createArrayParcel),
+      m_readArrayParcel(readArrayParcel) {}
+
+
+void BasicArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                   Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, m_writeArrayParcel, 1, v));
+}
+
+void BasicArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                      Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, m_createArrayParcel)));
+}
+
+void BasicArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                                    Variable* parcel, Variable**) const {
+  addTo->Add(new MethodCall(parcel, m_readArrayParcel, 1, v));
+}
+
+// ================================================================
+
+FileDescriptorType::FileDescriptorType(const JavaTypeNamespace* types)
+    : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN,
+           true, false) {
+    m_array_type.reset(new FileDescriptorArrayType(types));
+}
+
+void FileDescriptorType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                       Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeRawFileDescriptor", 1, v));
+}
+
+void FileDescriptorType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                          Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "readRawFileDescriptor")));
+}
+
+FileDescriptorArrayType::FileDescriptorArrayType(const JavaTypeNamespace* types)
+    : Type(types, "java.io", "FileDescriptor", ValidatableType::KIND_BUILT_IN,
+           true, true) {}
+
+void FileDescriptorArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                            Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeRawFileDescriptorArray", 1, v));
+}
+
+void FileDescriptorArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                               Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "createRawFileDescriptorArray")));
+}
+
+void FileDescriptorArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                                             Variable* parcel, Variable**) const {
+  addTo->Add(new MethodCall(parcel, "readRawFileDescriptorArray", 1, v));
+}
+
+// ================================================================
+
+BooleanType::BooleanType(const JavaTypeNamespace* types)
+    : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true, false) {
+    m_array_type.reset(new BooleanArrayType(types));
+}
+
+void BooleanType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(
+      parcel, "writeInt", 1,
+      new Ternary(v, new LiteralExpression("1"), new LiteralExpression("0"))));
+}
+
+void BooleanType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                   Variable* parcel, Variable**) const {
+  addTo->Add(
+      new Assignment(v, new Comparison(new LiteralExpression("0"), "!=",
+                                       new MethodCall(parcel, "readInt"))));
+}
+
+BooleanArrayType::BooleanArrayType(const JavaTypeNamespace* types)
+    : Type(types, "boolean", ValidatableType::KIND_BUILT_IN, true, true) {}
+
+void BooleanArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                     Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeBooleanArray", 1, v));
+}
+
+void BooleanArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                        Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "createBooleanArray")));
+}
+
+void BooleanArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                                      Variable* parcel, Variable**) const {
+  addTo->Add(new MethodCall(parcel, "readBooleanArray", 1, v));
+}
+
+// ================================================================
+
+CharType::CharType(const JavaTypeNamespace* types)
+    : Type(types, "char", ValidatableType::KIND_BUILT_IN, true, false) {
+    m_array_type.reset(new CharArrayType(types));
+}
+
+void CharType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                             Variable* parcel, int flags) const {
+  addTo->Add(
+      new MethodCall(parcel, "writeInt", 1, new Cast(m_types->IntType(), v)));
+}
+
+void CharType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "readInt"), this));
+}
+
+CharArrayType::CharArrayType(const JavaTypeNamespace* types)
+    : Type(types, "char", ValidatableType::KIND_BUILT_IN, true, true) {}
+
+void CharArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                  Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeCharArray", 1, v));
+}
+
+void CharArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                     Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "createCharArray")));
+}
+
+void CharArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                                   Variable* parcel, Variable**) const {
+  addTo->Add(new MethodCall(parcel, "readCharArray", 1, v));
+}
+
+// ================================================================
+
+StringType::StringType(const JavaTypeNamespace* types,
+                       const std::string& package,
+                       const std::string& class_name)
+    : Type(types, package, class_name,
+           ValidatableType::KIND_BUILT_IN, true, false) {
+  m_array_type.reset(new StringArrayType(types));
+}
+
+string StringType::CreatorName() const {
+  return "android.os.Parcel.STRING_CREATOR";
+}
+
+void StringType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                               Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeString", 1, v));
+}
+
+void StringType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                  Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "readString")));
+}
+
+StringArrayType::StringArrayType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "String", ValidatableType::KIND_BUILT_IN,
+           true, true) {}
+
+string StringArrayType::CreatorName() const {
+  return "android.os.Parcel.STRING_CREATOR";
+}
+
+void StringArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                    Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeStringArray", 1, v));
+}
+
+void StringArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                       Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "createStringArray")));
+}
+
+void StringArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                                     Variable* parcel, Variable**) const {
+  addTo->Add(new MethodCall(parcel, "readStringArray", 1, v));
+}
+
+// ================================================================
+
+CharSequenceType::CharSequenceType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "CharSequence", ValidatableType::KIND_BUILT_IN,
+           true, false) {}
+
+string CharSequenceType::CreatorName() const {
+  return "android.os.Parcel.STRING_CREATOR";
+}
+
+void CharSequenceType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                     Variable* parcel, int flags) const {
+  // if (v != null) {
+  //     parcel.writeInt(1);
+  //     v.writeToParcel(parcel);
+  // } else {
+  //     parcel.writeInt(0);
+  // }
+  IfStatement* elsepart = new IfStatement();
+  elsepart->statements->Add(
+      new MethodCall(parcel, "writeInt", 1, new LiteralExpression("0")));
+  IfStatement* ifpart = new IfStatement;
+  ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
+  ifpart->elseif = elsepart;
+  ifpart->statements->Add(
+      new MethodCall(parcel, "writeInt", 1, new LiteralExpression("1")));
+  ifpart->statements->Add(new MethodCall(m_types->TextUtilsType(),
+                                         "writeToParcel", 3, v, parcel,
+                                         BuildWriteToParcelFlags(flags)));
+
+  addTo->Add(ifpart);
+}
+
+void CharSequenceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                        Variable* parcel, Variable**) const {
+  // if (0 != parcel.readInt()) {
+  //     v = TextUtils.createFromParcel(parcel)
+  // } else {
+  //     v = null;
+  // }
+  IfStatement* elsepart = new IfStatement();
+  elsepart->statements->Add(new Assignment(v, NULL_VALUE));
+
+  IfStatement* ifpart = new IfStatement();
+  ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
+                                      new MethodCall(parcel, "readInt"));
+  ifpart->elseif = elsepart;
+  ifpart->statements->Add(new Assignment(
+      v, new MethodCall(m_types->TextUtilsType(),
+                        "CHAR_SEQUENCE_CREATOR.createFromParcel", 1, parcel)));
+
+  addTo->Add(ifpart);
+}
+
+// ================================================================
+
+RemoteExceptionType::RemoteExceptionType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "RemoteException",
+           ValidatableType::KIND_BUILT_IN, false, false) {}
+
+void RemoteExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                        Variable* parcel, int flags) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+void RemoteExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                           Variable* parcel, Variable**) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+// ================================================================
+
+RuntimeExceptionType::RuntimeExceptionType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "RuntimeException",
+           ValidatableType::KIND_BUILT_IN, false, false) {}
+
+void RuntimeExceptionType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                         Variable* parcel, int flags) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+void RuntimeExceptionType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                            Variable* parcel,
+                                            Variable**) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+// ================================================================
+
+IBinderType::IBinderType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN,
+           true, false) {
+  m_array_type.reset(new IBinderArrayType(types));
+}
+
+void IBinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeStrongBinder", 1, v));
+}
+
+void IBinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                   Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "readStrongBinder")));
+}
+
+IBinderArrayType::IBinderArrayType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "IBinder", ValidatableType::KIND_BUILT_IN,
+           true, true) {}
+
+void IBinderArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                     Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeBinderArray", 1, v));
+}
+
+void IBinderArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                        Variable* parcel, Variable**) const {
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "createBinderArray")));
+}
+
+void IBinderArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                                      Variable* parcel, Variable**) const {
+  addTo->Add(new MethodCall(parcel, "readBinderArray", 1, v));
+}
+
+// ================================================================
+
+IInterfaceType::IInterfaceType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "IInterface", ValidatableType::KIND_BUILT_IN,
+           false, false) {}
+
+void IInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                   Variable* parcel, int flags) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+void IInterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                      Variable* parcel, Variable**) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+// ================================================================
+
+BinderType::BinderType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "Binder", ValidatableType::KIND_BUILT_IN,
+           false, false) {}
+
+void BinderType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                               Variable* parcel, int flags) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+void BinderType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                  Variable* parcel, Variable**) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+// ================================================================
+
+BinderProxyType::BinderProxyType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "BinderProxy", ValidatableType::KIND_BUILT_IN,
+           false, false) {}
+
+void BinderProxyType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                    Variable* parcel, int flags) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+void BinderProxyType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                       Variable* parcel, Variable**) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+// ================================================================
+
+ParcelType::ParcelType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "Parcel", ValidatableType::KIND_BUILT_IN,
+           false, false) {}
+
+void ParcelType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                               Variable* parcel, int flags) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+void ParcelType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                  Variable* parcel, Variable**) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+// ================================================================
+
+ParcelableInterfaceType::ParcelableInterfaceType(const JavaTypeNamespace* types)
+    : Type(types, "android.os", "Parcelable", ValidatableType::KIND_BUILT_IN,
+           false, false) {}
+
+void ParcelableInterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                            Variable* parcel, int flags) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+void ParcelableInterfaceType::CreateFromParcel(StatementBlock* addTo,
+                                               Variable* v, Variable* parcel,
+                                               Variable**) const {
+  fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, __LINE__);
+}
+
+// ================================================================
+
+MapType::MapType(const JavaTypeNamespace* types)
+    : Type(types, "java.util", "Map", ValidatableType::KIND_BUILT_IN,
+           true, true) {}
+
+void MapType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                            Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeMap", 1, v));
+}
+
+static void EnsureClassLoader(StatementBlock* addTo, Variable** cl,
+                              const JavaTypeNamespace* types) {
+  // We don't want to look up the class loader once for every
+  // collection argument, so ensure we do it at most once per method.
+  if (*cl == NULL) {
+    *cl = new Variable(types->ClassLoaderType(), "cl");
+    addTo->Add(new VariableDeclaration(
+        *cl, new LiteralExpression("this.getClass().getClassLoader()"),
+        types->ClassLoaderType()));
+  }
+}
+
+void MapType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                               Variable* parcel, Variable** cl) const {
+  EnsureClassLoader(addTo, cl, m_types);
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "readHashMap", 1, *cl)));
+}
+
+void MapType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                             Variable* parcel, Variable** cl) const {
+  EnsureClassLoader(addTo, cl, m_types);
+  addTo->Add(new MethodCall(parcel, "readMap", 2, v, *cl));
+}
+
+// ================================================================
+
+ListType::ListType(const JavaTypeNamespace* types)
+    : Type(types, "java.util", "List", ValidatableType::KIND_BUILT_IN,
+           true, true) {}
+
+string ListType::InstantiableName() const { return "java.util.ArrayList"; }
+
+void ListType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                             Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeList", 1, v));
+}
+
+void ListType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                Variable* parcel, Variable** cl) const {
+  EnsureClassLoader(addTo, cl, m_types);
+  addTo->Add(
+      new Assignment(v, new MethodCall(parcel, "readArrayList", 1, *cl)));
+}
+
+void ListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                              Variable* parcel, Variable** cl) const {
+  EnsureClassLoader(addTo, cl, m_types);
+  addTo->Add(new MethodCall(parcel, "readList", 2, v, *cl));
+}
+
+// ================================================================
+
+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, true, declFile, declLine) {
+  m_array_type.reset(new UserDataArrayType(types, package, name, builtIn,
+                                           canWriteToParcel, declFile,
+                                           declLine));
+}
+
+string UserDataType::CreatorName() const {
+  return JavaType() + ".CREATOR";
+}
+
+void UserDataType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                 Variable* parcel, int flags) const {
+  // if (v != null) {
+  //     parcel.writeInt(1);
+  //     v.writeToParcel(parcel);
+  // } else {
+  //     parcel.writeInt(0);
+  // }
+  IfStatement* elsepart = new IfStatement();
+  elsepart->statements->Add(
+      new MethodCall(parcel, "writeInt", 1, new LiteralExpression("0")));
+  IfStatement* ifpart = new IfStatement;
+  ifpart->expression = new Comparison(v, "!=", NULL_VALUE);
+  ifpart->elseif = elsepart;
+  ifpart->statements->Add(
+      new MethodCall(parcel, "writeInt", 1, new LiteralExpression("1")));
+  ifpart->statements->Add(new MethodCall(v, "writeToParcel", 2, parcel,
+                                         BuildWriteToParcelFlags(flags)));
+
+  addTo->Add(ifpart);
+}
+
+void UserDataType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                    Variable* parcel, Variable**) const {
+  // if (0 != parcel.readInt()) {
+  //     v = CLASS.CREATOR.createFromParcel(parcel)
+  // } else {
+  //     v = null;
+  // }
+  IfStatement* elsepart = new IfStatement();
+  elsepart->statements->Add(new Assignment(v, NULL_VALUE));
+
+  IfStatement* ifpart = new IfStatement();
+  ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
+                                      new MethodCall(parcel, "readInt"));
+  ifpart->elseif = elsepart;
+  ifpart->statements->Add(new Assignment(
+      v, new MethodCall(v->type, "CREATOR.createFromParcel", 1, parcel)));
+
+  addTo->Add(ifpart);
+}
+
+void UserDataType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                                  Variable* parcel, Variable**) const {
+  // TODO: really, we don't need to have this extra check, but we
+  // don't have two separate marshalling code paths
+  // if (0 != parcel.readInt()) {
+  //     v.readFromParcel(parcel)
+  // }
+  IfStatement* ifpart = new IfStatement();
+  ifpart->expression = new Comparison(new LiteralExpression("0"), "!=",
+                                      new MethodCall(parcel, "readInt"));
+  ifpart->statements->Add(new MethodCall(v, "readFromParcel", 1, parcel));
+  addTo->Add(ifpart);
+}
+
+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, true, declFile, declLine) {}
+
+string UserDataArrayType::CreatorName() const {
+  return JavaType() + ".CREATOR";
+}
+
+void UserDataArrayType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                      Variable* parcel, int flags) const {
+  addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v,
+                            BuildWriteToParcelFlags(flags)));
+}
+
+void UserDataArrayType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                         Variable* parcel, Variable**) const {
+  string creator = v->type->JavaType() + ".CREATOR";
+  addTo->Add(new Assignment(v, new MethodCall(parcel, "createTypedArray", 1,
+                                              new LiteralExpression(creator))));
+}
+
+void UserDataArrayType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                                       Variable* parcel, Variable**) const {
+  string creator = v->type->JavaType() + ".CREATOR";
+  addTo->Add(new MethodCall(parcel, "readTypedArray", 2, v,
+                            new LiteralExpression(creator)));
+}
+
+// ================================================================
+
+InterfaceType::InterfaceType(const JavaTypeNamespace* types,
+                             const string& package, const string& name,
+                             bool builtIn, bool oneway, const string& declFile,
+                             int declLine, const Type* stub, const Type* proxy)
+    : Type(types, package, name, builtIn ? ValidatableType::KIND_BUILT_IN
+                                         : ValidatableType::KIND_INTERFACE,
+           true, false, declFile, declLine),
+      m_oneway(oneway),
+      stub_(stub),
+      proxy_(proxy) {}
+
+bool InterfaceType::OneWay() const { return m_oneway; }
+
+void InterfaceType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                  Variable* parcel, int flags) const {
+  // parcel.writeStrongBinder(v != null ? v.asBinder() : null);
+  addTo->Add(
+      new MethodCall(parcel, "writeStrongBinder", 1,
+                     new Ternary(new Comparison(v, "!=", NULL_VALUE),
+                                 new MethodCall(v, "asBinder"), NULL_VALUE)));
+}
+
+void InterfaceType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                     Variable* parcel, Variable**) const {
+  // v = Interface.asInterface(parcel.readStrongBinder());
+  addTo->Add(new Assignment(
+      v, new MethodCall(stub_, "asInterface", 1,
+                        new MethodCall(parcel, "readStrongBinder"))));
+}
+
+// ================================================================
+
+GenericListType::GenericListType(const JavaTypeNamespace* types,
+                                 const Type* contained_type)
+    : Type(types, "java.util", "List<" + contained_type->CanonicalName() + ">",
+           ValidatableType::KIND_BUILT_IN, true, true),
+      m_contained_type(contained_type),
+      m_creator(contained_type->CreatorName()) {}
+
+string GenericListType::CreatorName() const {
+  return "android.os.Parcel.arrayListCreator";
+}
+
+string GenericListType::InstantiableName() const {
+  return "java.util.ArrayList<" + m_contained_type->JavaType() + ">";
+}
+
+void GenericListType::WriteToParcel(StatementBlock* addTo, Variable* v,
+                                    Variable* parcel, int flags) const {
+  if (m_creator == m_types->StringType()->CreatorName()) {
+    addTo->Add(new MethodCall(parcel, "writeStringList", 1, v));
+  } else if (m_creator == m_types->IBinderType()->CreatorName()) {
+    addTo->Add(new MethodCall(parcel, "writeBinderList", 1, v));
+  } else {
+    // parcel.writeTypedListXX(arg);
+    addTo->Add(new MethodCall(parcel, "writeTypedList", 1, v));
+  }
+}
+
+void GenericListType::CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                       Variable* parcel, Variable**) const {
+  if (m_creator == m_types->StringType()->CreatorName()) {
+    addTo->Add(
+        new Assignment(v, new MethodCall(parcel, "createStringArrayList", 0)));
+  } else if (m_creator == m_types->IBinderType()->CreatorName()) {
+    addTo->Add(
+        new Assignment(v, new MethodCall(parcel, "createBinderArrayList", 0)));
+  } else {
+    // v = _data.readTypedArrayList(XXX.creator);
+    addTo->Add(
+        new Assignment(v, new MethodCall(parcel, "createTypedArrayList", 1,
+                                         new LiteralExpression(m_creator))));
+  }
+}
+
+void GenericListType::ReadFromParcel(StatementBlock* addTo, Variable* v,
+                                     Variable* parcel, Variable**) const {
+  if (m_creator == m_types->StringType()->CreatorName()) {
+    addTo->Add(new MethodCall(parcel, "readStringList", 1, v));
+  } else if (m_creator == m_types->IBinderType()->CreatorName()) {
+    addTo->Add(new MethodCall(parcel, "readBinderList", 1, v));
+  } else {
+    // v = _data.readTypedList(v, XXX.creator);
+    addTo->Add(new MethodCall(parcel, "readTypedList", 2, v,
+                              new LiteralExpression(m_creator)));
+  }
+}
+
+// ================================================================
+
+ClassLoaderType::ClassLoaderType(const JavaTypeNamespace* types)
+    : Type(types, "java.lang", "ClassLoader", ValidatableType::KIND_BUILT_IN,
+           false, false) {}
+
+// ================================================================
+
+void JavaTypeNamespace::Init() {
+  Add(new BasicType(this, "void", "XXX", "XXX", "XXX", "XXX", "XXX"));
+
+  m_bool_type = new BooleanType(this);
+  Add(m_bool_type);
+
+  Add(new BasicType(this, "byte", "writeByte", "readByte", "writeByteArray",
+                    "createByteArray", "readByteArray"));
+
+  Add(new CharType(this));
+
+  m_int_type = new BasicType(this, "int", "writeInt", "readInt",
+                             "writeIntArray", "createIntArray", "readIntArray");
+  Add(m_int_type);
+
+  Add(new BasicType(this, "long", "writeLong", "readLong", "writeLongArray",
+                    "createLongArray", "readLongArray"));
+
+  Add(new BasicType(this, "float", "writeFloat", "readFloat", "writeFloatArray",
+                    "createFloatArray", "readFloatArray"));
+
+  Add(new BasicType(this, "double", "writeDouble", "readDouble",
+                    "writeDoubleArray", "createDoubleArray",
+                    "readDoubleArray"));
+
+  m_string_type = new class StringType(this, "java.lang", "String");
+  Add(m_string_type);
+  Add(new class StringType(this, ::android::aidl::kAidlReservedTypePackage,
+                           ::android::aidl::kUtf8InCppStringClass));
+
+  Add(new Type(this, "java.lang", "Object", ValidatableType::KIND_BUILT_IN,
+               false, false));
+
+  Add(new FileDescriptorType(this));
+
+  Add(new CharSequenceType(this));
+
+  Add(new MapType(this));
+
+  Add(new ListType(this));
+
+  m_text_utils_type =
+      new Type(this, "android.text", "TextUtils",
+               ValidatableType::KIND_BUILT_IN, false, false);
+  Add(m_text_utils_type);
+
+  m_remote_exception_type = new class RemoteExceptionType(this);
+  Add(m_remote_exception_type);
+
+  m_runtime_exception_type = new class RuntimeExceptionType(this);
+  Add(m_runtime_exception_type);
+
+  m_ibinder_type = new class IBinderType(this);
+  Add(m_ibinder_type);
+
+  m_iinterface_type = new class IInterfaceType(this);
+  Add(m_iinterface_type);
+
+  m_binder_native_type = new class BinderType(this);
+  Add(m_binder_native_type);
+
+  m_binder_proxy_type = new class BinderProxyType(this);
+  Add(m_binder_proxy_type);
+
+  m_parcel_type = new class ParcelType(this);
+  Add(m_parcel_type);
+
+  m_parcelable_interface_type = new class ParcelableInterfaceType(this);
+  Add(m_parcelable_interface_type);
+
+  m_context_type = new class Type(this, "android.content", "Context",
+                                  ValidatableType::KIND_BUILT_IN, false, false);
+  Add(m_context_type);
+
+  m_classloader_type = new class ClassLoaderType(this);
+  Add(m_classloader_type);
+
+  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) {
+  Type* type =
+      new UserDataType(this, p.GetPackage(), p.GetName(), false,
+                       true, filename, p.GetLine());
+  return Add(type);
+}
+
+bool JavaTypeNamespace::AddBinderType(const AidlInterface& b,
+                                      const std::string& filename) {
+  // for interfaces, add the stub, proxy, and interface types.
+  Type* stub = new Type(this, b.GetPackage(),
+                        b.GetName() + ".Stub", ValidatableType::KIND_GENERATED,
+                        false, false, filename, b.GetLine());
+  Type* proxy = new Type(this, b.GetPackage(),
+                         b.GetName() + ".Stub.Proxy",
+                         ValidatableType::KIND_GENERATED,
+                         false, false, filename, b.GetLine());
+  Type* type =
+      new InterfaceType(this, b.GetPackage(), b.GetName(), false,
+                        b.IsOneway(), filename, b.GetLine(), stub, proxy);
+
+  bool success = true;
+  success &= Add(type);
+  success &= Add(stub);
+  success &= Add(proxy);
+  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(new 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/aidl/type_java.h b/aidl/type_java.h
new file mode 100644
index 0000000..6d35f2a
--- /dev/null
+++ b/aidl/type_java.h
@@ -0,0 +1,498 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_TYPE_JAVA_H_
+#define AIDL_TYPE_JAVA_H_
+
+#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 };
+
+  Type(const JavaTypeNamespace* types, const std::string& name, int kind,
+       bool canWriteToParcel, bool canBeOut);
+  Type(const JavaTypeNamespace* types, const std::string& package,
+       const std::string& name, int kind, bool canWriteToParcel, bool canBeOut,
+       const std::string& declFile = "", int declLine = -1);
+  virtual ~Type() = default;
+
+  bool CanBeOutParameter() const override { return m_canBeOut; }
+  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 CreatorName() const;
+  virtual std::string InstantiableName() const;
+
+  virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
+                             Variable* parcel, int flags) const;
+  virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
+                                Variable* parcel, Variable** cl) const;
+  virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
+                              Variable* parcel, Variable** cl) const;
+
+ 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;
+  bool m_canBeOut;
+};
+
+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);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  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);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+
+ private:
+  std::string m_marshallParcel;
+  std::string m_unmarshallParcel;
+};
+
+class FileDescriptorArrayType : public Type {
+ public:
+  explicit FileDescriptorArrayType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v,
+                        Variable* parcel, Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class FileDescriptorType : public Type {
+ public:
+  explicit FileDescriptorType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class BooleanArrayType : public Type {
+ public:
+  explicit BooleanArrayType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v,
+                        Variable* parcel, Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class BooleanType : public Type {
+ public:
+  explicit BooleanType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class CharArrayType : public Type {
+ public:
+  explicit CharArrayType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v,
+                        Variable* parcel, Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class CharType : public Type {
+ public:
+  explicit CharType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class StringArrayType : public Type {
+ public:
+  explicit StringArrayType(const JavaTypeNamespace* types);
+
+  std::string CreatorName() const override;
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v,
+                        Variable* parcel, Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  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"; }
+  std::string CreatorName() const override;
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class CharSequenceType : public Type {
+ public:
+  explicit CharSequenceType(const JavaTypeNamespace* types);
+
+  std::string CreatorName() const override;
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class RemoteExceptionType : public Type {
+ public:
+  explicit RemoteExceptionType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class RuntimeExceptionType : public Type {
+ public:
+  explicit RuntimeExceptionType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class IBinderArrayType : public Type {
+ public:
+  explicit IBinderArrayType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v,
+                        Variable* parcel, Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class IBinderType : public Type {
+ public:
+  explicit IBinderType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class IInterfaceType : public Type {
+ public:
+  explicit IInterfaceType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class BinderType : public Type {
+ public:
+  explicit BinderType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class BinderProxyType : public Type {
+ public:
+  explicit BinderProxyType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class ParcelType : public Type {
+ public:
+  explicit ParcelType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class ParcelableInterfaceType : public Type {
+ public:
+  explicit ParcelableInterfaceType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+};
+
+class MapType : public Type {
+ public:
+  explicit MapType(const JavaTypeNamespace* types);
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+};
+
+class ListType : public Type {
+ public:
+  explicit ListType(const JavaTypeNamespace* types);
+
+  std::string InstantiableName() const override;
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) 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);
+
+  std::string CreatorName() const override;
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v,
+                        Variable* parcel, Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  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);
+
+  std::string CreatorName() const override;
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  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, bool oneway,
+                const std::string& declFile, int declLine, const Type* stub,
+                const Type* proxy);
+
+  bool OneWay() const;
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+  const Type* GetStub() const { return stub_; }
+  const Type* GetProxy() const { return proxy_; }
+
+ private:
+  bool m_oneway;
+  const Type* stub_;
+  const Type* proxy_;
+};
+
+class ClassLoaderType : public Type {
+ public:
+  explicit ClassLoaderType(const JavaTypeNamespace* types);
+};
+
+class GenericListType : public Type {
+ public:
+  GenericListType(const JavaTypeNamespace* types, const Type* arg);
+
+  std::string CreatorName() const override;
+  std::string InstantiableName() const override;
+  std::string JavaType() const override {
+    return "java.util.List<" + m_contained_type->JavaType() + ">";
+  }
+
+  void WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                     int flags) const override;
+  void CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                        Variable** cl) const override;
+  void ReadFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel,
+                      Variable** cl) const override;
+  const ValidatableType* NullableType() const override { return this; }
+
+ private:
+  const Type* m_contained_type;
+  const std::string m_creator;
+};
+
+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
+
+#endif  // AIDL_TYPE_JAVA_H_
diff --git a/aidl/type_java_unittest.cpp b/aidl/type_java_unittest.cpp
new file mode 100644
index 0000000..a9df134
--- /dev/null
+++ b/aidl/type_java_unittest.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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(new AidlQualifiedName("Foo", ""), 0, {"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...
+  AidlType container_type("List<Foo>", 0, "", false /* not array */);
+  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/aidl/type_namespace.cpp b/aidl/type_namespace.cpp
new file mode 100644
index 0000000..d3f4aaf
--- /dev/null
+++ b/aidl/type_namespace.cpp
@@ -0,0 +1,165 @@
+/*
+ * 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 android::base::Split;
+using android::base::Trim;
+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 kUtf8StringClass[] = "Utf8String";
+const char kUtf8InCppStringClass[] = "Utf8InCppString";
+
+// These *must* match the package and class names above.
+const char kUtf8StringCanonicalName[] = "aidl-internal.Utf8String";
+const char kUtf8InCppStringCanonicalName[] = "aidl-internal.Utf8InCppString";
+
+const char kStringCanonicalName[] = "java.lang.String";
+
+const char kUtf8Annotation[] = "@utf8";
+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";
+}
+
+bool TypeNamespace::IsValidPackage(const string& /* package */) const {
+  return true;
+}
+
+const ValidatableType* TypeNamespace::GetReturnType(
+    const AidlType& raw_type, const string& filename,
+    const AidlInterface& interface) const {
+  string error_msg;
+  const ValidatableType* return_type = GetValidatableType(raw_type, &error_msg,
+                                                          interface);
+  if (return_type == nullptr) {
+    LOG(ERROR) << StringPrintf("In file %s line %d return type %s:\n    ",
+                               filename.c_str(), raw_type.GetLine(),
+                               raw_type.ToString().c_str())
+               << error_msg;
+    return nullptr;
+  }
+
+  return return_type;
+}
+
+const ValidatableType* TypeNamespace::GetArgType(
+    const AidlArgument& a, int arg_index, const string& filename,
+    const AidlInterface& interface) const {
+  string error_prefix = StringPrintf(
+      "In file %s line %d parameter %s (argument %d):\n    ",
+      filename.c_str(), a.GetLine(), a.GetName().c_str(), arg_index);
+
+  // check the arg type
+  string error_msg;
+  const ValidatableType* t = GetValidatableType(a.GetType(), &error_msg,
+                                                interface);
+  if (t == nullptr) {
+    LOG(ERROR) << error_prefix << error_msg;
+    return nullptr;
+  }
+
+  if (!a.DirectionWasSpecified() && t->CanBeOutParameter()) {
+    LOG(ERROR) << error_prefix << StringPrintf(
+        "'%s' can be an out type, so you must declare it as in,"
+        " out or inout.",
+        a.GetType().ToString().c_str());
+    return nullptr;
+  }
+
+  if (a.GetDirection() != AidlArgument::IN_DIR &&
+      !t->CanBeOutParameter()) {
+    LOG(ERROR) << error_prefix << StringPrintf(
+        "'%s' can only be an in parameter.",
+        a.ToString().c_str());
+    return nullptr;
+  }
+
+  // check that the name doesn't match a keyword
+  if (is_java_keyword(a.GetName().c_str())) {
+    LOG(ERROR) << 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") {
+    LOG(ERROR) << error_prefix << "Argument name cannot begin with '_aidl'";
+    return nullptr;
+  }
+
+  return t;
+}
+
+}  // namespace aidl
+}  // namespace android
diff --git a/aidl/type_namespace.h b/aidl/type_namespace.h
new file mode 100644
index 0000000..7defd24
--- /dev/null
+++ b/aidl/type_namespace.h
@@ -0,0 +1,496 @@
+/*
+ * 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.
+ */
+
+#ifndef AIDL_TYPE_NAMESPACE_H_
+#define AIDL_TYPE_NAMESPACE_H_
+
+#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 kUtf8StringClass[];  // UTF8 wire format string
+extern const char kUtf8InCppStringClass[];  // UTF16 wire format, UTF8 in C++
+
+// Helpful aliases defined to be <kAidlReservedTypePackage>.<class name>
+extern const char kUtf8StringCanonicalName[];
+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 kUtf8Annotation[];
+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 CanBeOutParameter() const = 0;
+  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;
+
+  // 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 AidlType& aidl_type) = 0;
+
+  // Returns true iff this has a type for |import|.
+  virtual bool HasImportType(const AidlImport& import) const = 0;
+
+  // Returns true iff |package| is a valid package name.
+  virtual bool IsValidPackage(const std::string& package) const;
+
+  // Returns a pointer to a type corresponding to |raw_type| or nullptr
+  // if this is an invalid return type.
+  virtual const ValidatableType* GetReturnType(
+      const AidlType& raw_type,
+      const std::string& filename,
+      const AidlInterface& interface) 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 std::string& filename,
+      const AidlInterface& interface) const;
+
+  // Returns a pointer to a type corresponding to |interface|.
+  virtual const ValidatableType* GetInterfaceType(
+      const AidlInterface& interface) const = 0;
+
+ protected:
+  TypeNamespace() = default;
+  virtual ~TypeNamespace() = default;
+
+  virtual const ValidatableType* GetValidatableType(
+      const AidlType& type, std::string* error_msg,
+      const AidlInterface& interface) 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 AidlType& 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 AidlImport& import) const override {
+    return HasTypeByCanonicalName(import.GetNeededClass());
+  }
+  const ValidatableType* GetInterfaceType(
+      const AidlInterface& interface) const override {
+    return FindTypeByCanonicalName(interface.GetCanonicalName());
+  }
+
+  bool MaybeAddContainerType(const AidlType& 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(const T* type);
+
+ private:
+  // Returns true iff the name can be canonicalized to a container type.
+  virtual bool CanonicalizeContainerType(
+      const AidlType& 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 AidlType& type, std::string* error_msg,
+      const AidlInterface& interface) const override;
+
+  std::vector<std::unique_ptr<const T>> types_;
+
+  DISALLOW_COPY_AND_ASSIGN(LanguageTypeNamespace);
+};  // class LanguageTypeNamespace
+
+template<typename T>
+bool LanguageTypeNamespace<T>::Add(const T* type) {
+  const T* existing = FindTypeByCanonicalName(type->CanonicalName());
+  if (!existing) {
+    types_.emplace_back(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 AidlType& aidl_type) const {
+  using std::string;
+  using std::vector;
+  using android::base::Join;
+  using android::base::Trim;
+
+  string name = Trim(aidl_type.GetName());
+  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 AidlType& aidl_type) {
+  using android::base::Join;
+
+  const std::string& type_name = aidl_type.GetName();
+  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 AidlType& aidl_type,
+    std::vector<std::string>* container_class,
+    std::vector<std::string>* contained_type_names) const {
+  using android::base::Trim;
+  using android::base::Split;
+
+  std::string name = Trim(aidl_type.GetName());
+  const size_t opening_brace = name.find('<');
+  const size_t closing_brace = name.find('>');
+  if (opening_brace == std::string::npos ||
+      closing_brace == std::string::npos) {
+    return false;
+  }
+
+  if (opening_brace != name.rfind('<') ||
+      closing_brace != name.rfind('>') ||
+      closing_brace != name.length() - 1) {
+    // Nested/invalid templates are forbidden.
+    LOG(ERROR) << "Invalid template type '" << name << "'";
+    return false;
+  }
+
+  std::string container = Trim(name.substr(0, opening_brace));
+  std::string remainder = name.substr(opening_brace + 1,
+                                 (closing_brace - opening_brace) - 1);
+  std::vector<std::string> args = Split(remainder, ",");
+  for (auto& type_name: args) {
+    // 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.IsUtf8() && type_name == "java.lang.String") {
+      type_name = kUtf8StringCanonicalName;
+    } else if (aidl_type.IsUtf8InCpp() && type_name == "java.lang.String") {
+      type_name = kUtf8InCppStringCanonicalName;
+    }
+  }
+
+  // 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 AidlType& aidl_type, std::string* error_msg,
+    const AidlInterface& interface) 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.IsUtf8() ||
+        aidl_type.IsUtf8InCpp()) {
+      *error_msg = "void type cannot be annotated";
+      return nullptr;
+    }
+    // We have no more special handling for void.
+    return type;
+  }
+
+  // No type may be annotated with both these annotations.
+  if (aidl_type.IsUtf8() && aidl_type.IsUtf8InCpp()) {
+    *error_msg = StringPrintf("Type cannot be marked as both %s and %s.",
+                              kUtf8Annotation, kUtf8InCppAnnotation);
+    return nullptr;
+  }
+
+  bool utf8 = aidl_type.IsUtf8();
+  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())) {
+    utf8 = false;
+    utf8InCpp = false;
+  } else if (aidl_type.GetName() == "String" ||
+             aidl_type.GetName() == "java.lang.String") {
+    utf8 = utf8 || interface.IsUtf8();
+    utf8InCpp = utf8InCpp || interface.IsUtf8InCpp();
+  } else if (utf8 || utf8InCpp) {
+    const char* annotation_literal =
+        (utf8) ? kUtf8Annotation : kUtf8InCppAnnotation;
+    *error_msg = StringPrintf("type '%s' may not be annotated as %s.",
+                              aidl_type.GetName().c_str(),
+                              annotation_literal);
+    return nullptr;
+  }
+
+  if (utf8) {
+    type = FindTypeByCanonicalName(kUtf8StringCanonicalName);
+  } else if (utf8InCpp) {
+    type = FindTypeByCanonicalName(kUtf8InCppStringCanonicalName);
+  }
+
+  // One of our UTF8 transforms made type null
+  if (type == nullptr) {
+    const char* annotation_literal =
+        (utf8) ? kUtf8Annotation : kUtf8InCppAnnotation;
+    *error_msg = StringPrintf(
+        "%s is unsupported when generating code for this language.",
+        annotation_literal);
+    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 (interface.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
+
+#endif  // AIDL_TYPE_NAMESPACE_H_
