diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7480ade
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,26 @@
+.classpath
+.factorypath
+.project
+.settings
+eclipsebin
+
+bin
+gen
+build
+out
+lib
+
+target
+*.class
+pom.xml.*
+release.properties
+
+.idea
+*.iml
+classes
+
+obj
+
+.DS_Store
+*~
+dependency-reduced-pom.xml
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..b0be6fa
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,28 @@
+sudo: false
+
+language: java
+
+install:
+  - mvn -B -U -f build-pom.xml dependency:go-offline test clean --quiet --fail-never -DskipTests=true
+
+script:
+  - mvn -B -U -f build-pom.xml verify --fail-at-end -Dsource.skip=true -Dmaven.javadoc.skip=true
+
+jdk:
+  - openjdk9
+  - openjdk8
+
+env:
+  global:
+  - secure: "bWNSSMURwYC0oZWIMZRd7dy5+JdoyZ060d427TAqFRJmOkYtlR+dBbBggjeJmM0PEkQDzeBrWwln/Vq3lnRPv8czA7hSg/R33r3GzTyi1GZhjCYN2mPW8qp4qgqlloh78aaOODUNSJsOtQqPDJPmhLLfD6UCY0eq9zHhweIjYdw="
+  - secure: "s5V9d8MKl7ZHqCxuYLljLSD4sp9KLtYkk9hVxEPqCLAi4zA70WkX9h+GZI1gAOpcavomfrWcgSDT2ZReiuNpwx7OtczdS4zB+s6mo4F598iRs4bhSLiPT+Hzvx6BSwf1ZKZTYEhrUPGmKOp2T29AxMV7D0Q+P7n574ubvpUuZmA="
+  - secure: "T24JAd60zthkeLBmenvZn6+qI43uvfuLwVb70Ljhbc19XDYEZV4Zm/kaafsisP5+F6kV4GjFaT+NCq2sJlwvPSMMRvU1JJgmNVh8TmtswkC/PHKonkMkOsj2KmFP0RRSPdvQv2NrSguZUq8mg+2pvnPO0qoPg4VeIODPGtAxNb8="
+
+after_success:
+  - util/generate-latest-docs.sh
+  - util/publish-snapshot-on-commit.sh
+
+branches:
+  only:
+    - master
+    - /^release.*$/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..b5622f6
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,34 @@
+Contributing
+============
+
+If you would like to contribute code to Auto you can do so through GitHub
+by forking the repository and sending a pull request.
+
+When submitting code, please make every effort to follow existing conventions
+and style in order to keep the code as readable as possible.
+
+Where appropriate, please provide unit tests or integration tests. Unit tests
+should be JUnit based tests and can use either standard JUnit assertions or
+Truth assertions and be added to `<project>/src/test/java`.  Changes to
+code generation or other build-time behaviour should go into small maven
+projects using the `maven-invoker-plugin`.  Examples of this are in
+`generator/src/it` and can include bean-shell verification scripts and other
+facilities provided by `maven-invoker-plugin`.
+
+Please make sure your code compiles by running `mvn clean verify` which will
+execute both unit and integration test phases.  Additionally, consider using
+http://travis-ci.org to validate your branches before you even put them into
+pull requests.  All pull requests will be validated by Travis-ci in any case
+and must pass before being merged.
+
+If you are adding or modifying files you may add your own copyright line, but
+please ensure that the form is consistent with the existing files, and please
+note that a Google, Inc. copyright line must appear in every copyright notice.
+All files are released with the Apache 2.0 license and any new files may only
+be accepted under the terms of that license.
+
+Before your code can be accepted into the project you must sign the
+[Individual Contributor License Agreement (CLA)][1].
+
+
+ [1]: https://developers.google.com/open-source/cla/individual
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..366f940
--- /dev/null
+++ b/README.md
@@ -0,0 +1,59 @@
+# Auto
+
+[![Build Status](https://travis-ci.org/google/auto.svg?branch=master)](https://travis-ci.org/google/auto)
+
+A collection of source code generators for [Java][java].
+
+## Auto‽
+
+[Java][java] is full of code that is mechanical, repetitive, typically untested
+and sometimes the source of subtle bugs. _Sounds like a job for robots!_
+
+The Auto subprojects are a collection of code generators that automate those
+types of tasks. They create the code you would have written, but without
+the bugs.
+
+Save time.  Save code.  Save sanity.
+
+## Subprojects
+
+  * [AutoFactory] - JSR-330-compatible factories
+
+    [![Maven Central](https://img.shields.io/maven-central/v/com.google.auto.factory/auto-factory.svg)](https://mvnrepository.com/artifact/com.google.auto.factory/auto-factory)
+
+  * [AutoService] - Provider-configuration files for [`ServiceLoader`]
+
+    [![Maven Central](https://img.shields.io/maven-central/v/com.google.auto.service/auto-service.svg)](https://mvnrepository.com/artifact/com.google.auto.service/auto-service)
+
+  * [AutoValue] - Immutable [value-type] code generation for Java 7+.
+
+    [![Maven Central](https://img.shields.io/maven-central/v/com.google.auto.value/auto-value.svg)](https://mvnrepository.com/artifact/com.google.auto.value/auto-value)
+
+  * [Common] - Helper utilities for writing annotation processors.
+
+    [![Maven Central](https://img.shields.io/maven-central/v/com.google.auto/auto-common.svg)](https://mvnrepository.com/artifact/com.google.auto/auto-common)
+
+## License
+
+    Copyright 2013 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       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.
+
+[AutoFactory]: https://github.com/google/auto/tree/master/factory
+[AutoService]: https://github.com/google/auto/tree/master/service
+[AutoValue]: https://github.com/google/auto/tree/master/value
+[Common]: https://github.com/google/auto/tree/master/common
+
+[java]: https://en.wikipedia.org/wiki/Java_(programming_language)
+[value-type]: http://en.wikipedia.org/wiki/Value_object
+[`ServiceLoader`]: http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html
diff --git a/build-pom.xml b/build-pom.xml
new file mode 100644
index 0000000..45a3113
--- /dev/null
+++ b/build-pom.xml
@@ -0,0 +1,26 @@
+<!-- A pure convenience for local builds and travis-ci. -->
+<project>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>build-only</groupId>
+  <artifactId>build-only</artifactId>
+  <version>NO_VERSION</version>
+  <packaging>pom</packaging>
+  <modules>
+    <module>common</module>
+    <module>factory</module>
+    <module>service</module>
+    <module>value</module>
+  </modules>
+  <distributionManagement>
+    <repository>
+      <id>sonatype-nexus-staging</id>
+      <name>Nexus Release Repository</name>
+      <url>file:///tmp/auto_project_maven_fake_repo/</url>
+    </repository>
+    <snapshotRepository>
+      <id>sonatype-nexus-snapshots</id>
+      <name>Sonatype Nexus Snapshots</name>
+      <url>file:///tmp/auto_project_maven_fake_repo/</url>
+    </snapshotRepository>
+  </distributionManagement>
+</project>
diff --git a/common/README.md b/common/README.md
new file mode 100644
index 0000000..990aa31
--- /dev/null
+++ b/common/README.md
@@ -0,0 +1,79 @@
+Auto Common Utilities
+========
+
+## Overview
+
+The Auto project has a set of common utilities to help ease use of the annotation processing
+environment.
+
+## Utility classes of note
+
+  * MoreTypes - utilities and Equivalence wrappers for TypeMirror and related subtypes
+  * MoreElements - utilities for Element and related subtypes
+  * SuperficialValidation - very simple scanner to ensure an Element is valid and free from
+    distortion from upstream compilation errors
+  * Visibility - utilities for working with Elements' visibility levels (public, protected, etc.)
+  * BasicAnnotationProcessor/ProcessingStep - simple types that
+    - implement a validating annotation processor
+    - defer invalid elements until later
+    - break processor actions into multiple steps (which may each handle different annotations)
+
+## Usage/Setup
+
+Auto common utilities have a standard [Maven](http://maven.apache.org) setup which can also be
+used from Gradle, Ivy, Ant, or other systems which consume binary artifacts from the central Maven
+binary artifact repositories.
+
+```xml
+<dependency>
+  <groupId>com.google.auto</groupId>
+  <artifactId>auto-common</artifactId>
+  <version>1.0-SNAPSHOT</version> <!-- or use a known release version -->
+</dependency>
+```
+
+## Processor Resilience
+
+Auto Common Utilities is used by a variety of annotation processors in Google and new versions
+may have breaking changes.  Users of auto-common are urged to use
+[shade](https://maven.apache.org/plugins/maven-shade-plugin/) or
+[jarjar](https://code.google.com/p/jarjar/) (or something similar) in packaging their processors
+so that conflicting versions of this library do not adversely interact with each other.
+
+For example, in a Maven build you can repackage `com.google.auto.common` into
+`your.processor.shaded.auto.common` like this:
+
+```xml
+<project>
+  <!-- your other config -->
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-shade-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <artifactSet>
+                <excludes>
+                  <!-- exclude dependencies you don't want to bundle in your processor -->
+                </excludes>
+              </artifactSet>
+              <relocations>
+                <relocation>
+                  <pattern>com.google.auto.common</pattern>
+                  <shadedPattern>your.processor.shaded.auto.common</shadedPattern>
+                </relocation>
+              </relocations>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+</project>
+```
+
diff --git a/common/pom.xml b/common/pom.xml
new file mode 100644
index 0000000..7d1c877
--- /dev/null
+++ b/common/pom.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2014 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.sonatype.oss</groupId>
+    <artifactId>oss-parent</artifactId>
+    <version>7</version>
+  </parent>
+
+  <groupId>com.google.auto</groupId>
+  <artifactId>auto-common</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>Auto Common Libraries</name>
+  <description>
+    Common utilities for creating annotation processors.
+  </description>
+  <url>https://github.com/google/auto/tree/master/common</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <java.version>1.8</java.version>
+    <guava.version>27.0.1-jre</guava.version>
+    <truth.version>1.0.1</truth.version>
+  </properties>
+
+  <scm>
+    <url>http://github.com/google/auto</url>
+    <connection>scm:git:git://github.com/google/auto.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+
+  <issueManagement>
+    <system>GitHub Issues</system>
+    <url>http://github.com/google/auto/issues</url>
+  </issueManagement>
+
+  <licenses>
+    <license>
+      <name>Apache 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+    </license>
+  </licenses>
+
+  <organization>
+    <name>Google LLC</name>
+    <url>http://www.google.com</url>
+  </organization>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>${guava.version}</version>
+    </dependency>
+    <dependency>
+      <!-- Used only by GeneratedAnnotationSpecs.
+           If you use JavaPoet, you can use GeneratedAnnotationSpecs. -->
+      <groupId>com.squareup</groupId>
+      <artifactId>javapoet</artifactId>
+      <version>1.9.0</version>
+      <optional>true</optional>
+    </dependency>
+
+    <!-- test dependencies -->
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava-testlib</artifactId>
+      <version>${guava.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.testing.compile</groupId>
+      <artifactId>compile-testing</artifactId>
+      <version>0.18</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <version>${truth.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jdt</groupId>
+      <artifactId>ecj</artifactId>
+      <version>3.20.0</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.7.0</version>
+        <configuration>
+          <source>${java.version}</source>
+          <target>${java.version}</target>
+          <compilerArgument>-Xlint:all</compilerArgument>
+          <showWarnings>true</showWarnings>
+          <showDeprecation>true</showDeprecation>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-java</artifactId>
+            <version>0.9.4</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>3.0.2</version>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/common/src/main/java/com/google/auto/common/AnnotationMirrors.java b/common/src/main/java/com/google/auto/common/AnnotationMirrors.java
new file mode 100644
index 0000000..62e5834
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/AnnotationMirrors.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.base.Equivalence;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+
+/**
+ * A utility class for working with {@link AnnotationMirror} instances.
+ *
+ * @author Gregory Kick
+ */
+public final class AnnotationMirrors {
+  private static final Equivalence<AnnotationMirror> ANNOTATION_MIRROR_EQUIVALENCE =
+      new Equivalence<AnnotationMirror>() {
+        @Override
+        protected boolean doEquivalent(AnnotationMirror left, AnnotationMirror right) {
+          return MoreTypes.equivalence().equivalent(left.getAnnotationType(),
+              right.getAnnotationType()) && AnnotationValues.equivalence().pairwise().equivalent(
+              getAnnotationValuesWithDefaults(left).values(),
+              getAnnotationValuesWithDefaults(right).values());
+        }
+        @Override
+        protected int doHash(AnnotationMirror annotation) {
+          DeclaredType type = annotation.getAnnotationType();
+          Iterable<AnnotationValue> annotationValues =
+              getAnnotationValuesWithDefaults(annotation).values();
+          return Arrays.hashCode(new int[] {MoreTypes.equivalence().hash(type),
+              AnnotationValues.equivalence().pairwise().hash(annotationValues)});
+        }
+    };
+
+  /**
+   * Returns an {@link Equivalence} for {@link AnnotationMirror} as some implementations
+   * delegate equality tests to {@link Object#equals} whereas the documentation explicitly
+   * states that instance/reference equality is not the proper test.
+   */
+  public static Equivalence<AnnotationMirror> equivalence() {
+    return ANNOTATION_MIRROR_EQUIVALENCE;
+  }
+
+  /**
+   * Returns the {@link AnnotationMirror}'s map of {@link AnnotationValue} indexed by {@link
+   * ExecutableElement}, supplying default values from the annotation if the annotation property has
+   * not been set. This is equivalent to {@link
+   * Elements#getElementValuesWithDefaults(AnnotationMirror)} but can be called statically without
+   * an {@link Elements} instance.
+   *
+   * <p>The iteration order of elements of the returned map will be the order in which the {@link
+   * ExecutableElement}s are defined in {@code annotation}'s {@linkplain
+   * AnnotationMirror#getAnnotationType() type}.
+   */
+  public static ImmutableMap<ExecutableElement, AnnotationValue> getAnnotationValuesWithDefaults(
+      AnnotationMirror annotation) {
+    ImmutableMap.Builder<ExecutableElement, AnnotationValue> values = ImmutableMap.builder();
+    Map<? extends ExecutableElement, ? extends AnnotationValue> declaredValues =
+        annotation.getElementValues();
+    for (ExecutableElement method :
+        ElementFilter.methodsIn(annotation.getAnnotationType().asElement().getEnclosedElements())) {
+      // Must iterate and put in this order, to ensure consistency in generated code.
+      if (declaredValues.containsKey(method)) {
+        values.put(method, declaredValues.get(method));
+      } else if (method.getDefaultValue() != null) {
+        values.put(method, method.getDefaultValue());
+      } else {
+        throw new IllegalStateException(
+            "Unset annotation value without default should never happen: "
+            + MoreElements.asType(method.getEnclosingElement()).getQualifiedName()
+            + '.' + method.getSimpleName() + "()");
+      }
+    }
+    return values.build();
+  }
+
+  /**
+   * Returns an {@link AnnotationValue} for the named element if such an element was
+   * either declared in the usage represented by the provided {@link AnnotationMirror}, or if
+   * such an element was defined with a default.
+   *
+   * @throws IllegalArgumentException if no element is defined with the given elementName.
+   */
+  public static AnnotationValue getAnnotationValue(
+      AnnotationMirror annotationMirror, String elementName) {
+    return getAnnotationElementAndValue(annotationMirror, elementName).getValue();
+  }
+
+  /**
+   * Returns a {@link ExecutableElement} and its associated {@link AnnotationValue} if such
+   * an element was either declared in the usage represented by the provided
+   * {@link AnnotationMirror}, or if such an element was defined with a default.
+   *
+   * @throws IllegalArgumentException if no element is defined with the given elementName.
+   */
+  public static Map.Entry<ExecutableElement, AnnotationValue> getAnnotationElementAndValue(
+      AnnotationMirror annotationMirror, final String elementName) {
+    checkNotNull(annotationMirror);
+    checkNotNull(elementName);
+    for (Map.Entry<ExecutableElement, AnnotationValue> entry :
+        getAnnotationValuesWithDefaults(annotationMirror).entrySet()) {
+      if (entry.getKey().getSimpleName().contentEquals(elementName)) {
+        return entry;
+      }
+    }
+    throw new IllegalArgumentException(String.format("@%s does not define an element %s()",
+        MoreElements.asType(annotationMirror.getAnnotationType().asElement()).getQualifiedName(),
+        elementName));
+  }
+
+  /**
+   * Returns all {@linkplain AnnotationMirror annotations} that are present on the given
+   * {@link Element} which are themselves annotated with {@code annotationType}.
+   */
+  public static ImmutableSet<? extends AnnotationMirror> getAnnotatedAnnotations(Element element,
+      final Class<? extends Annotation> annotationType) {
+    List<? extends AnnotationMirror> annotations = element.getAnnotationMirrors();
+    return FluentIterable.from(annotations)
+        .filter(new Predicate<AnnotationMirror>() {
+          @Override public boolean apply(AnnotationMirror input) {
+            return isAnnotationPresent(input.getAnnotationType().asElement(), annotationType);
+          }
+        })
+        .toSet();
+  }
+
+  private AnnotationMirrors() {}
+}
diff --git a/common/src/main/java/com/google/auto/common/AnnotationValues.java b/common/src/main/java/com/google/auto/common/AnnotationValues.java
new file mode 100644
index 0000000..e233901
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/AnnotationValues.java
@@ -0,0 +1,489 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+
+import com.google.common.base.Equivalence;
+import com.google.common.collect.ImmutableList;
+import java.util.List;
+import java.util.function.Function;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+
+/**
+ * A utility class for working with {@link AnnotationValue} instances.
+ *
+ * @author Christian Gruber
+ */
+public final class AnnotationValues {
+  private static final Equivalence<AnnotationValue> ANNOTATION_VALUE_EQUIVALENCE =
+      new Equivalence<AnnotationValue>() {
+        @Override protected boolean doEquivalent(AnnotationValue left, AnnotationValue right) {
+          return left.accept(new SimpleAnnotationValueVisitor8<Boolean, AnnotationValue>() {
+            // LHS is not an annotation or array of annotation values, so just test equality.
+            @Override protected Boolean defaultAction(Object left, AnnotationValue right) {
+              return left.equals(right.accept(
+                  new SimpleAnnotationValueVisitor8<Object, Void>() {
+                    @Override protected Object defaultAction(Object object, Void unused) {
+                      return object;
+                    }
+                  }, null));
+            }
+
+            // LHS is an annotation mirror so test equivalence for RHS annotation mirrors
+            // and false for other types.
+            @Override public Boolean visitAnnotation(AnnotationMirror left, AnnotationValue right) {
+              return right.accept(
+                  new SimpleAnnotationValueVisitor8<Boolean, AnnotationMirror>() {
+                    @Override protected Boolean defaultAction(Object right, AnnotationMirror left) {
+                      return false; // Not an annotation mirror, so can't be equal to such.
+                    }
+                    @Override
+                    public Boolean visitAnnotation(AnnotationMirror right, AnnotationMirror left) {
+                      return AnnotationMirrors.equivalence().equivalent(left, right);
+                    }
+                  }, left);
+            }
+
+            // LHS is a list of annotation values have to collect-test equivalences, or false
+            // for any other types.
+            @Override
+            public Boolean visitArray(List<? extends AnnotationValue> left, AnnotationValue right) {
+              return right.accept(
+                  new SimpleAnnotationValueVisitor8<Boolean, List<? extends AnnotationValue>>() {
+                    @Override protected Boolean defaultAction(
+                        Object ignored, List<? extends AnnotationValue> alsoIgnored) {
+                      return false; // Not an array, so can't be equal to such.
+                    }
+
+                    @SuppressWarnings("unchecked") // safe covariant cast
+                    @Override public Boolean visitArray(
+                        List<? extends AnnotationValue> right ,
+                        List<? extends AnnotationValue> left) {
+                      return AnnotationValues.equivalence().pairwise().equivalent(
+                          (List<AnnotationValue>) left, (List<AnnotationValue>) right);
+                    }
+                  }, left);
+            }
+
+            @Override
+            public Boolean visitType(TypeMirror left, AnnotationValue right) {
+              return right.accept(
+                  new SimpleAnnotationValueVisitor8<Boolean, TypeMirror>() {
+                    @Override protected Boolean defaultAction(
+                        Object ignored, TypeMirror alsoIgnored) {
+                      return false; // Not an annotation mirror, so can't be equal to such.
+                    }
+
+                    @Override public Boolean visitType(TypeMirror right, TypeMirror left) {
+                      return MoreTypes.equivalence().equivalent(left, right);
+                    }
+                  }, left);
+            }
+          }, right);
+        }
+
+        @Override protected int doHash(AnnotationValue value) {
+          return value.accept(new SimpleAnnotationValueVisitor8<Integer, Void>() {
+            @Override public Integer visitAnnotation(AnnotationMirror value, Void ignore) {
+              return AnnotationMirrors.equivalence().hash(value);
+            }
+
+            @SuppressWarnings("unchecked") // safe covariant cast
+            @Override public Integer visitArray(
+                List<? extends AnnotationValue> values, Void ignore) {
+              return AnnotationValues.equivalence().pairwise().hash((List<AnnotationValue>) values);
+            }
+
+            @Override public Integer visitType(TypeMirror value, Void ignore) {
+              return MoreTypes.equivalence().hash(value);
+            }
+
+            @Override protected Integer defaultAction(Object value, Void ignored) {
+              return value.hashCode();
+            }
+          }, null);
+        }
+      };
+
+  /**
+   * Returns an {@link Equivalence} for {@link AnnotationValue} as annotation values may
+   * contain {@link AnnotationMirror} instances some of whose implementations delegate
+   * equality tests to {@link Object#equals} whereas the documentation explicitly states
+   * that instance/reference equality is not the proper test.
+   *
+   * @see AnnotationMirrors#equivalence()
+   */
+  public static Equivalence<AnnotationValue> equivalence() {
+    return ANNOTATION_VALUE_EQUIVALENCE;
+  }
+
+  private static class DefaultVisitor<T> extends SimpleAnnotationValueVisitor8<T, Void> {
+    final Class<T> clazz;
+
+    DefaultVisitor(Class<T> clazz) {
+      this.clazz = checkNotNull(clazz);
+    }
+
+    @Override
+    public T defaultAction(Object o, Void unused) {
+      throw new IllegalArgumentException(
+          "Expected a " + clazz.getSimpleName() + ", got instead: " + o);
+    }
+  }
+
+  private static final class TypeMirrorVisitor extends DefaultVisitor<DeclaredType> {
+    static final TypeMirrorVisitor INSTANCE = new TypeMirrorVisitor();
+
+    TypeMirrorVisitor() {
+      super(DeclaredType.class);
+    }
+
+    @Override
+    public DeclaredType visitType(TypeMirror value, Void unused) {
+      return MoreTypes.asDeclared(value);
+    }
+  }
+  ;
+
+  /**
+   * Returns the value as a class.
+   *
+   * @throws IllegalArgumentException if the value is not a class.
+   */
+  public static DeclaredType getTypeMirror(AnnotationValue value) {
+    return TypeMirrorVisitor.INSTANCE.visit(value);
+  }
+
+  private static final class AnnotationMirrorVisitor extends DefaultVisitor<AnnotationMirror> {
+    static final AnnotationMirrorVisitor INSTANCE = new AnnotationMirrorVisitor();
+
+    AnnotationMirrorVisitor() {
+      super(AnnotationMirror.class);
+    }
+
+    @Override
+    public AnnotationMirror visitAnnotation(AnnotationMirror value, Void unused) {
+      return value;
+    }
+  }
+  ;
+
+  /**
+   * Returns the value as an AnnotationMirror.
+   *
+   * @throws IllegalArgumentException if the value is not an annotation.
+   */
+  public static AnnotationMirror getAnnotationMirror(AnnotationValue value) {
+    return AnnotationMirrorVisitor.INSTANCE.visit(value);
+  }
+
+  private static final class EnumVisitor extends DefaultVisitor<VariableElement> {
+    static final EnumVisitor INSTANCE = new EnumVisitor();
+
+    EnumVisitor() {
+      super(VariableElement.class);
+    }
+
+    @Override
+    public VariableElement visitEnumConstant(VariableElement value, Void unused) {
+      return value;
+    }
+  }
+  ;
+
+  /**
+   * Returns the value as a VariableElement.
+   *
+   * @throws IllegalArgumentException if the value is not an enum.
+   */
+  public static VariableElement getEnum(AnnotationValue value) {
+    return EnumVisitor.INSTANCE.visit(value);
+  }
+
+  private static <T> T valueOfType(AnnotationValue annotationValue, Class<T> type) {
+    Object value = annotationValue.getValue();
+    if (!type.isInstance(value)) {
+      throw new IllegalArgumentException(
+          "Expected " + type.getSimpleName() + ", got instead: " + value);
+    }
+    return type.cast(value);
+  }
+
+  /**
+   * Returns the value as a string.
+   *
+   * @throws IllegalArgumentException if the value is not a string.
+   */
+  public static String getString(AnnotationValue value) {
+    return valueOfType(value, String.class);
+  }
+
+  /**
+   * Returns the value as an int.
+   *
+   * @throws IllegalArgumentException if the value is not an int.
+   */
+  public static int getInt(AnnotationValue value) {
+    return valueOfType(value, Integer.class);
+  }
+
+  /**
+   * Returns the value as a long.
+   *
+   * @throws IllegalArgumentException if the value is not a long.
+   */
+  public static long getLong(AnnotationValue value) {
+    return valueOfType(value, Long.class);
+  }
+
+  /**
+   * Returns the value as a byte.
+   *
+   * @throws IllegalArgumentException if the value is not a byte.
+   */
+  public static byte getByte(AnnotationValue value) {
+    return valueOfType(value, Byte.class);
+  }
+
+  /**
+   * Returns the value as a short.
+   *
+   * @throws IllegalArgumentException if the value is not a short.
+   */
+  public static short getShort(AnnotationValue value) {
+    return valueOfType(value, Short.class);
+  }
+
+  /**
+   * Returns the value as a float.
+   *
+   * @throws IllegalArgumentException if the value is not a float.
+   */
+  public static float getFloat(AnnotationValue value) {
+    return valueOfType(value, Float.class);
+  }
+
+  /**
+   * Returns the value as a double.
+   *
+   * @throws IllegalArgumentException if the value is not a double.
+   */
+  public static double getDouble(AnnotationValue value) {
+    return valueOfType(value, Double.class);
+  }
+
+  /**
+   * Returns the value as a boolean.
+   *
+   * @throws IllegalArgumentException if the value is not a boolean.
+   */
+  public static boolean getBoolean(AnnotationValue value) {
+    return valueOfType(value, Boolean.class);
+  }
+
+  /**
+   * Returns the value as a char.
+   *
+   * @throws IllegalArgumentException if the value is not a char.
+   */
+  public static char getChar(AnnotationValue value) {
+    return valueOfType(value, Character.class);
+  }
+
+  private static final class ArrayVisitor<T>
+      extends SimpleAnnotationValueVisitor8<ImmutableList<T>, Void> {
+    final Function<AnnotationValue, T> visitT;
+
+    ArrayVisitor(Function<AnnotationValue, T> visitT) {
+      this.visitT = checkNotNull(visitT);
+    }
+
+    @Override
+    public ImmutableList<T> defaultAction(Object o, Void unused) {
+      throw new IllegalStateException("Expected an array, got instead: " + o);
+    }
+
+    @Override
+    public ImmutableList<T> visitArray(List<? extends AnnotationValue> values, Void unused) {
+      return values.stream().map(visitT).collect(toImmutableList());
+    }
+  }
+
+  private static final ArrayVisitor<DeclaredType> TYPE_MIRRORS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getTypeMirror);
+
+  /**
+   * Returns the value as a list of classes.
+   *
+   * @throws IllegalArgumentException if the value is not an array of classes.
+   */
+  public static ImmutableList<DeclaredType> getTypeMirrors(AnnotationValue value) {
+    return TYPE_MIRRORS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<AnnotationMirror> ANNOTATION_MIRRORS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getAnnotationMirror);
+
+  /**
+   * Returns the value as a list of annotations.
+   *
+   * @throws IllegalArgumentException if the value if not an array of annotations.
+   */
+  public static ImmutableList<AnnotationMirror> getAnnotationMirrors(AnnotationValue value) {
+    return ANNOTATION_MIRRORS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<VariableElement> ENUMS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getEnum);
+
+  /**
+   * Returns the value as a list of enums.
+   *
+   * @throws IllegalArgumentException if the value is not an array of enums.
+   */
+  public static ImmutableList<VariableElement> getEnums(AnnotationValue value) {
+    return ENUMS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<String> STRINGS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getString);
+
+  /**
+   * Returns the value as a list of strings.
+   *
+   * @throws IllegalArgumentException if the value is not an array of strings.
+   */
+  public static ImmutableList<String> getStrings(AnnotationValue value) {
+    return STRINGS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<Integer> INTS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getInt);
+
+  /**
+   * Returns the value as a list of integers.
+   *
+   * @throws IllegalArgumentException if the value is not an array of ints.
+   */
+  public static ImmutableList<Integer> getInts(AnnotationValue value) {
+    return INTS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<Long> LONGS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getLong);
+
+  /**
+   * Returns the value as a list of longs.
+   *
+   * @throws IllegalArgumentException if the value is not an array of longs.
+   */
+  public static ImmutableList<Long> getLongs(AnnotationValue value) {
+    return LONGS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<Byte> BYTES_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getByte);
+
+  /**
+   * Returns the value as a list of bytes.
+   *
+   * @throws IllegalArgumentException if the value is not an array of bytes.
+   */
+  public static ImmutableList<Byte> getBytes(AnnotationValue value) {
+    return BYTES_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<Short> SHORTS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getShort);
+  /**
+   * Returns the value as a list of shorts.
+   *
+   * @throws IllegalArgumentException if the value is not an array of shorts.
+   */
+  public static ImmutableList<Short> getShorts(AnnotationValue value) {
+    return SHORTS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<Float> FLOATS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getFloat);
+
+  /**
+   * Returns the value as a list of floats.
+   *
+   * @throws IllegalArgumentException if the value is not an array of floats.
+   */
+  public static ImmutableList<Float> getFloats(AnnotationValue value) {
+    return FLOATS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<Double> DOUBLES_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getDouble);
+
+  /**
+   * Returns the value as a list of doubles.
+   *
+   * @throws IllegalArgumentException if the value is not an array of doubles.
+   */
+  public static ImmutableList<Double> getDoubles(AnnotationValue value) {
+    return DOUBLES_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<Boolean> BOOLEANS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getBoolean);
+
+  /**
+   * Returns the value as a list of booleans.
+   *
+   * @throws IllegalArgumentException if the value is not an array of booleans.
+   */
+  public static ImmutableList<Boolean> getBooleans(AnnotationValue value) {
+    return BOOLEANS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<Character> CHARS_VISITOR =
+      new ArrayVisitor<>(AnnotationValues::getChar);
+
+  /**
+   * Returns the value as a list of characters.
+   *
+   * @throws IllegalArgumentException if the value is not an array of chars.
+   */
+  public static ImmutableList<Character> getChars(AnnotationValue value) {
+    return CHARS_VISITOR.visit(value);
+  }
+
+  private static final ArrayVisitor<AnnotationValue> ANNOTATION_VALUES_VISITOR =
+      new ArrayVisitor<>(x -> x);
+
+  /**
+   * Returns the value as a list of {@link AnnotationValue}s.
+   *
+   * @throws IllegalArgumentException if the value is not an array.
+   */
+  public static ImmutableList<AnnotationValue> getAnnotationValues(AnnotationValue value) {
+    return ANNOTATION_VALUES_VISITOR.visit(value);
+  }
+
+  private AnnotationValues() {}
+}
+
diff --git a/common/src/main/java/com/google/auto/common/BasicAnnotationProcessor.java b/common/src/main/java/com/google/auto/common/BasicAnnotationProcessor.java
new file mode 100644
index 0000000..d3f67aa
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/BasicAnnotationProcessor.java
@@ -0,0 +1,462 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.auto.common.MoreElements.asExecutable;
+import static com.google.auto.common.MoreElements.asPackage;
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.auto.common.SuperficialValidation.validateElement;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.transform;
+import static com.google.common.collect.Multimaps.filterKeys;
+import static javax.lang.model.element.ElementKind.PACKAGE;
+import static javax.tools.Diagnostic.Kind.ERROR;
+
+import com.google.common.base.Ascii;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicates;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+import java.lang.annotation.Annotation;
+import java.util.LinkedHashSet;
+import java.util.Objects;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ErrorType;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleElementVisitor8;
+
+/**
+ * An abstract {@link Processor} implementation that defers processing of {@link Element}s to later
+ * rounds if they cannot be processed.
+ *
+ * <p>Subclasses put their processing logic in {@link ProcessingStep} implementations. The steps are
+ * passed to the processor by returning them in the {@link #initSteps()} method, and can access the
+ * {@link ProcessingEnvironment} using {@link #processingEnv}.
+ *
+ * <p>Any logic that needs to happen once per round can be specified by overriding {@link
+ * #postRound(RoundEnvironment)}.
+ *
+ * <h3>Ill-formed elements are deferred</h3>
+ *
+ * Any annotated element whose nearest enclosing type is not well-formed is deferred, and not passed
+ * to any {@code ProcessingStep}. This helps processors to avoid many common pitfalls, such as
+ * {@link ErrorType} instances, {@link ClassCastException}s and badly coerced types.
+ *
+ * <p>A non-package element is considered well-formed if its type, type parameters, parameters,
+ * default values, supertypes, annotations, and enclosed elements are. Package elements are treated
+ * similarly, except that their enclosed elements are not validated. See {@link
+ * SuperficialValidation#validateElement(Element)} for details.
+ *
+ * <p>The primary disadvantage to this validation is that any element that forms a circular
+ * dependency with a type generated by another {@code BasicAnnotationProcessor} will never compile
+ * because the element will never be fully complete. All such compilations will fail with an error
+ * message on the offending type that describes the issue.
+ *
+ * <h3>Each {@code ProcessingStep} can defer elements</h3>
+ *
+ * <p>Each {@code ProcessingStep} can defer elements by including them in the set returned by {@link
+ * ProcessingStep#process(SetMultimap)}; elements deferred by a step will be passed back to that
+ * step in a later round of processing.
+ *
+ * <p>This feature is useful when one processor may depend on code generated by another, independent
+ * processor, in a way that isn't caught by the well-formedness check described above. For example,
+ * if an element {@code A} cannot be processed because processing it depends on the existence of
+ * some class {@code B}, then {@code A} should be deferred until a later round of processing, when
+ * {@code B} will have been generated by another processor.
+ *
+ * <p>If {@code A} directly references {@code B}, then the well-formedness check will correctly
+ * defer processing of {@code A} until {@code B} has been generated.
+ *
+ * <p>However, if {@code A} references {@code B} only indirectly (for example, from within a method
+ * body), then the well-formedness check will not defer processing {@code A}, but a processing step
+ * can reject {@code A}.
+ */
+public abstract class BasicAnnotationProcessor extends AbstractProcessor {
+
+  private final Set<ElementName> deferredElementNames = new LinkedHashSet<>();
+  private final SetMultimap<ProcessingStep, ElementName> elementsDeferredBySteps =
+      LinkedHashMultimap.create();
+
+  private Elements elements;
+  private Messager messager;
+  private ImmutableList<? extends ProcessingStep> steps;
+
+  @Override
+  public final synchronized void init(ProcessingEnvironment processingEnv) {
+    super.init(processingEnv);
+    this.elements = processingEnv.getElementUtils();
+    this.messager = processingEnv.getMessager();
+    this.steps = ImmutableList.copyOf(initSteps());
+  }
+
+  /**
+   * Creates {@linkplain ProcessingStep processing steps} for this processor. {@link #processingEnv}
+   * is guaranteed to be set when this method is invoked.
+   */
+  protected abstract Iterable<? extends ProcessingStep> initSteps();
+
+  /**
+   * An optional hook for logic to be executed at the end of each round.
+   *
+   * @deprecated use {@link #postRound(RoundEnvironment)} instead
+   */
+  @Deprecated
+  protected void postProcess() {}
+
+  /** An optional hook for logic to be executed at the end of each round. */
+  protected void postRound(RoundEnvironment roundEnv) {
+    if (!roundEnv.processingOver()) {
+      postProcess();
+    }
+  }
+
+  private ImmutableSet<? extends Class<? extends Annotation>> getSupportedAnnotationClasses() {
+    checkState(steps != null);
+    ImmutableSet.Builder<Class<? extends Annotation>> builder = ImmutableSet.builder();
+    for (ProcessingStep step : steps) {
+      builder.addAll(step.annotations());
+    }
+    return builder.build();
+  }
+
+  /**
+   * Returns the set of supported annotation types as a collected from registered {@linkplain
+   * ProcessingStep processing steps}.
+   */
+  @Override
+  public final ImmutableSet<String> getSupportedAnnotationTypes() {
+    ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+    for (Class<? extends Annotation> annotationClass : getSupportedAnnotationClasses()) {
+      builder.add(annotationClass.getCanonicalName());
+    }
+    return builder.build();
+  }
+
+  @Override
+  public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    checkState(elements != null);
+    checkState(messager != null);
+    checkState(steps != null);
+
+    // If this is the last round, report all of the missing elements if there
+    // were no errors raised in the round; otherwise reporting the missing
+    // elements just adds noise the output.
+    if (roundEnv.processingOver()) {
+      postRound(roundEnv);
+      if (!roundEnv.errorRaised()) {
+        reportMissingElements(
+            ImmutableSet.<ElementName>builder()
+                .addAll(deferredElementNames)
+                .addAll(elementsDeferredBySteps.values())
+                .build());
+      }
+      return false;
+    }
+
+    process(validElements(roundEnv));
+
+    postRound(roundEnv);
+
+    return false;
+  }
+
+  /** Processes the valid elements, including those previously deferred by each step. */
+  private void process(ImmutableSetMultimap<Class<? extends Annotation>, Element> validElements) {
+    for (ProcessingStep step : steps) {
+      ImmutableSetMultimap<Class<? extends Annotation>, Element> stepElements =
+          new ImmutableSetMultimap.Builder<Class<? extends Annotation>, Element>()
+              .putAll(indexByAnnotation(elementsDeferredBySteps.get(step), step.annotations()))
+              .putAll(filterKeys(validElements, Predicates.<Object>in(step.annotations())))
+              .build();
+      if (stepElements.isEmpty()) {
+        elementsDeferredBySteps.removeAll(step);
+      } else {
+        Set<? extends Element> rejectedElements = step.process(stepElements);
+        elementsDeferredBySteps.replaceValues(
+            step, transform(rejectedElements, ElementName::forAnnotatedElement));
+      }
+    }
+  }
+
+  private void reportMissingElements(Set<ElementName> missingElementNames) {
+    for (ElementName missingElementName : missingElementNames) {
+      Optional<? extends Element> missingElement = missingElementName.getElement(elements);
+      if (missingElement.isPresent()) {
+        messager.printMessage(
+            ERROR,
+            processingErrorMessage(
+                "this " + Ascii.toLowerCase(missingElement.get().getKind().name())),
+            missingElement.get());
+      } else {
+        messager.printMessage(ERROR, processingErrorMessage(missingElementName.name()));
+      }
+    }
+  }
+
+  private String processingErrorMessage(String target) {
+    return String.format(
+        "[%s:MiscError] %s was unable to process %s because not all of its dependencies could be "
+            + "resolved. Check for compilation errors or a circular dependency with generated "
+            + "code.",
+        getClass().getSimpleName(), getClass().getCanonicalName(), target);
+  }
+
+  /**
+   * Returns the valid annotated elements contained in all of the deferred elements. If none are
+   * found for a deferred element, defers it again.
+   */
+  private ImmutableSetMultimap<Class<? extends Annotation>, Element> validElements(
+      RoundEnvironment roundEnv) {
+    ImmutableSet<ElementName> prevDeferredElementNames = ImmutableSet.copyOf(deferredElementNames);
+    deferredElementNames.clear();
+
+    ImmutableSetMultimap.Builder<Class<? extends Annotation>, Element>
+        deferredElementsByAnnotationBuilder = ImmutableSetMultimap.builder();
+    for (ElementName deferredElementName : prevDeferredElementNames) {
+      Optional<? extends Element> deferredElement = deferredElementName.getElement(elements);
+      if (deferredElement.isPresent()) {
+        findAnnotatedElements(
+            deferredElement.get(),
+            getSupportedAnnotationClasses(),
+            deferredElementsByAnnotationBuilder);
+      } else {
+        deferredElementNames.add(deferredElementName);
+      }
+    }
+
+    ImmutableSetMultimap<Class<? extends Annotation>, Element> deferredElementsByAnnotation =
+        deferredElementsByAnnotationBuilder.build();
+
+    ImmutableSetMultimap.Builder<Class<? extends Annotation>, Element> validElements =
+        ImmutableSetMultimap.builder();
+
+    Set<ElementName> validElementNames = new LinkedHashSet<>();
+
+    // Look at the elements we've found and the new elements from this round and validate them.
+    for (Class<? extends Annotation> annotationClass : getSupportedAnnotationClasses()) {
+      // This should just call roundEnv.getElementsAnnotatedWith(Class) directly, but there is a bug
+      // in some versions of eclipse that cause that method to crash.
+      TypeElement annotationType = elements.getTypeElement(annotationClass.getCanonicalName());
+      Set<? extends Element> roundElements =
+          (annotationType == null)
+              ? ImmutableSet.<Element>of()
+              : roundEnv.getElementsAnnotatedWith(annotationType);
+      ImmutableSet<Element> prevRoundElements = deferredElementsByAnnotation.get(annotationClass);
+      for (Element element : Sets.union(roundElements, prevRoundElements)) {
+        ElementName elementName = ElementName.forAnnotatedElement(element);
+        boolean isValidElement =
+            validElementNames.contains(elementName)
+                || (!deferredElementNames.contains(elementName)
+                    && validateElement(
+                        element.getKind().equals(PACKAGE) ? element : getEnclosingType(element)));
+        if (isValidElement) {
+          validElements.put(annotationClass, element);
+          validElementNames.add(elementName);
+        } else {
+          deferredElementNames.add(elementName);
+        }
+      }
+    }
+
+    return validElements.build();
+  }
+
+  private ImmutableSetMultimap<Class<? extends Annotation>, Element> indexByAnnotation(
+      Set<ElementName> annotatedElements,
+      Set<? extends Class<? extends Annotation>> annotationClasses) {
+    ImmutableSetMultimap.Builder<Class<? extends Annotation>, Element> deferredElements =
+        ImmutableSetMultimap.builder();
+    for (ElementName elementName : annotatedElements) {
+      Optional<? extends Element> element = elementName.getElement(elements);
+      if (element.isPresent()) {
+        findAnnotatedElements(element.get(), annotationClasses, deferredElements);
+      }
+    }
+    return deferredElements.build();
+  }
+
+  /**
+   * Adds {@code element} and its enclosed elements to {@code annotatedElements} if they are
+   * annotated with any annotations in {@code annotationClasses}. Does not traverse to member types
+   * of {@code element}, so that if {@code Outer} is passed in the example below, looking for
+   * {@code @X}, then {@code Outer}, {@code Outer.foo}, and {@code Outer.foo()} will be added to the
+   * multimap, but neither {@code Inner} nor its members will.
+   *
+   * <pre><code>
+   *   {@literal @}X class Outer {
+   *     {@literal @}X Object foo;
+   *     {@literal @}X void foo() {}
+   *     {@literal @}X static class Inner {
+   *       {@literal @}X Object bar;
+   *       {@literal @}X void bar() {}
+   *     }
+   *   }
+   * </code></pre>
+   */
+  private static void findAnnotatedElements(
+      Element element,
+      Set<? extends Class<? extends Annotation>> annotationClasses,
+      ImmutableSetMultimap.Builder<Class<? extends Annotation>, Element> annotatedElements) {
+    for (Element enclosedElement : element.getEnclosedElements()) {
+      if (!enclosedElement.getKind().isClass() && !enclosedElement.getKind().isInterface()) {
+        findAnnotatedElements(enclosedElement, annotationClasses, annotatedElements);
+      }
+    }
+
+    // element.getEnclosedElements() does NOT return parameter elements
+    if (element instanceof ExecutableElement) {
+      for (Element parameterElement : asExecutable(element).getParameters()) {
+        findAnnotatedElements(parameterElement, annotationClasses, annotatedElements);
+      }
+    }
+    for (Class<? extends Annotation> annotationClass : annotationClasses) {
+      if (isAnnotationPresent(element, annotationClass)) {
+        annotatedElements.put(annotationClass, element);
+      }
+    }
+  }
+
+  /**
+   * Returns the nearest enclosing {@link TypeElement} to the current element, throwing an {@link
+   * IllegalArgumentException} if the provided {@link Element} is a {@link PackageElement} or is
+   * otherwise not enclosed by a type.
+   */
+  // TODO(cgruber) move to MoreElements and make public.
+  private static TypeElement getEnclosingType(Element element) {
+    return element.accept(
+        new SimpleElementVisitor8<TypeElement, Void>() {
+          @Override
+          protected TypeElement defaultAction(Element e, Void p) {
+            return e.getEnclosingElement().accept(this, p);
+          }
+
+          @Override
+          public TypeElement visitType(TypeElement e, Void p) {
+            return e;
+          }
+
+          @Override
+          public TypeElement visitPackage(PackageElement e, Void p) {
+            throw new IllegalArgumentException();
+          }
+        },
+        null);
+  }
+
+  /**
+   * The unit of processing logic that runs under the guarantee that all elements are complete and
+   * well-formed. A step may reject elements that are not ready for processing but may be at a later
+   * round.
+   */
+  public interface ProcessingStep {
+    /** The set of annotation types processed by this step. */
+    Set<? extends Class<? extends Annotation>> annotations();
+
+    /**
+     * The implementation of processing logic for the step. It is guaranteed that the keys in {@code
+     * elementsByAnnotation} will be a subset of the set returned by {@link #annotations()}.
+     *
+     * @return the elements (a subset of the values of {@code elementsByAnnotation}) that this step
+     *     is unable to process, possibly until a later processing round. These elements will be
+     *     passed back to this step at the next round of processing.
+     */
+    Set<? extends Element> process(
+        SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation);
+  }
+
+  /**
+   * A package or type name.
+   *
+   * <p>It's unfortunate that we have to track types and packages separately, but since there are
+   * two different methods to look them up in {@link Elements}, we end up with a lot of parallel
+   * logic. :(
+   *
+   * <p>Packages declared (and annotated) in {@code package-info.java} are tracked as deferred
+   * packages, type elements are tracked directly, and all other elements are tracked via their
+   * nearest enclosing type.
+   */
+  private static final class ElementName {
+    private enum Kind {
+      PACKAGE_NAME,
+      TYPE_NAME,
+    }
+
+    private final Kind kind;
+    private final String name;
+
+    private ElementName(Kind kind, Name name) {
+      this.kind = checkNotNull(kind);
+      this.name = name.toString();
+    }
+
+    /**
+     * An {@link ElementName} for an annotated element. If {@code element} is a package, uses the
+     * fully qualified name of the package. If it's a type, uses its fully qualified name.
+     * Otherwise, uses the fully-qualified name of the nearest enclosing type.
+     */
+    static ElementName forAnnotatedElement(Element element) {
+      return element.getKind() == PACKAGE
+          ? new ElementName(Kind.PACKAGE_NAME, asPackage(element).getQualifiedName())
+          : new ElementName(Kind.TYPE_NAME, getEnclosingType(element).getQualifiedName());
+    }
+
+    /** The fully-qualified name of the element. */
+    String name() {
+      return name;
+    }
+
+    /**
+     * The {@link Element} whose fully-qualified name is {@link #name()}. Absent if the relevant
+     * method on {@link Elements} returns {@code null}.
+     */
+    Optional<? extends Element> getElement(Elements elements) {
+      return Optional.fromNullable(
+          kind == Kind.PACKAGE_NAME
+              ? elements.getPackageElement(name)
+              : elements.getTypeElement(name));
+    }
+
+    @Override
+    public boolean equals(Object object) {
+      if (!(object instanceof ElementName)) {
+        return false;
+      }
+
+      ElementName that = (ElementName) object;
+      return this.kind == that.kind && this.name.equals(that.name);
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(kind, name);
+    }
+  }
+}
diff --git a/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java b/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java
new file mode 100644
index 0000000..bb35e22
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/GeneratedAnnotationSpecs.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import java.util.Optional;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.util.Elements;
+
+/** Utility methods for writing {@code @Generated} annotations using JavaPoet. */
+public final class GeneratedAnnotationSpecs {
+
+  private GeneratedAnnotationSpecs() {}
+
+  /**
+   * Returns {@code @Generated("processorClass"} if either {@code
+   * javax.annotation.processing.Generated} or {@code javax.annotation.Generated} is {@linkplain
+   * GeneratedAnnotations#generatedAnnotation(Elements) available at compile time}.
+   *
+   * @deprecated prefer {@link #generatedAnnotationSpec(Elements, SourceVersion, Class)}
+   */
+  @Deprecated
+  public static Optional<AnnotationSpec> generatedAnnotationSpec(
+      Elements elements, Class<?> processorClass) {
+    return generatedAnnotationSpecBuilder(elements, processorClass)
+        .map(AnnotationSpec.Builder::build);
+  }
+
+  /**
+   * Returns {@code @Generated(value = "processorClass", comments = "comments"} if either {@code
+   * javax.annotation.processing.Generated} or {@code javax.annotation.Generated} is {@linkplain
+   * GeneratedAnnotations#generatedAnnotation(Elements) available at compile time}.
+   *
+   * @deprecated prefer {@link #generatedAnnotationSpec(Elements, SourceVersion, Class, String)}
+   */
+  @Deprecated
+  public static Optional<AnnotationSpec> generatedAnnotationSpec(
+      Elements elements, Class<?> processorClass, String comments) {
+    return generatedAnnotationSpecBuilder(elements, processorClass)
+        .map(annotation -> annotation.addMember("comments", "$S", comments).build());
+  }
+
+  /**
+   * Returns {@code @Generated("processorClass"} for the target {@code SourceVersion}.
+   *
+   * <p>Returns {@code javax.annotation.processing.Generated} for JDK 9 and newer, {@code
+   * javax.annotation.Generated} for earlier releases, and Optional#empty()} if the annotation is
+   * not available.
+   */
+  public static Optional<AnnotationSpec> generatedAnnotationSpec(
+      Elements elements, SourceVersion sourceVersion, Class<?> processorClass) {
+    return generatedAnnotationSpecBuilder(elements, sourceVersion, processorClass)
+        .map(AnnotationSpec.Builder::build);
+  }
+
+  /**
+   * Returns {@code @Generated(value = "processorClass", comments = "comments"} for the target
+   * {@code SourceVersion}.
+   *
+   * <p>Returns {@code javax.annotation.processing.Generated} for JDK 9 and newer, {@code
+   * javax.annotation.Generated} for earlier releases, and Optional#empty()} if the annotation is
+   * not available.
+   */
+  public static Optional<AnnotationSpec> generatedAnnotationSpec(
+      Elements elements, SourceVersion sourceVersion, Class<?> processorClass, String comments) {
+    return generatedAnnotationSpecBuilder(elements, sourceVersion, processorClass)
+        .map(annotation -> annotation.addMember("comments", "$S", comments).build());
+  }
+
+  private static Optional<AnnotationSpec.Builder> generatedAnnotationSpecBuilder(
+      Elements elements, Class<?> processorClass) {
+    return GeneratedAnnotations.generatedAnnotation(elements)
+        .map(
+            generated ->
+                AnnotationSpec.builder(ClassName.get(generated))
+                    .addMember("value", "$S", processorClass.getCanonicalName()));
+  }
+
+  private static Optional<AnnotationSpec.Builder> generatedAnnotationSpecBuilder(
+      Elements elements, SourceVersion sourceVersion, Class<?> processorClass) {
+    return GeneratedAnnotations.generatedAnnotation(elements, sourceVersion)
+        .map(
+            generated ->
+                AnnotationSpec.builder(ClassName.get(generated))
+                    .addMember("value", "$S", processorClass.getCanonicalName()));
+  }
+}
diff --git a/common/src/main/java/com/google/auto/common/GeneratedAnnotations.java b/common/src/main/java/com/google/auto/common/GeneratedAnnotations.java
new file mode 100644
index 0000000..b4616d2
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/GeneratedAnnotations.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import java.util.Optional;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+
+/** Utility methods for writing {@code @Generated} annotations. */
+public final class GeneratedAnnotations {
+  private GeneratedAnnotations() {}
+
+  /**
+   * Returns the element corresponding to the version of the {@code @Generated} annotation present
+   * in the compile-time class- or module-path.
+   *
+   * <p>First looks for {@code javax.annotation.processing.Generated}, and then {@code
+   * javax.annotation.Generated}. Returns whichever is in the classpath (or modulepath), or {@link
+   * Optional#empty()} if neither is.
+   *
+   * @deprecated prefer {@link #generatedAnnotation(Elements, SourceVersion)}
+   */
+  @Deprecated
+  public static Optional<TypeElement> generatedAnnotation(Elements elements) {
+    TypeElement jdk9Generated = elements.getTypeElement("javax.annotation.processing.Generated");
+    if (jdk9Generated != null) {
+      return Optional.of(jdk9Generated);
+    }
+    return Optional.ofNullable(elements.getTypeElement("javax.annotation.Generated"));
+  }
+
+  /**
+   * Returns the element corresponding to the {@code @Generated} annotation present at the target
+   * {@code SourceVersion}.
+   *
+   * <p>Returns {@code javax.annotation.processing.Generated} for JDK 9 and newer, {@code
+   * javax.annotation.Generated} for earlier releases, and Optional#empty()} if the annotation is
+   * not available.
+   */
+  public static Optional<TypeElement> generatedAnnotation(
+      Elements elements, SourceVersion sourceVersion) {
+    return Optional.ofNullable(
+        elements.getTypeElement(
+            sourceVersion.compareTo(SourceVersion.RELEASE_8) > 0
+                ? "javax.annotation.processing.Generated"
+                : "javax.annotation.Generated"));
+  }
+}
diff --git a/common/src/main/java/com/google/auto/common/MoreElements.java b/common/src/main/java/com/google/auto/common/MoreElements.java
new file mode 100644
index 0000000..5e8e354
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/MoreElements.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2013 Google LLC
+ * Copyright (C) 2013 Square, Inc.
+ *
+ * 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 com.google.auto.common;
+
+import static javax.lang.model.element.ElementKind.PACKAGE;
+import static javax.lang.model.element.Modifier.STATIC;
+
+import com.google.auto.common.Overrides.ExplicitOverrides;
+import com.google.common.annotations.Beta;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.LinkedHashMultimap;
+import com.google.common.collect.SetMultimap;
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleElementVisitor8;
+import javax.lang.model.util.Types;
+
+/**
+ * Static utility methods pertaining to {@link Element} instances.
+ *
+ * @author Gregory Kick
+ */
+@Beta
+public final class MoreElements {
+  /**
+   * An alternate implementation of {@link Elements#getPackageOf} that does not require an
+   * {@link Elements} instance.
+   *
+   * @throws NullPointerException if {@code element} is {@code null}
+   */
+  public static PackageElement getPackage(Element element) {
+    while (element.getKind() != PACKAGE) {
+      element = element.getEnclosingElement();
+    }
+    return (PackageElement) element;
+  }
+
+  private static final class PackageElementVisitor extends CastingElementVisitor<PackageElement> {
+    private static final PackageElementVisitor INSTANCE = new PackageElementVisitor();
+
+    PackageElementVisitor() {
+      super("package element");
+    }
+
+    @Override
+    public PackageElement visitPackage(PackageElement e, Void ignore) {
+      return e;
+    }
+  }
+
+  /**
+   * Returns the given {@link Element} instance as {@link PackageElement}.
+   *
+   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should
+   * always be used over that idiom as instructed in the documentation for {@link Element}.
+   *
+   * @throws NullPointerException if {@code element} is {@code null}
+   * @throws IllegalArgumentException if {@code element} isn't a {@link PackageElement}.
+   */
+  public static PackageElement asPackage(Element element) {
+    return element.accept(PackageElementVisitor.INSTANCE, null);
+  }
+
+  private static final class TypeElementVisitor extends CastingElementVisitor<TypeElement> {
+    private static final TypeElementVisitor INSTANCE = new TypeElementVisitor();
+
+    TypeElementVisitor() {
+      super("type element");
+    }
+
+    @Override
+    public TypeElement visitType(TypeElement e, Void ignore) {
+      return e;
+    }
+  }
+
+  /**
+   * Returns true if the given {@link Element} instance is a {@link TypeElement}.
+   *
+   * <p>This method is functionally equivalent to an {@code instanceof} check, but should
+   * always be used over that idiom as instructed in the documentation for {@link Element}.
+   *
+   * @throws NullPointerException if {@code element} is {@code null}
+   */
+  public static boolean isType(Element element) {
+    return element.getKind().isClass() || element.getKind().isInterface();
+  }
+
+  /**
+   * Returns the given {@link Element} instance as {@link TypeElement}.
+   *
+   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should
+   * always be used over that idiom as instructed in the documentation for {@link Element}.
+   *
+   * @throws NullPointerException if {@code element} is {@code null}
+   * @throws IllegalArgumentException if {@code element} isn't a {@link TypeElement}.
+   */
+  public static TypeElement asType(Element element) {
+    return element.accept(TypeElementVisitor.INSTANCE, null);
+  }
+
+  /**
+   * Returns the given {@link Element} instance as {@link TypeParameterElement}.
+   *
+   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should
+   * always be used over that idiom as instructed in the documentation for {@link Element}.
+   *
+   * @throws NullPointerException if {@code element} is {@code null}
+   * @throws IllegalArgumentException if {@code element} isn't a {@link TypeParameterElement}.
+   */
+  public static TypeParameterElement asTypeParameter(Element element) {
+    return element.accept(TypeParameterElementVisitor.INSTANCE, null);
+  }
+
+  private static final class TypeParameterElementVisitor
+      extends CastingElementVisitor<TypeParameterElement> {
+    private static final TypeParameterElementVisitor INSTANCE = new TypeParameterElementVisitor();
+
+    TypeParameterElementVisitor() {
+      super("type parameter element");
+    }
+
+    @Override
+    public TypeParameterElement visitTypeParameter(TypeParameterElement e, Void ignore) {
+      return e;
+    }
+  }
+
+  private static final class VariableElementVisitor extends CastingElementVisitor<VariableElement> {
+    private static final VariableElementVisitor INSTANCE = new VariableElementVisitor();
+
+    VariableElementVisitor() {
+      super("variable element");
+    }
+
+    @Override
+    public VariableElement visitVariable(VariableElement e, Void ignore) {
+      return e;
+    }
+  }
+
+  /**
+   * Returns the given {@link Element} instance as {@link VariableElement}.
+   *
+   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should
+   * always be used over that idiom as instructed in the documentation for {@link Element}.
+   *
+   * @throws NullPointerException if {@code element} is {@code null}
+   * @throws IllegalArgumentException if {@code element} isn't a {@link VariableElement}.
+   */
+  public static VariableElement asVariable(Element element) {
+    return element.accept(VariableElementVisitor.INSTANCE, null);
+  }
+
+  private static final class ExecutableElementVisitor
+      extends CastingElementVisitor<ExecutableElement> {
+    private static final ExecutableElementVisitor INSTANCE = new ExecutableElementVisitor();
+
+    ExecutableElementVisitor() {
+      super("executable element");
+    }
+
+    @Override
+    public ExecutableElement visitExecutable(ExecutableElement e, Void label) {
+      return e;
+    }
+  }
+
+  /**
+   * Returns the given {@link Element} instance as {@link ExecutableElement}.
+   *
+   * <p>This method is functionally equivalent to an {@code instanceof} check and a cast, but should
+   * always be used over that idiom as instructed in the documentation for {@link Element}.
+   *
+   * @throws NullPointerException if {@code element} is {@code null}
+   * @throws IllegalArgumentException if {@code element} isn't a {@link ExecutableElement}.
+   */
+  public static ExecutableElement asExecutable(Element element) {
+    return element.accept(ExecutableElementVisitor.INSTANCE, null);
+  }
+
+  /**
+   * Returns {@code true} iff the given element has an {@link AnnotationMirror} whose
+   * {@linkplain AnnotationMirror#getAnnotationType() annotation type} has the same canonical name
+   * as that of {@code annotationClass}. This method is a safer alternative to calling
+   * {@link Element#getAnnotation} and checking for {@code null} as it avoids any interaction with
+   * annotation proxies.
+   */
+  public static boolean isAnnotationPresent(Element element,
+      Class<? extends Annotation> annotationClass) {
+    return getAnnotationMirror(element, annotationClass).isPresent();
+  }
+
+  /**
+   * Returns an {@link AnnotationMirror} for the annotation of type {@code annotationClass} on
+   * {@code element}, or {@link Optional#absent()} if no such annotation exists. This method is a
+   * safer alternative to calling {@link Element#getAnnotation} as it avoids any interaction with
+   * annotation proxies.
+   */
+  public static Optional<AnnotationMirror> getAnnotationMirror(Element element,
+      Class<? extends Annotation> annotationClass) {
+    String annotationClassName = annotationClass.getCanonicalName();
+    for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {
+      TypeElement annotationTypeElement = asType(annotationMirror.getAnnotationType().asElement());
+      if (annotationTypeElement.getQualifiedName().contentEquals(annotationClassName)) {
+        return Optional.of(annotationMirror);
+      }
+    }
+    return Optional.absent();
+  }
+
+  /**
+   * Returns a {@link Predicate} that can be used to filter elements by {@link Modifier}.
+   * The predicate returns {@code true} if the input {@link Element} has all of the given
+   * {@code modifiers}, perhaps in addition to others.
+   *
+   * <p>Here is an example how one could get a List of static methods of a class:
+   * <pre>{@code
+   * FluentIterable.from(ElementFilter.methodsIn(clazzElement.getEnclosedElements()))
+   *     .filter(MoreElements.hasModifiers(Modifier.STATIC).toList();
+   * }</pre>
+   */
+  public static <T extends Element> Predicate<T> hasModifiers(Modifier... modifiers) {
+    return hasModifiers(ImmutableSet.copyOf(modifiers));
+  }
+
+  /**
+   * Returns a {@link Predicate} that can be used to filter elements by {@link Modifier}.
+   * The predicate returns {@code true} if the input {@link Element} has all of the given
+   * {@code modifiers}, perhaps in addition to others.
+   *
+   * <p>Here is an example how one could get a List of methods with certain modifiers of a class:
+   * <pre>{@code
+   * Set<Modifier> modifiers = ...;
+   * FluentIterable.from(ElementFilter.methodsIn(clazzElement.getEnclosedElements()))
+   *     .filter(MoreElements.hasModifiers(modifiers).toList();}
+   * </pre>
+   */
+  public static <T extends Element> Predicate<T> hasModifiers(final Set<Modifier> modifiers) {
+    return new Predicate<T>() {
+      @Override
+      public boolean apply(T input) {
+        return input.getModifiers().containsAll(modifiers);
+      }
+    };
+  }
+
+  /**
+   * Returns the set of all non-private, non-static methods from {@code type}, including methods
+   * that it inherits from its ancestors. Inherited methods that are overridden are not included in
+   * the result. So if {@code type} defines {@code public String toString()}, the returned set will
+   * contain that method, but not the {@code toString()} method defined by {@code Object}.
+   *
+   * <p>The returned set may contain more than one method with the same signature, if
+   * {@code type} inherits those methods from different ancestors. For example, if it
+   * inherits from unrelated interfaces {@code One} and {@code Two} which each define
+   * {@code void foo();}, and if it does not itself override the {@code foo()} method,
+   * then both {@code One.foo()} and {@code Two.foo()} will be in the returned set.
+   *
+   * <p>The order of the returned set is deterministic: within a class or interface, methods are in
+   * the order they appear in the source code; methods in ancestors come before methods in
+   * descendants; methods in interfaces come before methods in classes; and in a class or interface
+   * that has more than one superinterface, the interfaces are in the order of their appearance in
+   * {@code implements} or {@code extends}.
+   *
+   * @param type the type whose own and inherited methods are to be returned
+   * @param elementUtils an {@link Elements} object, typically returned by
+   *     {@link javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}<!--
+   *     -->.{@link javax.annotation.processing.ProcessingEnvironment#getElementUtils
+   *     getElementUtils()}
+   *
+   * @deprecated The method {@link #getLocalAndInheritedMethods(TypeElement, Types, Elements)}
+   *     has better consistency between Java compilers.
+   */
+  @Deprecated
+  public static ImmutableSet<ExecutableElement> getLocalAndInheritedMethods(
+      TypeElement type, Elements elementUtils) {
+    Overrides overrides = new Overrides.NativeOverrides(elementUtils);
+    return getLocalAndInheritedMethods(type, overrides);
+  }
+
+  /**
+   * Returns the set of all non-private, non-static methods from {@code type}, including methods
+   * that it inherits from its ancestors. Inherited methods that are overridden are not included in
+   * the result. So if {@code type} defines {@code public String toString()}, the returned set will
+   * contain that method, but not the {@code toString()} method defined by {@code Object}.
+   *
+   * <p>The returned set may contain more than one method with the same signature, if
+   * {@code type} inherits those methods from different ancestors. For example, if it
+   * inherits from unrelated interfaces {@code One} and {@code Two} which each define
+   * {@code void foo();}, and if it does not itself override the {@code foo()} method,
+   * then both {@code One.foo()} and {@code Two.foo()} will be in the returned set.
+   *
+   * <p>The order of the returned set is deterministic: within a class or interface, methods are in
+   * the order they appear in the source code; methods in ancestors come before methods in
+   * descendants; methods in interfaces come before methods in classes; and in a class or interface
+   * that has more than one superinterface, the interfaces are in the order of their appearance in
+   * {@code implements} or {@code extends}.
+   *
+   * @param type the type whose own and inherited methods are to be returned
+   * @param typeUtils a {@link Types} object, typically returned by
+   *     {@link javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}<!--
+   *     -->.{@link javax.annotation.processing.ProcessingEnvironment#getTypeUtils
+   *     getTypeUtils()}
+   * @param elementUtils an {@link Elements} object, typically returned by
+   *     {@link javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}<!--
+   *     -->.{@link javax.annotation.processing.ProcessingEnvironment#getElementUtils
+   *     getElementUtils()}
+   */
+  public static ImmutableSet<ExecutableElement> getLocalAndInheritedMethods(
+      TypeElement type, Types typeUtils, Elements elementUtils) {
+    return getLocalAndInheritedMethods(type, new ExplicitOverrides(typeUtils));
+  }
+
+  private static ImmutableSet<ExecutableElement> getLocalAndInheritedMethods(
+      TypeElement type, Overrides overrides) {
+    PackageElement pkg = getPackage(type);
+
+    ImmutableSet.Builder<ExecutableElement> methods = ImmutableSet.builder();
+    for (ExecutableElement method : getAllMethods(type, overrides)) {
+      // Filter out all static and non-visible methods.
+      if (!method.getModifiers().contains(STATIC) && methodVisibleFromPackage(method, pkg)) {
+        methods.add(method);
+      }
+    }
+    return methods.build();
+  }
+
+  /**
+   * Tests whether one method, as a member of a given type, overrides another method.
+   *
+   * <p>This method does the same thing as {@link Elements#overrides(ExecutableElement,
+   * ExecutableElement, TypeElement)}, but in a way that is more consistent between compilers, in
+   * particular between javac and ecj (the Eclipse compiler).
+   *
+   * @param overrider the first method, possible overrider
+   * @param overridden the second method, possibly being overridden
+   * @param type the type of which the first method is a member
+   * @return {@code true} if and only if the first method overrides the second
+   */
+  public static boolean overrides(
+      ExecutableElement overrider,
+      ExecutableElement overridden,
+      TypeElement type,
+      Types typeUtils) {
+    return new ExplicitOverrides(typeUtils).overrides(overrider, overridden, type);
+  }
+
+  /**
+   * Returns the set of all methods from {@code type}, including methods that it inherits
+   * from its ancestors. Inherited methods that are overridden are not included in the
+   * result. So if {@code type} defines {@code public String toString()}, the returned set
+   * will contain that method, but not the {@code toString()} method defined by {@code Object}.
+   *
+   * <p>The returned set may contain more than one method with the same signature, if
+   * {@code type} inherits those methods from different ancestors. For example, if it
+   * inherits from unrelated interfaces {@code One} and {@code Two} which each define
+   * {@code void foo();}, and if it does not itself override the {@code foo()} method,
+   * then both {@code One.foo()} and {@code Two.foo()} will be in the returned set.
+   *
+   * <p>The order of the returned set is deterministic: within a class or interface, methods are in
+   * the order they appear in the source code; methods in ancestors come before methods in
+   * descendants; methods in interfaces come before methods in classes; and in a class or interface
+   * that has more than one superinterface, the interfaces are in the order of their appearance in
+   * {@code implements} or {@code extends}.
+   *
+   * @param type the type whose own and inherited methods are to be returned
+   * @param typeUtils a {@link Types} object, typically returned by
+   *     {@link javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}<!--
+   *     -->.{@link javax.annotation.processing.ProcessingEnvironment#getTypeUtils
+   *     getTypeUtils()}
+   * @param elementUtils an {@link Elements} object, typically returned by
+   *     {@link javax.annotation.processing.AbstractProcessor#processingEnv processingEnv}<!--
+   *     -->.{@link javax.annotation.processing.ProcessingEnvironment#getElementUtils
+   *     getElementUtils()}
+   */
+  public static ImmutableSet<ExecutableElement> getAllMethods(
+      TypeElement type, Types typeUtils, Elements elementUtils) {
+    return getAllMethods(type, new ExplicitOverrides(typeUtils));
+  }
+
+  private static ImmutableSet<ExecutableElement> getAllMethods(
+      TypeElement type, Overrides overrides) {
+    SetMultimap<String, ExecutableElement> methodMap = LinkedHashMultimap.create();
+    getAllMethods(type, methodMap);
+    // Find methods that are overridden. We do this using `Elements.overrides`, which means
+    // that it is inherently a quadratic operation, since we have to compare every method against
+    // every other method. We reduce the performance impact by (a) grouping methods by name, since
+    // a method cannot override another method with a different name, and (b) making sure that
+    // methods in ancestor types precede those in descendant types, which means we only have to
+    // check a method against the ones that follow it in that order.
+    Set<ExecutableElement> overridden = new LinkedHashSet<ExecutableElement>();
+    for (Collection<ExecutableElement> methods : methodMap.asMap().values()) {
+      List<ExecutableElement> methodList = ImmutableList.copyOf(methods);
+      for (int i = 0; i < methodList.size(); i++) {
+        ExecutableElement methodI = methodList.get(i);
+        for (int j = i + 1; j < methodList.size(); j++) {
+          ExecutableElement methodJ = methodList.get(j);
+          if (overrides.overrides(methodJ, methodI, type)) {
+            overridden.add(methodI);
+            break;
+          }
+        }
+      }
+    }
+    Set<ExecutableElement> methods = new LinkedHashSet<ExecutableElement>(methodMap.values());
+    methods.removeAll(overridden);
+    return ImmutableSet.copyOf(methods);
+  }
+
+  // Add to `methods` the static and instance methods from `type`. This means all methods from
+  // `type` itself and all methods it inherits from its ancestors. This method does not take
+  // overriding into account, so it will add both an ancestor method and a descendant method that
+  // overrides it. `methods` is a multimap from a method name to all of the methods with that name,
+  // including methods that override or overload one another. Within those methods, those in
+  // ancestor types always precede those in descendant types.
+  private static void getAllMethods(
+      TypeElement type, SetMultimap<String, ExecutableElement> methods) {
+    for (TypeMirror superInterface : type.getInterfaces()) {
+      getAllMethods(MoreTypes.asTypeElement(superInterface), methods);
+    }
+    if (type.getSuperclass().getKind() != TypeKind.NONE) {
+      // Visit the superclass after superinterfaces so we will always see the implementation of a
+      // method after any interfaces that declared it.
+      getAllMethods(MoreTypes.asTypeElement(type.getSuperclass()), methods);
+    }
+    for (ExecutableElement method : ElementFilter.methodsIn(type.getEnclosedElements())) {
+      methods.put(method.getSimpleName().toString(), method);
+    }
+  }
+
+  static boolean methodVisibleFromPackage(ExecutableElement method, PackageElement pkg) {
+    // We use Visibility.ofElement rather than .effectiveVisibilityOfElement because it doesn't
+    // really matter whether the containing class is visible. If you inherit a public method
+    // then you have a public method, regardless of whether you inherit it from a public class.
+    Visibility visibility = Visibility.ofElement(method);
+    switch (visibility) {
+      case PRIVATE:
+        return false;
+      case DEFAULT:
+        return getPackage(method).equals(pkg);
+      default:
+        return true;
+    }
+  }
+
+  private abstract static class CastingElementVisitor<T> extends SimpleElementVisitor8<T, Void> {
+    private final String label;
+
+    CastingElementVisitor(String label) {
+      this.label = label;
+    }
+
+    @Override
+    protected final T defaultAction(Element e, Void ignore) {
+      throw new IllegalArgumentException(e + " does not represent a " + label);
+    }
+  }
+
+  private MoreElements() {}
+}
diff --git a/common/src/main/java/com/google/auto/common/MoreTypes.java b/common/src/main/java/com/google/auto/common/MoreTypes.java
new file mode 100644
index 0000000..e09680b
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/MoreTypes.java
@@ -0,0 +1,1019 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static javax.lang.model.type.TypeKind.ARRAY;
+import static javax.lang.model.type.TypeKind.DECLARED;
+import static javax.lang.model.type.TypeKind.EXECUTABLE;
+import static javax.lang.model.type.TypeKind.INTERSECTION;
+import static javax.lang.model.type.TypeKind.TYPEVAR;
+import static javax.lang.model.type.TypeKind.WILDCARD;
+
+import com.google.common.base.Equivalence;
+import com.google.common.base.Objects;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ErrorType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.IntersectionType;
+import javax.lang.model.type.NoType;
+import javax.lang.model.type.NullType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor8;
+import javax.lang.model.util.Types;
+
+/**
+ * Utilities related to {@link TypeMirror} instances.
+ *
+ * @author Gregory Kick
+ * @since 2.0
+ */
+public final class MoreTypes {
+  private static final class TypeEquivalence extends Equivalence<TypeMirror> {
+    private static final TypeEquivalence INSTANCE = new TypeEquivalence();
+
+    @Override
+    protected boolean doEquivalent(TypeMirror a, TypeMirror b) {
+      return MoreTypes.equal(a, b, ImmutableSet.<ComparedElements>of());
+    }
+
+    @Override
+    protected int doHash(TypeMirror t) {
+      return MoreTypes.hash(t, ImmutableSet.<Element>of());
+    }
+  }
+
+  /**
+   * Returns an {@link Equivalence} that can be used to compare types. The standard way to compare
+   * types is {@link javax.lang.model.util.Types#isSameType Types.isSameType}, but this alternative
+   * may be preferred in a number of cases:
+   *
+   * <ul>
+   * <li>If you don't have an instance of {@code Types}.
+   * <li>If you want a reliable {@code hashCode()} for the types, for example to construct a set
+   *     of types using {@link java.util.HashSet} with {@link Equivalence#wrap(Object)}.
+   * <li>If you want distinct type variables to be considered equal if they have the same names
+   *     and bounds.
+   * <li>If you want wildcard types to compare equal if they have the same bounds. {@code
+   *     Types.isSameType} never considers wildcards equal, even when comparing a type to itself.
+   * </ul>
+   */
+  public static Equivalence<TypeMirror> equivalence() {
+    return TypeEquivalence.INSTANCE;
+  }
+
+  // So EQUAL_VISITOR can be a singleton, we maintain visiting state, in particular which types
+  // have been seen already, in this object.
+  // The logic for handling recursive types like Comparable<T extends Comparable<T>> is very tricky.
+  // If we're not careful we'll end up with an infinite recursion. So we record the types that
+  // we've already seen during the recursion, and if we see the same pair of types again we just
+  // return true provisionally. But "the same pair of types" is itself poorly-defined. We can't
+  // just say that it is an equal pair of TypeMirrors, because of course if we knew how to
+  // determine that then we wouldn't need the complicated type visitor at all. On the other hand,
+  // we can't say that it is an identical pair of TypeMirrors either, because there's no
+  // guarantee that the TypeMirrors for the two Ts in Comparable<T extends Comparable<T>> will be
+  // represented by the same object, and indeed with the Eclipse compiler they aren't. We could
+  // compare the corresponding Elements, since equality is well-defined there, but that's not enough
+  // either, because the Element for Set<Object> is the same as the one for Set<String>. So we
+  // approximate by comparing the Elements and, if there are any type arguments, requiring them to
+  // be identical. This may not be foolproof either but it is sufficient for all the cases we've
+  // encountered so far.
+  private static final class EqualVisitorParam {
+    TypeMirror type;
+    Set<ComparedElements> visiting;
+  }
+
+  private static class ComparedElements {
+    final Element a;
+    final ImmutableList<TypeMirror> aArguments;
+    final Element b;
+    final ImmutableList<TypeMirror> bArguments;
+
+    ComparedElements(
+        Element a,
+        ImmutableList<TypeMirror> aArguments,
+        Element b,
+        ImmutableList<TypeMirror> bArguments) {
+      this.a = a;
+      this.aArguments = aArguments;
+      this.b = b;
+      this.bArguments = bArguments;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (o instanceof ComparedElements) {
+        ComparedElements that = (ComparedElements) o;
+        int nArguments = aArguments.size();
+        if (!this.a.equals(that.a)
+            || !this.b.equals(that.b)
+            || nArguments != bArguments.size()) {
+          // The arguments must be the same size, but we check anyway.
+          return false;
+        }
+        for (int i = 0; i < nArguments; i++) {
+          if (aArguments.get(i) != bArguments.get(i)) {
+            return false;
+          }
+        }
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    @Override
+    public int hashCode() {
+      return a.hashCode() * 31 + b.hashCode();
+    }
+  }
+
+  private static final class EqualVisitor extends SimpleTypeVisitor8<Boolean, EqualVisitorParam> {
+    private static final EqualVisitor INSTANCE = new EqualVisitor();
+
+    @Override
+    protected Boolean defaultAction(TypeMirror a, EqualVisitorParam p) {
+      return a.getKind().equals(p.type.getKind());
+    }
+
+    @Override
+    public Boolean visitArray(ArrayType a, EqualVisitorParam p) {
+      if (p.type.getKind().equals(ARRAY)) {
+        ArrayType b = (ArrayType) p.type;
+        return equal(a.getComponentType(), b.getComponentType(), p.visiting);
+      }
+      return false;
+    }
+
+    @Override
+    public Boolean visitDeclared(DeclaredType a, EqualVisitorParam p) {
+      if (p.type.getKind().equals(DECLARED)) {
+        DeclaredType b = (DeclaredType) p.type;
+        Element aElement = a.asElement();
+        Element bElement = b.asElement();
+        Set<ComparedElements> newVisiting =
+            visitingSetPlus(
+                p.visiting, aElement, a.getTypeArguments(), bElement, b.getTypeArguments());
+        if (newVisiting.equals(p.visiting)) {
+          // We're already visiting this pair of elements.
+          // This can happen for example with Enum in Enum<E extends Enum<E>>. Return a
+          // provisional true value since if the Elements are not in fact equal the original
+          // visitor of Enum will discover that. We have to check both Elements being compared
+          // though to avoid missing the fact that one of the types being compared
+          // differs at exactly this point.
+          return true;
+        }
+        return aElement.equals(bElement)
+            && equal(enclosingType(a), enclosingType(b), newVisiting)
+            && equalLists(a.getTypeArguments(), b.getTypeArguments(), newVisiting);
+      }
+      return false;
+    }
+
+    @Override
+    @SuppressWarnings("TypeEquals")
+    public Boolean visitError(ErrorType a, EqualVisitorParam p) {
+      return a.equals(p.type);
+    }
+
+    @Override
+    public Boolean visitExecutable(ExecutableType a, EqualVisitorParam p) {
+      if (p.type.getKind().equals(EXECUTABLE)) {
+        ExecutableType b = (ExecutableType) p.type;
+        return equalLists(a.getParameterTypes(), b.getParameterTypes(), p.visiting)
+            && equal(a.getReturnType(), b.getReturnType(), p.visiting)
+            && equalLists(a.getThrownTypes(), b.getThrownTypes(), p.visiting)
+            && equalLists(a.getTypeVariables(), b.getTypeVariables(), p.visiting);
+      }
+      return false;
+    }
+
+    @Override
+    public Boolean visitIntersection(IntersectionType a, EqualVisitorParam p) {
+      if (p.type.getKind().equals(INTERSECTION)) {
+        IntersectionType b = (IntersectionType) p.type;
+        return equalLists(a.getBounds(), b.getBounds(), p.visiting);
+      }
+      return false;
+    }
+
+    @Override
+    public Boolean visitTypeVariable(TypeVariable a, EqualVisitorParam p) {
+      if (p.type.getKind().equals(TYPEVAR)) {
+        TypeVariable b = (TypeVariable) p.type;
+        TypeParameterElement aElement = (TypeParameterElement) a.asElement();
+        TypeParameterElement bElement = (TypeParameterElement) b.asElement();
+        Set<ComparedElements> newVisiting = visitingSetPlus(p.visiting, aElement, bElement);
+        if (newVisiting.equals(p.visiting)) {
+          // We're already visiting this pair of elements.
+          // This can happen with our friend Eclipse when looking at <T extends Comparable<T>>.
+          // It incorrectly reports the upper bound of T as T itself.
+          return true;
+        }
+        // We use aElement.getBounds() instead of a.getUpperBound() to avoid having to deal with
+        // the different way intersection types (like <T extends Number & Comparable<T>>) are
+        // represented before and after Java 8. We do have an issue that this code may consider
+        // that <T extends Foo & Bar> is different from <T extends Bar & Foo>, but it's very
+        // hard to avoid that, and not likely to be much of a problem in practice.
+        return equalLists(aElement.getBounds(), bElement.getBounds(), newVisiting)
+            && equal(a.getLowerBound(), b.getLowerBound(), newVisiting)
+            && a.asElement().getSimpleName().equals(b.asElement().getSimpleName());
+      }
+      return false;
+    }
+
+    @Override
+    public Boolean visitWildcard(WildcardType a, EqualVisitorParam p) {
+      if (p.type.getKind().equals(WILDCARD)) {
+        WildcardType b = (WildcardType) p.type;
+        return equal(a.getExtendsBound(), b.getExtendsBound(), p.visiting)
+            && equal(a.getSuperBound(), b.getSuperBound(), p.visiting);
+      }
+      return false;
+    }
+
+    @Override
+    public Boolean visitUnknown(TypeMirror a, EqualVisitorParam p) {
+      throw new UnsupportedOperationException();
+    }
+
+    private Set<ComparedElements> visitingSetPlus(
+        Set<ComparedElements> visiting, Element a, Element b) {
+      ImmutableList<TypeMirror> noArguments = ImmutableList.of();
+      return visitingSetPlus(visiting, a, noArguments, b, noArguments);
+    }
+
+    private Set<ComparedElements> visitingSetPlus(
+        Set<ComparedElements> visiting,
+        Element a,
+        List<? extends TypeMirror> aArguments,
+        Element b,
+        List<? extends TypeMirror> bArguments) {
+      ComparedElements comparedElements =
+          new ComparedElements(
+              a, ImmutableList.<TypeMirror>copyOf(aArguments),
+              b, ImmutableList.<TypeMirror>copyOf(bArguments));
+      Set<ComparedElements> newVisiting = new HashSet<ComparedElements>(visiting);
+      newVisiting.add(comparedElements);
+      return newVisiting;
+    }
+  }
+
+  @SuppressWarnings("TypeEquals")
+  private static boolean equal(TypeMirror a, TypeMirror b, Set<ComparedElements> visiting) {
+    // TypeMirror.equals is not guaranteed to return true for types that are equal, but we can
+    // assume that if it does return true then the types are equal. This check also avoids getting
+    // stuck in infinite recursion when Eclipse decrees that the upper bound of the second K in
+    // <K extends Comparable<K>> is a distinct but equal K.
+    // The javac implementation of ExecutableType, at least in some versions, does not take thrown
+    // exceptions into account in its equals implementation, so avoid this optimization for
+    // ExecutableType.
+    if (Objects.equal(a, b) && !(a instanceof ExecutableType)) {
+      return true;
+    }
+    EqualVisitorParam p = new EqualVisitorParam();
+    p.type = b;
+    p.visiting = visiting;
+    return (a == b) || (a != null && b != null && a.accept(EqualVisitor.INSTANCE, p));
+  }
+
+  /**
+   * Returns the type of the innermost enclosing instance, or null if there is none. This is the
+   * same as {@link DeclaredType#getEnclosingType()} except that it returns null rather than
+   * NoType for a static type. We need this because of
+   * <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=508222">this bug</a> whereby
+   * the Eclipse compiler returns a value for static classes that is not NoType.
+   */
+  private static TypeMirror enclosingType(DeclaredType t) {
+    TypeMirror enclosing = t.getEnclosingType();
+    if (enclosing.getKind().equals(TypeKind.NONE)
+        || t.asElement().getModifiers().contains(Modifier.STATIC)) {
+      return null;
+    }
+    return enclosing;
+  }
+
+  private static boolean equalLists(
+      List<? extends TypeMirror> a, List<? extends TypeMirror> b, Set<ComparedElements> visiting) {
+    int size = a.size();
+    if (size != b.size()) {
+      return false;
+    }
+    // Use iterators in case the Lists aren't RandomAccess
+    Iterator<? extends TypeMirror> aIterator = a.iterator();
+    Iterator<? extends TypeMirror> bIterator = b.iterator();
+    while (aIterator.hasNext()) {
+      if (!bIterator.hasNext()) {
+        return false;
+      }
+      TypeMirror nextMirrorA = aIterator.next();
+      TypeMirror nextMirrorB = bIterator.next();
+      if (!equal(nextMirrorA, nextMirrorB, visiting)) {
+        return false;
+      }
+    }
+    return !aIterator.hasNext();
+  }
+
+  private static final int HASH_SEED = 17;
+  private static final int HASH_MULTIPLIER = 31;
+
+  private static final class HashVisitor extends SimpleTypeVisitor8<Integer, Set<Element>> {
+    private static final HashVisitor INSTANCE = new HashVisitor();
+
+    int hashKind(int seed, TypeMirror t) {
+      int result = seed * HASH_MULTIPLIER;
+      result += t.getKind().hashCode();
+      return result;
+    }
+
+    @Override
+    protected Integer defaultAction(TypeMirror e, Set<Element> visiting) {
+      return hashKind(HASH_SEED, e);
+    }
+
+    @Override
+    public Integer visitArray(ArrayType t, Set<Element> visiting) {
+      int result = hashKind(HASH_SEED, t);
+      result *= HASH_MULTIPLIER;
+      result += t.getComponentType().accept(this, visiting);
+      return result;
+    }
+
+    @Override
+    public Integer visitDeclared(DeclaredType t, Set<Element> visiting) {
+      Element element = t.asElement();
+      if (visiting.contains(element)) {
+        return 0;
+      }
+      Set<Element> newVisiting = new HashSet<Element>(visiting);
+      newVisiting.add(element);
+      int result = hashKind(HASH_SEED, t);
+      result *= HASH_MULTIPLIER;
+      result += t.asElement().hashCode();
+      result *= HASH_MULTIPLIER;
+      result += t.getEnclosingType().accept(this, newVisiting);
+      result *= HASH_MULTIPLIER;
+      result += hashList(t.getTypeArguments(), newVisiting);
+      return result;
+    }
+
+    @Override
+    public Integer visitExecutable(ExecutableType t, Set<Element> visiting) {
+      int result = hashKind(HASH_SEED, t);
+      result *= HASH_MULTIPLIER;
+      result += hashList(t.getParameterTypes(), visiting);
+      result *= HASH_MULTIPLIER;
+      result += t.getReturnType().accept(this, visiting);
+      result *= HASH_MULTIPLIER;
+      result += hashList(t.getThrownTypes(), visiting);
+      result *= HASH_MULTIPLIER;
+      result += hashList(t.getTypeVariables(), visiting);
+      return result;
+    }
+
+    @Override
+    public Integer visitTypeVariable(TypeVariable t, Set<Element> visiting) {
+      int result = hashKind(HASH_SEED, t);
+      result *= HASH_MULTIPLIER;
+      result += t.getLowerBound().accept(this, visiting);
+      TypeParameterElement element = (TypeParameterElement) t.asElement();
+      for (TypeMirror bound : element.getBounds()) {
+        result *= HASH_MULTIPLIER;
+        result += bound.accept(this, visiting);
+      }
+      return result;
+    }
+
+    @Override
+    public Integer visitWildcard(WildcardType t, Set<Element> visiting) {
+      int result = hashKind(HASH_SEED, t);
+      result *= HASH_MULTIPLIER;
+      result += (t.getExtendsBound() == null) ? 0 : t.getExtendsBound().accept(this, visiting);
+      result *= HASH_MULTIPLIER;
+      result += (t.getSuperBound() == null) ? 0 : t.getSuperBound().accept(this, visiting);
+      return result;
+    }
+
+    @Override
+    public Integer visitUnknown(TypeMirror t, Set<Element> visiting) {
+      throw new UnsupportedOperationException();
+    }
+  };
+
+  private static int hashList(List<? extends TypeMirror> mirrors, Set<Element> visiting) {
+    int result = HASH_SEED;
+    for (TypeMirror mirror : mirrors) {
+      result *= HASH_MULTIPLIER;
+      result += hash(mirror, visiting);
+    }
+    return result;
+  }
+
+  private static int hash(TypeMirror mirror, Set<Element> visiting) {
+    return mirror == null ? 0 : mirror.accept(HashVisitor.INSTANCE, visiting);
+  }
+
+  /**
+   * Returns the set of {@linkplain TypeElement types} that are referenced by the given {@link
+   * TypeMirror}.
+   */
+  public static ImmutableSet<TypeElement> referencedTypes(TypeMirror type) {
+    checkNotNull(type);
+    ImmutableSet.Builder<TypeElement> elements = ImmutableSet.builder();
+    type.accept(ReferencedTypes.INSTANCE, elements);
+    return elements.build();
+  }
+
+  private static final class ReferencedTypes
+      extends SimpleTypeVisitor8<Void, ImmutableSet.Builder<TypeElement>> {
+    private static final ReferencedTypes INSTANCE = new ReferencedTypes();
+
+    @Override
+    public Void visitArray(ArrayType t, ImmutableSet.Builder<TypeElement> p) {
+      t.getComponentType().accept(this, p);
+      return null;
+    }
+
+    @Override
+    public Void visitDeclared(DeclaredType t, ImmutableSet.Builder<TypeElement> p) {
+      p.add(MoreElements.asType(t.asElement()));
+      for (TypeMirror typeArgument : t.getTypeArguments()) {
+        typeArgument.accept(this, p);
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitTypeVariable(TypeVariable t, ImmutableSet.Builder<TypeElement> p) {
+      t.getLowerBound().accept(this, p);
+      t.getUpperBound().accept(this, p);
+      return null;
+    }
+
+    @Override
+    public Void visitWildcard(WildcardType t, ImmutableSet.Builder<TypeElement> p) {
+      TypeMirror extendsBound = t.getExtendsBound();
+      if (extendsBound != null) {
+        extendsBound.accept(this, p);
+      }
+      TypeMirror superBound = t.getSuperBound();
+      if (superBound != null) {
+        superBound.accept(this, p);
+      }
+      return null;
+    }
+  }
+
+  /**
+   * An alternate implementation of {@link Types#asElement} that does not require a {@link Types}
+   * instance with the notable difference that it will throw {@link IllegalArgumentException}
+   * instead of returning null if the {@link TypeMirror} can not be converted to an {@link Element}.
+   *
+   * @throws NullPointerException if {@code typeMirror} is {@code null}
+   * @throws IllegalArgumentException if {@code typeMirror} cannot be converted to an {@link
+   *     Element}
+   */
+  public static Element asElement(TypeMirror typeMirror) {
+    return typeMirror.accept(AsElementVisitor.INSTANCE, null);
+  }
+
+  private static final class AsElementVisitor extends SimpleTypeVisitor8<Element, Void> {
+    private static final AsElementVisitor INSTANCE = new AsElementVisitor();
+
+    @Override
+    protected Element defaultAction(TypeMirror e, Void p) {
+      throw new IllegalArgumentException(e + " cannot be converted to an Element");
+    }
+
+    @Override
+    public Element visitDeclared(DeclaredType t, Void p) {
+      return t.asElement();
+    }
+
+    @Override
+    public Element visitError(ErrorType t, Void p) {
+      return t.asElement();
+    }
+
+    @Override
+    public Element visitTypeVariable(TypeVariable t, Void p) {
+      return t.asElement();
+    }
+  };
+
+  // TODO(gak): consider removing these two methods as they're pretty trivial now
+  public static TypeElement asTypeElement(TypeMirror mirror) {
+    return MoreElements.asType(asElement(mirror));
+  }
+
+  public static ImmutableSet<TypeElement> asTypeElements(Iterable<? extends TypeMirror> mirrors) {
+    checkNotNull(mirrors);
+    ImmutableSet.Builder<TypeElement> builder = ImmutableSet.builder();
+    for (TypeMirror mirror : mirrors) {
+      builder.add(asTypeElement(mirror));
+    }
+    return builder.build();
+  }
+
+  /**
+   * Returns a {@link ArrayType} if the {@link TypeMirror} represents an array or throws an {@link
+   * IllegalArgumentException}.
+   */
+  public static ArrayType asArray(TypeMirror maybeArrayType) {
+    return maybeArrayType.accept(ArrayTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class ArrayTypeVisitor extends CastingTypeVisitor<ArrayType> {
+    private static final ArrayTypeVisitor INSTANCE = new ArrayTypeVisitor();
+
+    ArrayTypeVisitor() {
+      super("array");
+    }
+
+    @Override
+    public ArrayType visitArray(ArrayType type, Void ignore) {
+      return type;
+    }
+  }
+
+  /**
+   * Returns a {@link DeclaredType} if the {@link TypeMirror} represents a declared type such as a
+   * class, interface, union/compound, or enum or throws an {@link IllegalArgumentException}.
+   */
+  public static DeclaredType asDeclared(TypeMirror maybeDeclaredType) {
+    return maybeDeclaredType.accept(DeclaredTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class DeclaredTypeVisitor extends CastingTypeVisitor<DeclaredType> {
+    private static final DeclaredTypeVisitor INSTANCE = new DeclaredTypeVisitor();
+
+    DeclaredTypeVisitor() {
+      super("declared type");
+    }
+
+    @Override
+    public DeclaredType visitDeclared(DeclaredType type, Void ignore) {
+      return type;
+    }
+  }
+
+  /**
+   * Returns a {@link ExecutableType} if the {@link TypeMirror} represents an executable type such
+   * as may result from missing code, or bad compiles or throws an {@link IllegalArgumentException}.
+   */
+  public static ErrorType asError(TypeMirror maybeErrorType) {
+    return maybeErrorType.accept(ErrorTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class ErrorTypeVisitor extends CastingTypeVisitor<ErrorType> {
+    private static final ErrorTypeVisitor INSTANCE = new ErrorTypeVisitor();
+
+    ErrorTypeVisitor() {
+      super("error type");
+    }
+
+    @Override
+    public ErrorType visitError(ErrorType type, Void ignore) {
+      return type;
+    }
+  }
+
+  /**
+   * Returns a {@link ExecutableType} if the {@link TypeMirror} represents an executable type such
+   * as a method, constructor, or initializer or throws an {@link IllegalArgumentException}.
+   */
+  public static ExecutableType asExecutable(TypeMirror maybeExecutableType) {
+    return maybeExecutableType.accept(ExecutableTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class ExecutableTypeVisitor extends CastingTypeVisitor<ExecutableType> {
+    private static final ExecutableTypeVisitor INSTANCE = new ExecutableTypeVisitor();
+
+    ExecutableTypeVisitor() {
+      super("executable type");
+    }
+
+    @Override
+    public ExecutableType visitExecutable(ExecutableType type, Void ignore) {
+      return type;
+    }
+  }
+
+  /**
+   * Returns an {@link IntersectionType} if the {@link TypeMirror} represents an intersection-type
+   * or throws an {@link IllegalArgumentException}.
+   */
+  public static IntersectionType asIntersection(TypeMirror maybeIntersectionType) {
+    return maybeIntersectionType.accept(IntersectionTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class IntersectionTypeVisitor extends CastingTypeVisitor<IntersectionType> {
+    private static final IntersectionTypeVisitor INSTANCE = new IntersectionTypeVisitor();
+
+    IntersectionTypeVisitor() {
+      super("intersection type");
+    }
+
+    @Override
+    public IntersectionType visitIntersection(IntersectionType type, Void ignore) {
+      return type;
+    }
+  }
+
+  /**
+   * Returns a {@link NoType} if the {@link TypeMirror} represents an non-type such as void, or
+   * package, etc. or throws an {@link IllegalArgumentException}.
+   */
+  public static NoType asNoType(TypeMirror maybeNoType) {
+    return maybeNoType.accept(NoTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class NoTypeVisitor extends CastingTypeVisitor<NoType> {
+    private static final NoTypeVisitor INSTANCE = new NoTypeVisitor();
+
+    NoTypeVisitor() {
+      super("non-type");
+    }
+
+    @Override
+    public NoType visitNoType(NoType type, Void ignore) {
+      return type;
+    }
+  }
+
+  /**
+   * Returns a {@link NullType} if the {@link TypeMirror} represents the null type or throws an
+   * {@link IllegalArgumentException}.
+   */
+  public static NullType asNullType(TypeMirror maybeNullType) {
+    return maybeNullType.accept(NullTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class NullTypeVisitor extends CastingTypeVisitor<NullType> {
+    private static final NullTypeVisitor INSTANCE = new NullTypeVisitor();
+
+    NullTypeVisitor() {
+      super("null");
+    }
+
+    @Override
+    public NullType visitNull(NullType type, Void ignore) {
+      return type;
+    }
+  }
+
+  /**
+   * Returns a {@link PrimitiveType} if the {@link TypeMirror} represents a primitive type or throws
+   * an {@link IllegalArgumentException}.
+   */
+  public static PrimitiveType asPrimitiveType(TypeMirror maybePrimitiveType) {
+    return maybePrimitiveType.accept(PrimitiveTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class PrimitiveTypeVisitor extends CastingTypeVisitor<PrimitiveType> {
+    private static final PrimitiveTypeVisitor INSTANCE = new PrimitiveTypeVisitor();
+
+    PrimitiveTypeVisitor() {
+      super("primitive type");
+    }
+
+    @Override
+    public PrimitiveType visitPrimitive(PrimitiveType type, Void ignore) {
+      return type;
+    }
+  }
+
+  //
+  // visitUnionType would go here, but isn't relevant for annotation processors
+  //
+
+  /**
+   * Returns a {@link TypeVariable} if the {@link TypeMirror} represents a type variable or throws
+   * an {@link IllegalArgumentException}.
+   */
+  public static TypeVariable asTypeVariable(TypeMirror maybeTypeVariable) {
+    return maybeTypeVariable.accept(TypeVariableVisitor.INSTANCE, null);
+  }
+
+  private static final class TypeVariableVisitor extends CastingTypeVisitor<TypeVariable> {
+    private static final TypeVariableVisitor INSTANCE = new TypeVariableVisitor();
+
+    TypeVariableVisitor() {
+      super("type variable");
+    }
+
+    @Override
+    public TypeVariable visitTypeVariable(TypeVariable type, Void ignore) {
+      return type;
+    }
+  }
+
+  /**
+   * Returns a {@link WildcardType} if the {@link TypeMirror} represents a wildcard type or throws
+   * an {@link IllegalArgumentException}.
+   */
+  public static WildcardType asWildcard(TypeMirror maybeWildcardType) {
+    return maybeWildcardType.accept(WildcardTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class WildcardTypeVisitor extends CastingTypeVisitor<WildcardType> {
+    private static final WildcardTypeVisitor INSTANCE = new WildcardTypeVisitor();
+
+    WildcardTypeVisitor() {
+      super("wildcard type");
+    }
+
+    @Override
+    public WildcardType visitWildcard(WildcardType type, Void ignore) {
+      return type;
+    }
+  }
+
+  /**
+   * Returns true if the raw type underlying the given {@link TypeMirror} represents a type that can
+   * be referenced by a {@link Class}. If this returns true, then {@link #isTypeOf} is guaranteed to
+   * not throw.
+   */
+  public static boolean isType(TypeMirror type) {
+    return type.accept(IsTypeVisitor.INSTANCE, null);
+  }
+
+  private static final class IsTypeVisitor extends SimpleTypeVisitor8<Boolean, Void> {
+    private static final IsTypeVisitor INSTANCE = new IsTypeVisitor();
+
+    @Override
+    protected Boolean defaultAction(TypeMirror type, Void ignored) {
+      return false;
+    }
+
+    @Override
+    public Boolean visitNoType(NoType noType, Void p) {
+      return noType.getKind().equals(TypeKind.VOID);
+    }
+
+    @Override
+    public Boolean visitPrimitive(PrimitiveType type, Void p) {
+      return true;
+    }
+
+    @Override
+    public Boolean visitArray(ArrayType array, Void p) {
+      return true;
+    }
+
+    @Override
+    public Boolean visitDeclared(DeclaredType type, Void ignored) {
+      return MoreElements.isType(type.asElement());
+    }
+  }
+
+  /**
+   * Returns true if the raw type underlying the given {@link TypeMirror} represents the same raw
+   * type as the given {@link Class} and throws an IllegalArgumentException if the {@link
+   * TypeMirror} does not represent a type that can be referenced by a {@link Class}
+   */
+  public static boolean isTypeOf(final Class<?> clazz, TypeMirror type) {
+    checkNotNull(clazz);
+    return type.accept(new IsTypeOf(clazz), null);
+  }
+
+  private static final class IsTypeOf extends SimpleTypeVisitor8<Boolean, Void> {
+    private final Class<?> clazz;
+
+    IsTypeOf(Class<?> clazz) {
+      this.clazz = clazz;
+    }
+
+    @Override
+    protected Boolean defaultAction(TypeMirror type, Void ignored) {
+      throw new IllegalArgumentException(type + " cannot be represented as a Class<?>.");
+    }
+
+    @Override
+    public Boolean visitNoType(NoType noType, Void p) {
+      if (noType.getKind().equals(TypeKind.VOID)) {
+        return clazz.equals(Void.TYPE);
+      }
+      throw new IllegalArgumentException(noType + " cannot be represented as a Class<?>.");
+    }
+
+    @Override
+    public Boolean visitPrimitive(PrimitiveType type, Void p) {
+      switch (type.getKind()) {
+        case BOOLEAN:
+          return clazz.equals(Boolean.TYPE);
+        case BYTE:
+          return clazz.equals(Byte.TYPE);
+        case CHAR:
+          return clazz.equals(Character.TYPE);
+        case DOUBLE:
+          return clazz.equals(Double.TYPE);
+        case FLOAT:
+          return clazz.equals(Float.TYPE);
+        case INT:
+          return clazz.equals(Integer.TYPE);
+        case LONG:
+          return clazz.equals(Long.TYPE);
+        case SHORT:
+          return clazz.equals(Short.TYPE);
+        default:
+          throw new IllegalArgumentException(type + " cannot be represented as a Class<?>.");
+      }
+    }
+
+    @Override
+    public Boolean visitArray(ArrayType array, Void p) {
+      return clazz.isArray() && isTypeOf(clazz.getComponentType(), array.getComponentType());
+    }
+
+    @Override
+    public Boolean visitDeclared(DeclaredType type, Void ignored) {
+      TypeElement typeElement = MoreElements.asType(type.asElement());
+      return typeElement.getQualifiedName().contentEquals(clazz.getCanonicalName());
+    }
+  }
+
+  /**
+   * Returns the superclass of {@code type}, with any type parameters bound by {@code type}, or
+   * {@link Optional#absent()} if {@code type} is an interface or {@link Object} or its superclass
+   * is {@link Object}.
+   */
+  // TODO(user): Remove unused parameter Elements?
+  public static Optional<DeclaredType> nonObjectSuperclass(Types types, Elements elements,
+      DeclaredType type) {
+    checkNotNull(types);
+    checkNotNull(elements);  // This is no longer used, but here to avoid changing the API.
+    checkNotNull(type);
+
+    TypeMirror superclassType = asTypeElement(type).getSuperclass();
+    if (!isType(superclassType)) { // type is Object or an interface
+      return Optional.absent();
+    }
+
+    DeclaredType superclass =  asDeclared(superclassType);
+    if (isObjectType(superclass)) {
+      return Optional.absent();
+    }
+
+    if (superclass.getTypeArguments().isEmpty()) {
+      return Optional.of(superclass);
+    }
+
+    // In the case where the super class has type parameters, TypeElement#getSuperclass gives
+    // SuperClass<T> rather than SuperClass<Foo>, so use Types#directSupertypes instead. The javadoc
+    // for Types#directSupertypes guarantees that a super class, if it exists, comes before any
+    // interfaces. Thus, we can just get the first element in the list.
+    return Optional.of(asDeclared(types.directSupertypes(type).get(0)));
+  }
+
+  private static boolean isObjectType(DeclaredType type) {
+    return asTypeElement(type).getQualifiedName().contentEquals("java.lang.Object");
+  }
+
+  /**
+   * Resolves a {@link VariableElement} parameter to a method or constructor based on the given
+   * container, or a member of a class. For parameters to a method or constructor, the variable's
+   * enclosing element must be a supertype of the container type. For example, given a
+   * {@code container} of type {@code Set<String>}, and a variable corresponding to the {@code E e}
+   * parameter in the {@code Set.add(E e)} method, this will return a TypeMirror for {@code String}.
+   */
+  public static TypeMirror asMemberOf(Types types, DeclaredType container,
+      VariableElement variable) {
+    if (variable.getKind().equals(ElementKind.PARAMETER)) {
+      ExecutableElement methodOrConstructor =
+          MoreElements.asExecutable(variable.getEnclosingElement());
+      ExecutableType resolvedMethodOrConstructor =
+          MoreTypes.asExecutable(types.asMemberOf(container, methodOrConstructor));
+      List<? extends VariableElement> parameters = methodOrConstructor.getParameters();
+      List<? extends TypeMirror> parameterTypes = resolvedMethodOrConstructor.getParameterTypes();
+      checkState(parameters.size() == parameterTypes.size());
+      for (int i = 0; i < parameters.size(); i++) {
+        // We need to capture the parameter type of the variable we're concerned about,
+        // for later printing.  This is the only way to do it since we can't use
+        // types.asMemberOf on variables of methods.
+        if (parameters.get(i).equals(variable)) {
+          return parameterTypes.get(i);
+        }
+      }
+      throw new IllegalStateException("Could not find variable: " + variable);
+    } else {
+      return types.asMemberOf(container, variable);
+    }
+  }
+
+  private abstract static class CastingTypeVisitor<T> extends SimpleTypeVisitor8<T, Void> {
+    private final String label;
+
+    CastingTypeVisitor(String label) {
+      this.label = label;
+    }
+
+    @Override
+    protected T defaultAction(TypeMirror e, Void v) {
+      throw new IllegalArgumentException(e + " does not represent a " + label);
+    }
+  }
+
+  /**
+   * Returns true if casting {@code Object} to the given type will elicit an unchecked warning from
+   * the compiler. Only type variables and parameterized types such as {@code List<String>} produce
+   * such warnings. There will be no warning if the type's only type parameters are simple
+   * wildcards, as in {@code Map<?, ?>}.
+   */
+  public static boolean isConversionFromObjectUnchecked(TypeMirror type) {
+    return new CastingUncheckedVisitor().visit(type, null);
+  }
+
+  /**
+   * Visitor that tells whether a type is erased, in the sense of {@link #castIsUnchecked}. Each
+   * visitX method returns true if its input parameter is true or if the type being visited is
+   * erased.
+   */
+  private static class CastingUncheckedVisitor extends SimpleTypeVisitor8<Boolean, Void> {
+    CastingUncheckedVisitor() {
+      super(false);
+    }
+
+    @Override
+    public Boolean visitUnknown(TypeMirror t, Void p) {
+      // We don't know whether casting is unchecked for this mysterious type but assume it is,
+      // so we will insert a possibly unnecessary @SuppressWarnings("unchecked").
+      return true;
+    }
+
+    @Override
+    public Boolean visitArray(ArrayType t, Void p) {
+      return visit(t.getComponentType(), p);
+    }
+
+    @Override
+    public Boolean visitDeclared(DeclaredType t, Void p) {
+      return t.getTypeArguments().stream().anyMatch(CastingUncheckedVisitor::uncheckedTypeArgument);
+    }
+
+    @Override
+    public Boolean visitTypeVariable(TypeVariable t, Void p) {
+      return true;
+    }
+
+    // If a type has a type argument, then casting to the type is unchecked, except if the argument
+    // is <?> or <? extends Object>. The same applies to all type arguments, so casting to Map<?, ?>
+    // does not produce an unchecked warning for example.
+    private static boolean uncheckedTypeArgument(TypeMirror arg) {
+      if (arg.getKind().equals(TypeKind.WILDCARD)) {
+        WildcardType wildcard = asWildcard(arg);
+        if (wildcard.getExtendsBound() == null || isJavaLangObject(wildcard.getExtendsBound())) {
+          // This is <?>, unless there's a super bound, in which case it is <? super Foo> and
+          // is erased.
+          return (wildcard.getSuperBound() != null);
+        }
+      }
+      return true;
+    }
+
+    private static boolean isJavaLangObject(TypeMirror type) {
+      if (type.getKind() != TypeKind.DECLARED) {
+        return false;
+      }
+      TypeElement typeElement = asTypeElement(type);
+      return typeElement.getQualifiedName().contentEquals("java.lang.Object");
+    }
+  }
+
+  private MoreTypes() {}
+}
diff --git a/common/src/main/java/com/google/auto/common/Overrides.java b/common/src/main/java/com/google/auto/common/Overrides.java
new file mode 100644
index 0000000..19a4586
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/Overrides.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Verify;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.util.List;
+import java.util.Map;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor8;
+import javax.lang.model.util.Types;
+
+/**
+ * Determines if one method overrides another. This class defines two ways of doing that:
+ * {@code NativeOverrides} uses the method
+ * {@link Elements#overrides(ExecutableElement, ExecutableElement, TypeElement)} while
+ * {@code ExplicitOverrides} reimplements that method in a way that is more consistent between
+ * compilers, in particular between javac and ecj (the Eclipse compiler).
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+abstract class Overrides {
+  abstract boolean overrides(
+      ExecutableElement overrider, ExecutableElement overridden, TypeElement in);
+
+  static class NativeOverrides extends Overrides {
+    private final Elements elementUtils;
+
+    NativeOverrides(Elements elementUtils) {
+      this.elementUtils = elementUtils;
+    }
+
+    @Override
+    boolean overrides(ExecutableElement overrider, ExecutableElement overridden, TypeElement in) {
+      return elementUtils.overrides(overrider, overridden, in);
+    }
+  }
+
+  static class ExplicitOverrides extends Overrides {
+    private final Types typeUtils;
+
+    ExplicitOverrides(Types typeUtils) {
+      this.typeUtils = typeUtils;
+    }
+
+    @Override
+    public boolean overrides(
+        ExecutableElement overrider, ExecutableElement overridden, TypeElement in) {
+      if (!overrider.getSimpleName().equals(overridden.getSimpleName())) {
+        // They must have the same name.
+        return false;
+      }
+      // We should just be able to write overrider.equals(overridden) here, but that runs afoul
+      // of a problem with Eclipse. If for example you look at the method Stream<E> stream() in
+      // Collection<E>, as obtained by collectionTypeElement.getEnclosedElements(), it will not
+      // compare equal to the method Stream<E> stream() as obtained by
+      // elementUtils.getAllMembers(listTypeElement), even though List<E> inherits the method
+      // from Collection<E>. The reason is that, in ecj, getAllMembers does type substitution,
+      // so the return type of stream() is Stream<E'>, where E' is the E from List<E> rather than
+      // the one from Collection<E>. Instead we compare the enclosing element, which will be
+      // Collection<E> no matter how we got the method. If two methods are in the same type
+      // then it's impossible for one to override the other, regardless of whether they are the
+      // same method.
+      if (overrider.getEnclosingElement().equals(overridden.getEnclosingElement())) {
+        return false;
+      }
+      if (overridden.getModifiers().contains(Modifier.STATIC)) {
+        // Static methods can't be overridden (though they can be hidden by other static methods).
+        return false;
+      }
+      Visibility overriddenVisibility = Visibility.ofElement(overridden);
+      Visibility overriderVisibility = Visibility.ofElement(overrider);
+      if (overriddenVisibility.equals(Visibility.PRIVATE)
+          || overriderVisibility.compareTo(overriddenVisibility) < 0) {
+        // Private methods can't be overridden, and methods can't be overridden by less-visible
+        // methods. The latter condition is enforced by the compiler so in theory we might report
+        // an "incorrect" result here for code that javac would not have allowed.
+        return false;
+      }
+      if (!isSubsignature(overrider, overridden, in)) {
+        return false;
+      }
+      if (!MoreElements.methodVisibleFromPackage(overridden, MoreElements.getPackage(overrider))) {
+        // If the overridden method is a package-private method in a different package then it
+        // can't be overridden.
+        return false;
+      }
+      TypeElement overriddenType;
+      if (!(overridden.getEnclosingElement() instanceof TypeElement)) {
+        return false;
+        // We don't know how this could happen but we avoid blowing up if it does.
+      }
+      overriddenType = MoreElements.asType(overridden.getEnclosingElement());
+      // We erase the types before checking subtypes, because the TypeMirror we get for List<E> is
+      // not a subtype of the one we get for Collection<E> since the two E instances are not the
+      // same. For the purposes of overriding, type parameters in the containing type should not
+      // matter because if the code compiles at all then they must be consistent.
+      if (!typeUtils.isSubtype(
+          typeUtils.erasure(in.asType()), typeUtils.erasure(overriddenType.asType()))) {
+        return false;
+      }
+      if (in.getKind().isClass()) {
+        // Method mC in or inherited by class C (JLS 8.4.8.1)...
+        if (overriddenType.getKind().isClass()) {
+          // ...overrides from C another method mA declared in class A. The only condition we
+          // haven't checked is that C does not inherit mA. Ideally we could just write this:
+          //    return !elementUtils.getAllMembers(in).contains(overridden);
+          // But that doesn't work in Eclipse. For example, getAllMembers(AbstractList)
+          // contains List.isEmpty() where you might reasonably expect it to contain
+          // AbstractCollection.isEmpty(). So we need to visit superclasses until we reach
+          // one that declares the same method, and check that we haven't reached mA. We compare
+          // the enclosing elements rather than the methods themselves for the reason described
+          // at the start of the method.
+          ExecutableElement inherited = methodFromSuperclasses(in, overridden);
+          return !overridden.getEnclosingElement().equals(inherited.getEnclosingElement());
+        } else if (overriddenType.getKind().isInterface()) {
+          // ...overrides from C another method mI declared in interface I. We've already checked
+          // the conditions (assuming that the only alternative to mI being abstract or default is
+          // mI being static, which we eliminated above). However, it appears that the logic here
+          // is necessary in order to be compatible with javac's `overrides` method. An inherited
+          // abstract method does not override another method. (But, if it is not inherited,
+          // it does, including if `in` inherits a concrete method of the same name from its
+          // superclass.) Here again we can use getAllMembers with javac but not with ecj. javac
+          // says that getAllMembers(AbstractList) contains both AbstractCollection.size() and
+          // List.size(), but ecj doesn't have the latter. The spec is not particularly clear so
+          // either seems justifiable. So we need to look up the interface path that goes from `in`
+          // to `overriddenType` (or the several paths if there are several) and apply similar logic
+          // to methodFromSuperclasses above.
+          if (overrider.getModifiers().contains(Modifier.ABSTRACT)) {
+            ExecutableElement inherited = methodFromSuperinterfaces(in, overridden);
+            return !overridden.getEnclosingElement().equals(inherited.getEnclosingElement());
+          } else {
+            return true;
+          }
+        } else {
+          // We don't know what this is so say no.
+          return false;
+        }
+      } else {
+        return in.getKind().isInterface();
+        // Method mI in or inherited by interface I (JLS 9.4.1.1). We've already checked everything.
+        // If this is not an interface then we don't know what it is so we say no.
+      }
+    }
+
+    private boolean isSubsignature(
+        ExecutableElement overrider, ExecutableElement overridden, TypeElement in) {
+      DeclaredType inType = MoreTypes.asDeclared(in.asType());
+      try {
+        ExecutableType overriderExecutable =
+            MoreTypes.asExecutable(typeUtils.asMemberOf(inType, overrider));
+        ExecutableType overriddenExecutable =
+            MoreTypes.asExecutable(typeUtils.asMemberOf(inType, overridden));
+        return typeUtils.isSubsignature(overriderExecutable, overriddenExecutable);
+      } catch (IllegalArgumentException e) {
+        // This might mean that at least one of the methods is not in fact declared in or inherited
+        // by `in` (in which case we should indeed return false); or it might mean that we are
+        // tickling an Eclipse bug such as https://bugs.eclipse.org/bugs/show_bug.cgi?id=499026
+        // (in which case we fall back on explicit code to find the parameters).
+        int nParams = overrider.getParameters().size();
+        if (overridden.getParameters().size() != nParams) {
+          return false;
+        }
+        List<TypeMirror> overriderParams = erasedParameterTypes(overrider, in);
+        List<TypeMirror> overriddenParams = erasedParameterTypes(overridden, in);
+        if (overriderParams == null || overriddenParams == null) {
+          // This probably means that one or other of the methods is not in `in`.
+          return false;
+        }
+        for (int i = 0; i < nParams; i++) {
+          if (!typeUtils.isSameType(overriderParams.get(i), overriddenParams.get(i))) {
+            // If the erasures of the parameters don't correspond, return false. We erase so we
+            // don't get any confusion about different type variables not comparing equal.
+            return false;
+          }
+        }
+        return true;
+      }
+    }
+
+    /**
+     * Returns the list of erased parameter types of the given method as they appear in the given
+     * type. For example, if the method is {@code add(E)} from {@code List<E>} and we ask how it
+     * appears in {@code class NumberList implements List<Number>}, the answer will be
+     * {@code Number}. That will also be the answer for {@code class NumberList<E extends Number>
+     * implements List<E>}. The parameter types are erased since the purpose of this method is to
+     * determine whether two methods are candidates for one to override the other.
+     */
+    ImmutableList<TypeMirror> erasedParameterTypes(ExecutableElement method, TypeElement in) {
+      if (method.getParameters().isEmpty()) {
+        return ImmutableList.of();
+      }
+      return new TypeSubstVisitor().erasedParameterTypes(method, in);
+    }
+
+    /**
+     * Visitor that replaces type variables with their values in the types it sees. If we know
+     * that {@code E} is {@code String}, then we can return {@code String} for {@code E},
+     * {@code List<String>} for {@code List<E>}, {@code String[]} for {@code E[]}, etc. We don't
+     * have to cover all types here because (1) the type is going to end up being erased, and
+     * (2) wildcards can't appear in direct supertypes. So for example it is illegal to write
+     * {@code class MyList implements List<? extends Number>}. It's legal to write
+     * {@code class MyList implements List<Set<? extends Number>>} but that doesn't matter
+     * because the {@code E} of the {@code List} is going to be erased to raw {@code Set}.
+     */
+    private class TypeSubstVisitor extends SimpleTypeVisitor8<TypeMirror, Void> {
+      /**
+       * The bindings of type variables. We can put them all in one map because E in {@code List<E>}
+       * is not the same as E in {@code Collection<E>}. As we ascend the type hierarchy we'll add
+       * mappings for all the variables we see. We could equivalently create a new map for each type
+       * we visit, but this is slightly simpler and probably about as performant.
+       */
+      private final Map<TypeParameterElement, TypeMirror> typeBindings = Maps.newLinkedHashMap();
+
+      ImmutableList<TypeMirror> erasedParameterTypes(ExecutableElement method, TypeElement in) {
+        if (method.getEnclosingElement().equals(in)) {
+          ImmutableList.Builder<TypeMirror> params = ImmutableList.builder();
+          for (VariableElement param : method.getParameters()) {
+            params.add(typeUtils.erasure(visit(param.asType())));
+          }
+          return params.build();
+        }
+        // Make a list of supertypes we are going to visit recursively: the superclass, if there
+        // is one, plus the superinterfaces.
+        List<TypeMirror> supers = Lists.newArrayList();
+        if (in.getSuperclass().getKind() == TypeKind.DECLARED) {
+          supers.add(in.getSuperclass());
+        }
+        supers.addAll(in.getInterfaces());
+        for (TypeMirror supertype : supers) {
+          DeclaredType declared = MoreTypes.asDeclared(supertype);
+          TypeElement element = MoreElements.asType(declared.asElement());
+          List<? extends TypeMirror> actuals = declared.getTypeArguments();
+          List<? extends TypeParameterElement> formals = element.getTypeParameters();
+          Verify.verify(actuals.size() == formals.size());
+          for (int i = 0; i < actuals.size(); i++) {
+            typeBindings.put(formals.get(i), actuals.get(i));
+          }
+          ImmutableList<TypeMirror> params = erasedParameterTypes(method, element);
+          if (params != null) {
+            return params;
+          }
+        }
+        return null;
+      }
+
+      @Override
+      protected TypeMirror defaultAction(TypeMirror e, Void p) {
+        return e;
+      }
+
+      @Override
+      public TypeMirror visitTypeVariable(TypeVariable t, Void p) {
+        Element element = typeUtils.asElement(t);
+        if (element instanceof TypeParameterElement) {
+          TypeParameterElement e = (TypeParameterElement) element;
+          if (typeBindings.containsKey(e)) {
+            return visit(typeBindings.get(e));
+          }
+        }
+        // We erase the upper bound to avoid infinite recursion. We can get away with erasure for
+        // the reasons described above.
+        return visit(typeUtils.erasure(t.getUpperBound()));
+      }
+
+      @Override
+      public TypeMirror visitDeclared(DeclaredType t, Void p) {
+        if (t.getTypeArguments().isEmpty()) {
+          return t;
+        }
+        List<TypeMirror> newArgs = Lists.newArrayList();
+        for (TypeMirror arg : t.getTypeArguments()) {
+          newArgs.add(visit(arg));
+        }
+        return typeUtils.getDeclaredType(asTypeElement(t), newArgs.toArray(new TypeMirror[0]));
+      }
+
+      @Override
+      public TypeMirror visitArray(ArrayType t, Void p) {
+        return typeUtils.getArrayType(visit(t.getComponentType()));
+      }
+    }
+
+    /**
+     * Returns the given method as it appears in the given type. This is the method itself,
+     * or the nearest override in a superclass of the given type, or null if the method is not
+     * found in the given type or any of its superclasses.
+     */
+    ExecutableElement methodFromSuperclasses(TypeElement in, ExecutableElement method) {
+      for (TypeElement t = in; t != null; t = superclass(t)) {
+        ExecutableElement tMethod = methodInType(t, method);
+        if (tMethod != null) {
+          return tMethod;
+        }
+      }
+      return null;
+    }
+
+    /**
+     * Returns the given interface method as it appears in the given type. This is the method
+     * itself, or the nearest override in a superinterface of the given type, or null if the method
+     * is not found in the given type or any of its transitive superinterfaces.
+     */
+    ExecutableElement methodFromSuperinterfaces(TypeElement in, ExecutableElement method) {
+      TypeElement methodContainer = MoreElements.asType(method.getEnclosingElement());
+      Preconditions.checkArgument(methodContainer.getKind().isInterface());
+      TypeMirror methodContainerType = typeUtils.erasure(methodContainer.asType());
+      ImmutableList<TypeElement> types = ImmutableList.of(in);
+      // On the first pass through this loop, `types` is the type we're starting from,
+      // which might be a class or an interface. On later passes it is a list of direct
+      // superinterfaces we saw in the previous pass, but only the ones that were assignable
+      // to the interface that `method` appears in.
+      while (!types.isEmpty()) {
+        ImmutableList.Builder<TypeElement> newTypes = ImmutableList.builder();
+        for (TypeElement t : types) {
+          TypeMirror candidateType = typeUtils.erasure(t.asType());
+          if (typeUtils.isAssignable(candidateType, methodContainerType)) {
+            ExecutableElement tMethod = methodInType(t, method);
+            if (tMethod != null) {
+              return tMethod;
+            }
+            newTypes.addAll(superinterfaces(t));
+          }
+          if (t.getKind().isClass()) {
+            TypeElement sup = superclass(t);
+            if (sup != null) {
+              newTypes.add(sup);
+            }
+          }
+        }
+        types = newTypes.build();
+      }
+      return null;
+    }
+
+    /**
+     * Returns the method from within the given type that has the same erased signature as the given
+     * method, or null if there is no such method.
+     */
+    private ExecutableElement methodInType(TypeElement type, ExecutableElement method) {
+      int nParams = method.getParameters().size();
+      List<TypeMirror> params = erasedParameterTypes(method, type);
+      if (params == null) {
+        return null;
+      }
+      methods:
+      for (ExecutableElement tMethod : ElementFilter.methodsIn(type.getEnclosedElements())) {
+        if (tMethod.getSimpleName().equals(method.getSimpleName())
+            && tMethod.getParameters().size() == nParams) {
+          for (int i = 0; i < nParams; i++) {
+            TypeMirror tParamType = typeUtils.erasure(tMethod.getParameters().get(i).asType());
+            if (!typeUtils.isSameType(params.get(i), tParamType)) {
+              continue methods;
+            }
+          }
+          return tMethod;
+        }
+      }
+      return null;
+    }
+
+    private TypeElement superclass(TypeElement type) {
+      TypeMirror sup = type.getSuperclass();
+      if (sup.getKind() == TypeKind.DECLARED) {
+        return MoreElements.asType(typeUtils.asElement(sup));
+      } else {
+        return null;
+      }
+    }
+
+    private ImmutableList<TypeElement> superinterfaces(TypeElement type) {
+      ImmutableList.Builder<TypeElement> types = ImmutableList.builder();
+      for (TypeMirror sup : type.getInterfaces()) {
+        types.add(MoreElements.asType(typeUtils.asElement(sup)));
+      }
+      return types.build();
+    }
+
+    private TypeElement asTypeElement(TypeMirror typeMirror) {
+      DeclaredType declaredType = MoreTypes.asDeclared(typeMirror);
+      Element element = declaredType.asElement();
+      return MoreElements.asType(element);
+    }
+  }
+}
diff --git a/common/src/main/java/com/google/auto/common/SimpleAnnotationMirror.java b/common/src/main/java/com/google/auto/common/SimpleAnnotationMirror.java
new file mode 100644
index 0000000..7d508e3
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/SimpleAnnotationMirror.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableMap.toImmutableMap;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableMap;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+
+/**
+ * A simple implementation of the {@link AnnotationMirror} interface.
+ *
+ * <p>This type implements {@link #equals(Object)} and {@link #hashCode()} using {@link
+ * AnnotationMirrors#equivalence} in accordance with the {@link AnnotationMirror} spec. Some {@link
+ * AnnotationMirror}s, however, do not correctly implement equals, you should always compare them
+ * using {@link AnnotationMirrors#equivalence} anyway.
+ */
+public final class SimpleAnnotationMirror implements AnnotationMirror {
+  private final TypeElement annotationType;
+  private final ImmutableMap<String, ? extends AnnotationValue> namedValues;
+  private final ImmutableMap<ExecutableElement, ? extends AnnotationValue> elementValues;
+
+  private SimpleAnnotationMirror(
+      TypeElement annotationType, Map<String, ? extends AnnotationValue> namedValues) {
+    checkArgument(
+        annotationType.getKind().equals(ElementKind.ANNOTATION_TYPE),
+        "annotationType must be an annotation: %s",
+        annotationType);
+    Map<String, AnnotationValue> values = new LinkedHashMap<>();
+    Map<String, AnnotationValue> unusedValues = new LinkedHashMap<>(namedValues);
+    List<String> missingMembers = new ArrayList<>();
+    for (ExecutableElement method : methodsIn(annotationType.getEnclosedElements())) {
+      String memberName = method.getSimpleName().toString();
+      if (unusedValues.containsKey(memberName)) {
+        values.put(memberName, unusedValues.remove(memberName));
+      } else if (method.getDefaultValue() != null) {
+        values.put(memberName, method.getDefaultValue());
+      } else {
+        missingMembers.add(memberName);
+      }
+    }
+    
+    checkArgument(
+        unusedValues.isEmpty(),
+        "namedValues has entries for members that are not in %s: %s",
+        annotationType,
+        unusedValues);
+    checkArgument(
+        missingMembers.isEmpty(), "namedValues is missing entries for: %s", missingMembers);
+
+    this.annotationType = annotationType;
+    this.namedValues = ImmutableMap.copyOf(namedValues);
+    this.elementValues =
+        methodsIn(annotationType.getEnclosedElements())
+            .stream()
+            .collect(toImmutableMap(e -> e, e -> values.get(e.getSimpleName().toString())));
+  }
+
+  /**
+   * An object representing an {@linkplain ElementKind#ANNOTATION_TYPE annotation} instance. If
+   * {@code annotationType} has any annotation members, they must have default values.
+   */
+  public static AnnotationMirror of(TypeElement annotationType) {
+    return of(annotationType, ImmutableMap.of());
+  }
+
+  /**
+   * An object representing an {@linkplain ElementKind#ANNOTATION_TYPE annotation} instance. If
+   * {@code annotationType} has any annotation members, they must either be present in {@code
+   * namedValues} or have default values.
+   */
+  public static AnnotationMirror of(
+      TypeElement annotationType, Map<String, ? extends AnnotationValue> namedValues) {
+    return new SimpleAnnotationMirror(annotationType, namedValues);
+  }
+
+  @Override
+  public DeclaredType getAnnotationType() {
+    return MoreTypes.asDeclared(annotationType.asType());
+  }
+
+  @Override
+  public Map<ExecutableElement, ? extends AnnotationValue> getElementValues() {
+    return elementValues;
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder builder = new StringBuilder("@").append(annotationType.getQualifiedName());
+    if (!namedValues.isEmpty()) {
+      builder
+          .append('(')
+          .append(Joiner.on(", ").withKeyValueSeparator(" = ").join(namedValues))
+          .append(')');
+    }
+    return builder.toString();
+  }
+
+  @Override
+  public boolean equals(Object other) {
+    return other instanceof AnnotationMirror
+        && AnnotationMirrors.equivalence().equivalent(this, (AnnotationMirror) other);
+  }
+
+  @Override
+  public int hashCode() {
+    return AnnotationMirrors.equivalence().hash(this);
+  }
+}
diff --git a/common/src/main/java/com/google/auto/common/SimpleTypeAnnotationValue.java b/common/src/main/java/com/google/auto/common/SimpleTypeAnnotationValue.java
new file mode 100644
index 0000000..a281011
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/SimpleTypeAnnotationValue.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static javax.lang.model.type.TypeKind.ARRAY;
+import static javax.lang.model.type.TypeKind.DECLARED;
+
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.AnnotationValueVisitor;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A simple implementation of the {@link AnnotationValue} interface for a class literal, e.g. an
+ * annotation member of type {@code Class<?>} or {@code Class<? extends Foo>}.
+ */
+public final class SimpleTypeAnnotationValue implements AnnotationValue {
+  private final TypeMirror value;
+
+  private SimpleTypeAnnotationValue(TypeMirror value) {
+    checkArgument(
+        value.getKind().isPrimitive()
+            || value.getKind().equals(DECLARED)
+            || value.getKind().equals(ARRAY),
+        "value must be a primitive, array, or declared type, but was %s (%s)",
+        value.getKind(),
+        value);
+    if (value.getKind().equals(DECLARED)) {
+      checkArgument(
+          MoreTypes.asDeclared(value).getTypeArguments().isEmpty(),
+          "value must not be a parameterized type: %s",
+          value);
+    }
+    this.value = value;
+  }
+
+  /**
+   * An object representing an annotation value instance.
+   *
+   * @param value a primitive, array, or non-parameterized declared type
+   */
+  public static AnnotationValue of(TypeMirror value) {
+    return new SimpleTypeAnnotationValue(value);
+  }
+
+  @Override
+  public TypeMirror getValue() {
+    return value;
+  }
+
+  @Override
+  public String toString() {
+    return value + ".class";
+  }
+
+  @Override
+  public <R, P> R accept(AnnotationValueVisitor<R, P> visitor, P parameter) {
+    return visitor.visitType(getValue(), parameter);
+  }
+}
diff --git a/common/src/main/java/com/google/auto/common/SuperficialValidation.java b/common/src/main/java/com/google/auto/common/SuperficialValidation.java
new file mode 100644
index 0000000..dddb1be
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/SuperficialValidation.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import java.util.List;
+import java.util.Map;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.AnnotationValueVisitor;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementVisitor;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ErrorType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVisitor;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.AbstractElementVisitor8;
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+import javax.lang.model.util.SimpleTypeVisitor8;
+
+/**
+ * A utility class that traverses {@link Element} instances and ensures that all type information
+ * is present and resolvable.
+ *
+ * @author Gregory Kick
+ */
+public final class SuperficialValidation {
+  public static boolean validateElements(Iterable<? extends Element> elements) {
+    for (Element element : elements) {
+      if (!validateElement(element)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private static final ElementVisitor<Boolean, Void> ELEMENT_VALIDATING_VISITOR =
+      new AbstractElementVisitor8<Boolean, Void>() {
+        @Override public Boolean visitPackage(PackageElement e, Void p) {
+          // don't validate enclosed elements because it will return types in the package
+          return validateAnnotations(e.getAnnotationMirrors());
+        }
+
+        @Override public Boolean visitType(TypeElement e, Void p) {
+          return isValidBaseElement(e)
+              && validateElements(e.getTypeParameters())
+              && validateTypes(e.getInterfaces())
+              && validateType(e.getSuperclass());
+        }
+
+        @Override public Boolean visitVariable(VariableElement e, Void p) {
+          return isValidBaseElement(e);
+        }
+
+        @Override public Boolean visitExecutable(ExecutableElement e, Void p) {
+          AnnotationValue defaultValue = e.getDefaultValue();
+          return isValidBaseElement(e)
+              && (defaultValue == null || validateAnnotationValue(defaultValue, e.getReturnType()))
+              && validateType(e.getReturnType())
+              && validateTypes(e.getThrownTypes())
+              && validateElements(e.getTypeParameters())
+              && validateElements(e.getParameters());
+        }
+
+        @Override public Boolean visitTypeParameter(TypeParameterElement e, Void p) {
+          return isValidBaseElement(e)
+              && validateTypes(e.getBounds());
+        }
+
+        @Override public Boolean visitUnknown(Element e, Void p) {
+          // just assume that unknown elements are OK
+          return true;
+        }
+      };
+
+  public static boolean validateElement(Element element) {
+    return element.accept(ELEMENT_VALIDATING_VISITOR, null);
+  }
+
+  private static boolean isValidBaseElement(Element e) {
+    return validateType(e.asType())
+        && validateAnnotations(e.getAnnotationMirrors())
+        && validateElements(e.getEnclosedElements());
+  }
+
+  private static boolean validateTypes(Iterable<? extends TypeMirror> types) {
+    for (TypeMirror type : types) {
+      if (!validateType(type)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /*
+   * This visitor does not test type variables specifically, but it seems that that is not actually
+   * an issue.  Javac turns the whole type parameter into an error type if it can't figure out the
+   * bounds.
+   */
+  private static final TypeVisitor<Boolean, Void> TYPE_VALIDATING_VISITOR =
+      new SimpleTypeVisitor8<Boolean, Void>() {
+        @Override
+        protected Boolean defaultAction(TypeMirror t, Void p) {
+          return true;
+        }
+
+        @Override
+        public Boolean visitArray(ArrayType t, Void p) {
+          return validateType(t.getComponentType());
+        }
+
+        @Override
+        public Boolean visitDeclared(DeclaredType t, Void p) {
+          return validateTypes(t.getTypeArguments());
+        }
+
+        @Override
+        public Boolean visitError(ErrorType t, Void p) {
+          return false;
+        }
+
+        @Override
+        public Boolean visitUnknown(TypeMirror t, Void p) {
+          // just make the default choice for unknown types
+          return defaultAction(t, p);
+        }
+
+        @Override
+        public Boolean visitWildcard(WildcardType t, Void p) {
+          TypeMirror extendsBound = t.getExtendsBound();
+          TypeMirror superBound = t.getSuperBound();
+          return (extendsBound == null || validateType(extendsBound))
+              && (superBound == null || validateType(superBound));
+        }
+
+        @Override
+        public Boolean visitExecutable(ExecutableType t, Void p) {
+          return validateTypes(t.getParameterTypes())
+              && validateType(t.getReturnType())
+              && validateTypes(t.getThrownTypes())
+              && validateTypes(t.getTypeVariables());
+        }
+      };
+
+  private static boolean validateType(TypeMirror type) {
+    return type.accept(TYPE_VALIDATING_VISITOR, null);
+  }
+
+  private static boolean validateAnnotations(
+      Iterable<? extends AnnotationMirror> annotationMirrors) {
+    for (AnnotationMirror annotationMirror : annotationMirrors) {
+      if (!validateAnnotation(annotationMirror)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private static boolean validateAnnotation(AnnotationMirror annotationMirror) {
+    return validateType(annotationMirror.getAnnotationType())
+        && validateAnnotationValues(annotationMirror.getElementValues());
+  }
+
+  @SuppressWarnings("unused")
+  private static boolean validateAnnotationValues(
+      Map<? extends ExecutableElement, ? extends AnnotationValue> valueMap) {
+    for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> valueEntry :
+        valueMap.entrySet()) {
+      TypeMirror expectedType = valueEntry.getKey().getReturnType();
+      if (!validateAnnotationValue(valueEntry.getValue(), expectedType)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private static final AnnotationValueVisitor<Boolean, TypeMirror> VALUE_VALIDATING_VISITOR =
+      new SimpleAnnotationValueVisitor8<Boolean, TypeMirror>() {
+        @Override protected Boolean defaultAction(Object o, TypeMirror expectedType) {
+          return MoreTypes.isTypeOf(o.getClass(), expectedType);
+        }
+
+        @Override public Boolean visitUnknown(AnnotationValue av, TypeMirror expectedType) {
+          // just take the default action for the unknown
+          return defaultAction(av, expectedType);
+        }
+
+        @Override public Boolean visitAnnotation(AnnotationMirror a, TypeMirror expectedType) {
+          return MoreTypes.equivalence().equivalent(a.getAnnotationType(), expectedType)
+              && validateAnnotation(a);
+        }
+
+        @Override
+        public Boolean visitArray(List<? extends AnnotationValue> values, TypeMirror expectedType) {
+          if (!expectedType.getKind().equals(TypeKind.ARRAY)) {
+            return false;
+          }
+          try {
+            expectedType = MoreTypes.asArray(expectedType).getComponentType();
+          } catch (IllegalArgumentException e) {
+            return false; // Not an array expected, ergo invalid.
+          }
+          for (AnnotationValue value : values) {
+            if (!value.accept(this, expectedType)) {
+              return false;
+            }
+          }
+          return true;
+        }
+
+        @Override
+        public Boolean visitEnumConstant(VariableElement enumConstant, TypeMirror expectedType) {
+          return MoreTypes.equivalence().equivalent(enumConstant.asType(), expectedType)
+              && validateElement(enumConstant);
+        }
+
+        @Override public Boolean visitType(TypeMirror type, TypeMirror ignored) {
+          // We could check assignability here, but would require a Types instance. Since this
+          // isn't really the sort of thing that shows up in a bad AST from upstream compilation
+          // we ignore the expected type and just validate the type.  It might be wrong, but
+          // it's valid.
+          return validateType(type);
+        }
+
+        @Override public Boolean visitBoolean(boolean b, TypeMirror expectedType) {
+          return MoreTypes.isTypeOf(Boolean.TYPE, expectedType);
+        }
+
+        @Override public Boolean visitByte(byte b, TypeMirror expectedType) {
+          return MoreTypes.isTypeOf(Byte.TYPE, expectedType);
+        }
+
+        @Override public Boolean visitChar(char c, TypeMirror expectedType) {
+          return MoreTypes.isTypeOf(Character.TYPE, expectedType);
+        }
+
+        @Override public Boolean visitDouble(double d, TypeMirror expectedType) {
+          return MoreTypes.isTypeOf(Double.TYPE, expectedType);
+        }
+
+        @Override public Boolean visitFloat(float f, TypeMirror expectedType) {
+          return MoreTypes.isTypeOf(Float.TYPE, expectedType);
+        }
+
+        @Override public Boolean visitInt(int i, TypeMirror expectedType) {
+          return MoreTypes.isTypeOf(Integer.TYPE, expectedType);
+        }
+
+        @Override public Boolean visitLong(long l, TypeMirror expectedType) {
+          return MoreTypes.isTypeOf(Long.TYPE, expectedType);
+        }
+
+        @Override public Boolean visitShort(short s, TypeMirror expectedType) {
+          return MoreTypes.isTypeOf(Short.TYPE, expectedType);
+        }
+      };
+
+  private static boolean validateAnnotationValue(
+      AnnotationValue annotationValue, TypeMirror expectedType) {
+    return annotationValue.accept(VALUE_VALIDATING_VISITOR, expectedType);
+  }
+}
diff --git a/common/src/main/java/com/google/auto/common/Visibility.java b/common/src/main/java/com/google/auto/common/Visibility.java
new file mode 100644
index 0000000..f82fdd5
--- /dev/null
+++ b/common/src/main/java/com/google/auto/common/Visibility.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.lang.model.element.ElementKind.PACKAGE;
+
+import com.google.common.base.Enums;
+import com.google.common.collect.Ordering;
+import java.util.Set;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+
+/**
+ * Represents the visibility of a given {@link Element}: {@code public}, {@code protected},
+ * {@code private} or default/package-private.
+ *
+ * <p>The constants for this enum are ordered according by increasing visibility.
+ *
+ * @author Gregory Kick
+ */
+public enum Visibility {
+  PRIVATE,
+  DEFAULT,
+  PROTECTED,
+  PUBLIC;
+
+  // TODO(ronshapiro): remove this and reference ElementKind.MODULE directly once we start building
+  // with -source 9
+  private static final ElementKind MODULE =
+      Enums.getIfPresent(ElementKind.class, "MODULE").orNull();
+
+  /**
+   * Returns the visibility of the given {@link Element}. While package and module elements don't
+   * technically have a visibility associated with them, this method returns {@link #PUBLIC} for
+   * them.
+   */
+  public static Visibility ofElement(Element element) {
+    checkNotNull(element);
+    // packages and module don't have modifiers, but they're obviously "public"
+    if (element.getKind().equals(PACKAGE) || element.getKind().equals(MODULE)) {
+      return PUBLIC;
+    }
+    Set<Modifier> modifiers = element.getModifiers();
+    if (modifiers.contains(Modifier.PRIVATE)) {
+      return PRIVATE;
+    } else if (modifiers.contains(Modifier.PROTECTED)) {
+      return PROTECTED;
+    } else if (modifiers.contains(Modifier.PUBLIC)) {
+      return PUBLIC;
+    } else {
+      return DEFAULT;
+    }
+  }
+
+  /**
+   * Returns effective visibility of the given element meaning that it takes into account the
+   * visibility of its enclosing elements.
+   */
+  public static Visibility effectiveVisibilityOfElement(Element element) {
+    checkNotNull(element);
+    Visibility effectiveVisibility = PUBLIC;
+    Element currentElement = element;
+    while (currentElement != null) {
+      effectiveVisibility =
+          Ordering.natural().min(effectiveVisibility, ofElement(currentElement));
+      currentElement = currentElement.getEnclosingElement();
+    }
+    return effectiveVisibility;
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/AnnotationMirrorsTest.java b/common/src/test/java/com/google/auto/common/AnnotationMirrorsTest.java
new file mode 100644
index 0000000..dfc043a
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/AnnotationMirrorsTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.BLAH;
+import static com.google.auto.common.AnnotationMirrorsTest.SimpleEnum.FOO;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.common.testing.EquivalenceTester;
+import com.google.testing.compile.CompilationRule;
+import java.util.Map;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleAnnotationValueVisitor6;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests {@link AnnotationMirrors}.
+ */
+@RunWith(JUnit4.class)
+public class AnnotationMirrorsTest {
+  @Rule public CompilationRule compilationRule = new CompilationRule();
+
+  private Elements elements;
+
+  @Before public void setUp() {
+    this.elements = compilationRule.getElements();
+  }
+
+  @interface SimpleAnnotation {}
+
+  @SimpleAnnotation class SimplyAnnotated {}
+  @SimpleAnnotation class AlsoSimplyAnnotated {}
+
+  enum SimpleEnum {
+    BLAH, FOO
+  }
+
+  @interface Outer {
+    SimpleEnum value();
+  }
+
+  @Outer(BLAH) static class TestClassBlah {}
+  @Outer(BLAH) static class TestClassBlah2 {}
+  @Outer(FOO) static class TestClassFoo {}
+
+  @interface DefaultingOuter {
+    SimpleEnum value() default SimpleEnum.BLAH;
+  }
+
+  @DefaultingOuter class TestWithDefaultingOuterDefault {}
+  @DefaultingOuter(BLAH) class TestWithDefaultingOuterBlah {}
+  @DefaultingOuter(FOO) class TestWithDefaultingOuterFoo {}
+
+  @interface AnnotatedOuter {
+    DefaultingOuter value();
+  }
+
+  @AnnotatedOuter(@DefaultingOuter) class TestDefaultNestedAnnotated {}
+  @AnnotatedOuter(@DefaultingOuter(BLAH)) class TestBlahNestedAnnotated {}
+  @AnnotatedOuter(@DefaultingOuter(FOO)) class TestFooNestedAnnotated {}
+
+  @interface OuterWithValueArray {
+    DefaultingOuter[] value() default {};
+  }
+
+  @OuterWithValueArray class TestValueArrayWithDefault {}
+  @OuterWithValueArray({}) class TestValueArrayWithEmpty {}
+
+  @OuterWithValueArray({@DefaultingOuter}) class TestValueArrayWithOneDefault {}
+  @OuterWithValueArray(@DefaultingOuter(BLAH)) class TestValueArrayWithOneBlah {}
+  @OuterWithValueArray(@DefaultingOuter(FOO)) class TestValueArrayWithOneFoo {}
+
+  @OuterWithValueArray({@DefaultingOuter(FOO), @DefaultingOuter})
+  class TestValueArrayWithFooAndDefaultBlah {}
+  @OuterWithValueArray({@DefaultingOuter(FOO), @DefaultingOuter(BLAH)})
+  class TestValueArrayWithFooBlah {}
+  @OuterWithValueArray({@DefaultingOuter(FOO), @DefaultingOuter(BLAH)})
+  class TestValueArrayWithFooBlah2 {} // Different instances than on TestValueArrayWithFooBlah.
+  @OuterWithValueArray({@DefaultingOuter(BLAH), @DefaultingOuter(FOO)})
+  class TestValueArrayWithBlahFoo {}
+
+  @Test public void testEquivalences() {
+    EquivalenceTester<AnnotationMirror> tester =
+        EquivalenceTester.of(AnnotationMirrors.equivalence());
+
+    tester.addEquivalenceGroup(
+        annotationOn(SimplyAnnotated.class),
+        annotationOn(AlsoSimplyAnnotated.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestClassBlah.class),
+        annotationOn(TestClassBlah2.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestClassFoo.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestWithDefaultingOuterDefault.class),
+        annotationOn(TestWithDefaultingOuterBlah.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestWithDefaultingOuterFoo.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestDefaultNestedAnnotated.class),
+        annotationOn(TestBlahNestedAnnotated.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestFooNestedAnnotated.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestValueArrayWithDefault.class),
+        annotationOn(TestValueArrayWithEmpty.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestValueArrayWithOneDefault.class),
+        annotationOn(TestValueArrayWithOneBlah.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestValueArrayWithOneFoo.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestValueArrayWithFooAndDefaultBlah.class),
+        annotationOn(TestValueArrayWithFooBlah.class),
+        annotationOn(TestValueArrayWithFooBlah2.class));
+
+    tester.addEquivalenceGroup(
+        annotationOn(TestValueArrayWithBlahFoo.class));
+
+    tester.test();
+  }
+
+  @interface Stringy {
+    String value() default "default";
+  }
+
+  @Stringy class StringyUnset {}
+  @Stringy("foo") class StringySet {}
+
+  @Test public void testGetDefaultValuesUnset() {
+    assertThat(annotationOn(StringyUnset.class).getElementValues()).isEmpty();
+    Iterable<AnnotationValue> values = AnnotationMirrors.getAnnotationValuesWithDefaults(
+        annotationOn(StringyUnset.class)).values();
+    String value = getOnlyElement(values).accept(new SimpleAnnotationValueVisitor6<String, Void>() {
+          @Override public String visitString(String value, Void ignored) {
+            return value;
+          }
+        }, null);
+    assertThat(value).isEqualTo("default");
+  }
+
+  @Test public void testGetDefaultValuesSet() {
+    Iterable<AnnotationValue> values = AnnotationMirrors.getAnnotationValuesWithDefaults(
+        annotationOn(StringySet.class)).values();
+    String value = getOnlyElement(values).accept(new SimpleAnnotationValueVisitor6<String, Void>() {
+          @Override public String visitString(String value, Void ignored) {
+            return value;
+          }
+        }, null);
+    assertThat(value).isEqualTo("foo");
+  }
+
+  @Test public void testGetValueEntry() {
+    Map.Entry<ExecutableElement, AnnotationValue> elementValue =
+        AnnotationMirrors.getAnnotationElementAndValue(
+            annotationOn(TestClassBlah.class), "value");
+    assertThat(elementValue.getKey().getSimpleName().toString()).isEqualTo("value");
+    assertThat(elementValue.getValue().getValue()).isInstanceOf(VariableElement.class);
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(
+        annotationOn(TestClassBlah.class), "value");
+    assertThat(value.getValue()).isInstanceOf(VariableElement.class);
+  }
+
+  @Test public void testGetValueEntryFailure() {
+    try {
+      AnnotationMirrors.getAnnotationValue(annotationOn(TestClassBlah.class), "a");
+    } catch (IllegalArgumentException e) {
+      assertThat(e)
+          .hasMessageThat()
+          .isEqualTo(
+              "@com.google.auto.common.AnnotationMirrorsTest.Outer does not define an element a()");
+      return;
+    }
+    fail("Should have thrown.");
+  }
+
+  private AnnotationMirror annotationOn(Class<?> clazz) {
+    return getOnlyElement(elements.getTypeElement(clazz.getCanonicalName()).getAnnotationMirrors());
+  }
+
+}
diff --git a/common/src/test/java/com/google/auto/common/AnnotationValuesTest.java b/common/src/test/java/com/google/auto/common/AnnotationValuesTest.java
new file mode 100644
index 0000000..825c85a
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/AnnotationValuesTest.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.truth.Correspondence;
+import com.google.testing.compile.CompilationRule;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests {@link AnnotationValues}. */
+@RunWith(JUnit4.class)
+public final class AnnotationValuesTest {
+
+  private @interface InsideAnnotation {
+    int value();
+  }
+
+  private static class GenericClass<T> {}
+
+  private static class InsideClassA {}
+
+  private static class InsideClassB {}
+
+  private @interface MultiValueAnnotation {
+    Class<InsideClassA> classValue();
+
+    Class<?>[] classValues();
+
+    Class<?> genericClassValue();
+
+    InsideAnnotation insideAnnotationValue();
+
+    InsideAnnotation[] insideAnnotationValues();
+
+    String stringValue();
+
+    String[] stringValues();
+
+    Foo enumValue();
+
+    Foo[] enumValues();
+
+    int intValue();
+
+    int[] intValues();
+
+    long longValue();
+
+    long[] longValues();
+
+    byte byteValue();
+
+    byte[] byteValues();
+
+    short shortValue();
+
+    short[] shortValues();
+
+    float floatValue();
+
+    float[] floatValues();
+
+    double doubleValue();
+
+    double[] doubleValues();
+
+    boolean booleanValue();
+
+    boolean[] booleanValues();
+
+    char charValue();
+
+    char[] charValues();
+  }
+
+  private enum Foo {
+    BAR,
+    BAZ,
+    BAH;
+  }
+
+  @MultiValueAnnotation(
+      classValue = InsideClassA.class,
+      classValues = {InsideClassA.class, InsideClassB.class},
+      genericClassValue = GenericClass.class,
+      insideAnnotationValue = @InsideAnnotation(19),
+      insideAnnotationValues = {@InsideAnnotation(20), @InsideAnnotation(21)},
+      stringValue = "hello",
+      stringValues = {"it's", "me"},
+      enumValue = Foo.BAR,
+      enumValues = {Foo.BAZ, Foo.BAH},
+      intValue = 5,
+      intValues = {1, 2},
+      longValue = 6L,
+      longValues = {3L, 4L},
+      byteValue = (byte) 7,
+      byteValues = {(byte) 8, (byte) 9},
+      shortValue = (short) 10,
+      shortValues = {(short) 11, (short) 12},
+      floatValue = 13F,
+      floatValues = {14F, 15F},
+      doubleValue = 16D,
+      doubleValues = {17D, 18D},
+      booleanValue = true,
+      booleanValues = {true, false},
+      charValue = 'a',
+      charValues = {'b', 'c'})
+  private static class AnnotatedClass {}
+
+  @Rule public final CompilationRule compilation = new CompilationRule();
+
+  private Elements elements;
+  private Types types;
+  private AnnotationMirror annotationMirror;
+
+  @Before
+  public void setUp() {
+    elements = compilation.getElements();
+    types = compilation.getTypes();
+    TypeElement annotatedClass = getTypeElement(AnnotatedClass.class);
+    annotationMirror =
+        MoreElements.getAnnotationMirror(annotatedClass, MultiValueAnnotation.class).get();
+  }
+
+  @Test
+  public void getTypeMirror() {
+    TypeElement insideClassA = getTypeElement(InsideClassA.class);
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "classValue");
+    assertThat(AnnotationValues.getTypeMirror(value).asElement()).isEqualTo(insideClassA);
+  }
+
+  @Test
+  public void getTypeMirrorGenericClass() {
+    TypeElement genericClass = getTypeElement(GenericClass.class);
+    AnnotationValue gvalue =
+        AnnotationMirrors.getAnnotationValue(annotationMirror, "genericClassValue");
+    assertThat(AnnotationValues.getTypeMirror(gvalue).asElement()).isEqualTo(genericClass);
+  }
+
+  @Test
+  public void getTypeMirrors() {
+    TypeMirror insideClassA = getTypeElement(InsideClassA.class).asType();
+    TypeMirror insideClassB = getTypeElement(InsideClassB.class).asType();
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "classValues");
+    ImmutableList<DeclaredType> valueElements = AnnotationValues.getTypeMirrors(value);
+    assertThat(valueElements)
+        .comparingElementsUsing(Correspondence.from(types::isSameType, "has Same Type"))
+        .containsExactly(insideClassA, insideClassB)
+        .inOrder();
+  }
+
+  @Test
+  public void getAnnotationMirror() {
+    TypeElement insideAnnotation = getTypeElement(InsideAnnotation.class);
+    AnnotationValue value =
+        AnnotationMirrors.getAnnotationValue(annotationMirror, "insideAnnotationValue");
+    AnnotationMirror annotationMirror = AnnotationValues.getAnnotationMirror(value);
+    assertThat(annotationMirror.getAnnotationType().asElement()).isEqualTo(insideAnnotation);
+    assertThat(AnnotationMirrors.getAnnotationValue(annotationMirror, "value").getValue())
+        .isEqualTo(19);
+  }
+
+  @Test
+  public void getAnnotationMirrors() {
+    TypeElement insideAnnotation = getTypeElement(InsideAnnotation.class);
+    AnnotationValue value =
+        AnnotationMirrors.getAnnotationValue(annotationMirror, "insideAnnotationValues");
+    ImmutableList<AnnotationMirror> annotationMirrors =
+        AnnotationValues.getAnnotationMirrors(value);
+    ImmutableList<Element> valueElements =
+        annotationMirrors.stream()
+            .map(AnnotationMirror::getAnnotationType)
+            .map(DeclaredType::asElement)
+            .collect(toImmutableList());
+    assertThat(valueElements).containsExactly(insideAnnotation, insideAnnotation);
+    ImmutableList<Object> valuesStoredInAnnotation =
+        annotationMirrors.stream()
+            .map(
+                annotationMirror ->
+                    AnnotationMirrors.getAnnotationValue(annotationMirror, "value").getValue())
+            .collect(toImmutableList());
+    assertThat(valuesStoredInAnnotation).containsExactly(20, 21).inOrder();
+  }
+
+  @Test
+  public void getString() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "stringValue");
+    assertThat(AnnotationValues.getString(value)).isEqualTo("hello");
+  }
+
+  @Test
+  public void getStrings() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "stringValues");
+    assertThat(AnnotationValues.getStrings(value)).containsExactly("it's", "me").inOrder();
+  }
+
+  @Test
+  public void getEnum() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "enumValue");
+    assertThat(AnnotationValues.getEnum(value)).isEqualTo(value.getValue());
+  }
+
+  @Test
+  public void getEnums() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "enumValues");
+    assertThat(getEnumNames(AnnotationValues.getEnums(value)))
+        .containsExactly(Foo.BAZ.name(), Foo.BAH.name())
+        .inOrder();
+  }
+
+  @Test
+  public void getAnnotationValues() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "intValues");
+    ImmutableList<AnnotationValue> values = AnnotationValues.getAnnotationValues(value);
+    assertThat(values)
+        .comparingElementsUsing(Correspondence.transforming(AnnotationValue::getValue, "has value"))
+        .containsExactly(1, 2)
+        .inOrder();
+  }
+
+  @Test
+  public void getInt() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "intValue");
+    assertThat(AnnotationValues.getInt(value)).isEqualTo(5);
+  }
+
+  @Test
+  public void getInts() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "intValues");
+    assertThat(AnnotationValues.getInts(value)).containsExactly(1, 2).inOrder();
+  }
+
+  @Test
+  public void getLong() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "longValue");
+    assertThat(AnnotationValues.getLong(value)).isEqualTo(6L);
+  }
+
+  @Test
+  public void getLongs() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "longValues");
+    assertThat(AnnotationValues.getLongs(value)).containsExactly(3L, 4L).inOrder();
+  }
+
+  @Test
+  public void getByte() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "byteValue");
+    assertThat(AnnotationValues.getByte(value)).isEqualTo((byte) 7);
+  }
+
+  @Test
+  public void getBytes() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "byteValues");
+    assertThat(AnnotationValues.getBytes(value)).containsExactly((byte) 8, (byte) 9).inOrder();
+  }
+
+  @Test
+  public void getShort() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "shortValue");
+    assertThat(AnnotationValues.getShort(value)).isEqualTo((short) 10);
+  }
+
+  @Test
+  public void getShorts() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "shortValues");
+    assertThat(AnnotationValues.getShorts(value)).containsExactly((short) 11, (short) 12).inOrder();
+  }
+
+  @Test
+  public void getFloat() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "floatValue");
+    assertThat(AnnotationValues.getFloat(value)).isEqualTo(13F);
+  }
+
+  @Test
+  public void getFloats() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "floatValues");
+    assertThat(AnnotationValues.getFloats(value)).containsExactly(14F, 15F).inOrder();
+  }
+
+  @Test
+  public void getDouble() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "doubleValue");
+    assertThat(AnnotationValues.getDouble(value)).isEqualTo(16D);
+  }
+
+  @Test
+  public void getDoubles() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "doubleValues");
+    assertThat(AnnotationValues.getDoubles(value)).containsExactly(17D, 18D).inOrder();
+  }
+
+  @Test
+  public void getBoolean() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "booleanValue");
+    assertThat(AnnotationValues.getBoolean(value)).isTrue();
+  }
+
+  @Test
+  public void getBooleans() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "booleanValues");
+    assertThat(AnnotationValues.getBooleans(value)).containsExactly(true, false).inOrder();
+  }
+
+  @Test
+  public void getChar() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "charValue");
+    assertThat(AnnotationValues.getChar(value)).isEqualTo('a');
+  }
+
+  @Test
+  public void getChars() {
+    AnnotationValue value = AnnotationMirrors.getAnnotationValue(annotationMirror, "charValues");
+    assertThat(AnnotationValues.getChars(value)).containsExactly('b', 'c').inOrder();
+  }
+
+  private TypeElement getTypeElement(Class<?> clazz) {
+    return elements.getTypeElement(clazz.getCanonicalName());
+  }
+
+  private static ImmutableList<String> getEnumNames(ImmutableList<VariableElement> values) {
+    return values.stream()
+        .map(VariableElement::getSimpleName)
+        .map(Name::toString)
+        .collect(toImmutableList());
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/BasicAnnotationProcessorTest.java b/common/src/test/java/com/google/auto/common/BasicAnnotationProcessorTest.java
new file mode 100644
index 0000000..59a135c
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/BasicAnnotationProcessorTest.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.collect.Multimaps.transformValues;
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static javax.tools.Diagnostic.Kind.ERROR;
+import static javax.tools.StandardLocation.SOURCE_OUTPUT;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.SetMultimap;
+import com.google.common.truth.Correspondence;
+import com.google.testing.compile.JavaFileObjects;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Set;
+import javax.annotation.processing.Filer;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class BasicAnnotationProcessorTest {
+
+  @Retention(RetentionPolicy.SOURCE)
+  public @interface RequiresGeneratedCode {}
+
+  /**
+   * Rejects elements unless the class generated by {@link GeneratesCode}'s processor is present.
+   */
+  private static final class RequiresGeneratedCodeProcessor extends BasicAnnotationProcessor {
+
+    int rejectedRounds;
+    final ImmutableList.Builder<ImmutableSetMultimap<Class<? extends Annotation>, Element>>
+        processArguments = ImmutableList.builder();
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latestSupported();
+    }
+
+    @Override
+    protected Iterable<? extends ProcessingStep> initSteps() {
+      return ImmutableSet.of(
+          new ProcessingStep() {
+            @Override
+            public Set<Element> process(
+                SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+              processArguments.add(ImmutableSetMultimap.copyOf(elementsByAnnotation));
+              TypeElement requiredClass =
+                  processingEnv.getElementUtils().getTypeElement("test.SomeGeneratedClass");
+              if (requiredClass == null) {
+                rejectedRounds++;
+                return ImmutableSet.copyOf(elementsByAnnotation.values());
+              }
+              generateClass(processingEnv.getFiler(), "GeneratedByRequiresGeneratedCodeProcessor");
+              return ImmutableSet.of();
+            }
+
+            @Override
+            public Set<? extends Class<? extends Annotation>> annotations() {
+              return ImmutableSet.of(RequiresGeneratedCode.class);
+            }
+          },
+          new ProcessingStep() {
+            @Override
+            public Set<? extends Class<? extends Annotation>> annotations() {
+              return ImmutableSet.of(AnAnnotation.class);
+            }
+
+            @Override
+            public Set<? extends Element> process(
+                SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+              return ImmutableSet.of();
+            }
+          });
+    }
+
+    ImmutableList<ImmutableSetMultimap<Class<? extends Annotation>, Element>> processArguments() {
+      return processArguments.build();
+    }
+  }
+
+  @Retention(RetentionPolicy.SOURCE)
+  public @interface GeneratesCode {}
+
+  /** Generates a class called {@code test.SomeGeneratedClass}. */
+  public class GeneratesCodeProcessor extends BasicAnnotationProcessor {
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latestSupported();
+    }
+
+    @Override
+    protected Iterable<? extends ProcessingStep> initSteps() {
+      return ImmutableSet.of(
+          new ProcessingStep() {
+            @Override
+            public Set<Element> process(
+                SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+              generateClass(processingEnv.getFiler(), "SomeGeneratedClass");
+              return ImmutableSet.of();
+            }
+
+            @Override
+            public Set<? extends Class<? extends Annotation>> annotations() {
+              return ImmutableSet.of(GeneratesCode.class);
+            }
+          });
+    }
+  }
+
+  public @interface AnAnnotation {}
+
+  /** When annotating a type {@code Foo}, generates a class called {@code FooXYZ}. */
+  public class AnAnnotationProcessor extends BasicAnnotationProcessor {
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latestSupported();
+    }
+
+    @Override
+    protected Iterable<? extends ProcessingStep> initSteps() {
+      return ImmutableSet.of(
+          new ProcessingStep() {
+            @Override
+            public Set<Element> process(
+                SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+              for (Element element : elementsByAnnotation.values()) {
+                generateClass(processingEnv.getFiler(), element.getSimpleName() + "XYZ");
+              }
+              return ImmutableSet.of();
+            }
+
+            @Override
+            public Set<? extends Class<? extends Annotation>> annotations() {
+              return ImmutableSet.of(AnAnnotation.class);
+            }
+          });
+    }
+  }
+
+  /** An annotation which causes an annotation processing error. */
+  public @interface CauseError {}
+
+  /** Report an error for any class annotated. */
+  public static class CauseErrorProcessor extends BasicAnnotationProcessor {
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latestSupported();
+    }
+
+    @Override
+    protected Iterable<? extends ProcessingStep> initSteps() {
+      return ImmutableSet.of(
+          new ProcessingStep() {
+            @Override
+            public Set<Element> process(
+                SetMultimap<Class<? extends Annotation>, Element> elementsByAnnotation) {
+              for (Element e : elementsByAnnotation.values()) {
+                processingEnv.getMessager().printMessage(ERROR, "purposeful error", e);
+              }
+              return ImmutableSet.copyOf(elementsByAnnotation.values());
+            }
+
+            @Override
+            public Set<? extends Class<? extends Annotation>> annotations() {
+              return ImmutableSet.of(CauseError.class);
+            }
+          });
+    }
+  }
+
+  @Test public void properlyDefersProcessing_typeElement() {
+    JavaFileObject classAFileObject = JavaFileObjects.forSourceLines("test.ClassA",
+        "package test;",
+        "",
+        "@" + RequiresGeneratedCode.class.getCanonicalName(),
+        "public class ClassA {",
+        "  SomeGeneratedClass sgc;",
+        "}");
+    JavaFileObject classBFileObject = JavaFileObjects.forSourceLines("test.ClassB",
+        "package test;",
+        "",
+        "@" + GeneratesCode.class.getCanonicalName(),
+        "public class ClassB {}");
+    RequiresGeneratedCodeProcessor requiresGeneratedCodeProcessor =
+        new RequiresGeneratedCodeProcessor();
+    assertAbout(javaSources())
+        .that(ImmutableList.of(classAFileObject, classBFileObject))
+        .processedWith(requiresGeneratedCodeProcessor, new GeneratesCodeProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesFileNamed(
+            SOURCE_OUTPUT, "test", "GeneratedByRequiresGeneratedCodeProcessor.java");
+    assertThat(requiresGeneratedCodeProcessor.rejectedRounds).isEqualTo(0);
+  }
+
+  @Test
+  public void properlyDefersProcessing_nestedTypeValidBeforeOuterType() {
+    JavaFileObject source =
+        JavaFileObjects.forSourceLines(
+            "test.ValidInRound2",
+            "package test;",
+            "",
+            "@" + AnAnnotation.class.getCanonicalName(),
+            "public class ValidInRound2 {",
+            "  ValidInRound1XYZ vir1xyz;",
+            "  @" + AnAnnotation.class.getCanonicalName(),
+            "  static class ValidInRound1 {}",
+            "}");
+    assertAbout(javaSource())
+        .that(source)
+        .processedWith(new AnAnnotationProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesFileNamed(SOURCE_OUTPUT, "test", "ValidInRound2XYZ.java");
+  }
+
+  @Retention(RetentionPolicy.SOURCE)
+  public @interface ReferencesAClass {
+    Class<?> value();
+  }
+
+  @Test public void properlyDefersProcessing_packageElement() {
+    JavaFileObject classAFileObject = JavaFileObjects.forSourceLines("test.ClassA",
+        "package test;",
+        "",
+        "@" + GeneratesCode.class.getCanonicalName(),
+        "public class ClassA {",
+        "}");
+    JavaFileObject packageFileObject = JavaFileObjects.forSourceLines("test.package-info",
+        "@" + RequiresGeneratedCode.class.getCanonicalName(),
+        "@" + ReferencesAClass.class.getCanonicalName() + "(SomeGeneratedClass.class)",
+        "package test;");
+    RequiresGeneratedCodeProcessor requiresGeneratedCodeProcessor =
+        new RequiresGeneratedCodeProcessor();
+    assertAbout(javaSources())
+        .that(ImmutableList.of(classAFileObject, packageFileObject))
+        .processedWith(requiresGeneratedCodeProcessor, new GeneratesCodeProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesFileNamed(
+            SOURCE_OUTPUT, "test", "GeneratedByRequiresGeneratedCodeProcessor.java");
+    assertThat(requiresGeneratedCodeProcessor.rejectedRounds).isEqualTo(0);
+  }
+
+  @Test public void properlyDefersProcessing_argumentElement() {
+    JavaFileObject classAFileObject = JavaFileObjects.forSourceLines("test.ClassA",
+        "package test;",
+        "",
+        "public class ClassA {",
+        "  SomeGeneratedClass sgc;",
+        "  public void myMethod(@" + RequiresGeneratedCode.class.getCanonicalName() + " int myInt)",
+        "  {}",
+        "}");
+    JavaFileObject classBFileObject = JavaFileObjects.forSourceLines("test.ClassB",
+        "package test;",
+        "",
+        "public class ClassB {",
+        "  public void myMethod(@" + GeneratesCode.class.getCanonicalName() + " int myInt) {}",
+        "}");
+    RequiresGeneratedCodeProcessor requiresGeneratedCodeProcessor =
+        new RequiresGeneratedCodeProcessor();
+    assertAbout(javaSources())
+        .that(ImmutableList.of(classAFileObject, classBFileObject))
+        .processedWith(requiresGeneratedCodeProcessor, new GeneratesCodeProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesFileNamed(
+            SOURCE_OUTPUT, "test", "GeneratedByRequiresGeneratedCodeProcessor.java");
+    assertThat(requiresGeneratedCodeProcessor.rejectedRounds).isEqualTo(0);
+  }
+
+  @Test
+  public void properlyDefersProcessing_rejectsElement() {
+    JavaFileObject classAFileObject =
+        JavaFileObjects.forSourceLines(
+            "test.ClassA",
+            "package test;",
+            "",
+            "@" + RequiresGeneratedCode.class.getCanonicalName(),
+            "public class ClassA {",
+            "  @" + AnAnnotation.class.getCanonicalName(),
+            "  public void method() {}",
+            "}");
+    JavaFileObject classBFileObject = JavaFileObjects.forSourceLines("test.ClassB",
+        "package test;",
+        "",
+        "@" + GeneratesCode.class.getCanonicalName(),
+        "public class ClassB {}");
+    RequiresGeneratedCodeProcessor requiresGeneratedCodeProcessor =
+        new RequiresGeneratedCodeProcessor();
+    assertAbout(javaSources())
+        .that(ImmutableList.of(classAFileObject, classBFileObject))
+        .processedWith(requiresGeneratedCodeProcessor, new GeneratesCodeProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesFileNamed(
+            SOURCE_OUTPUT, "test", "GeneratedByRequiresGeneratedCodeProcessor.java");
+    assertThat(requiresGeneratedCodeProcessor.rejectedRounds).isEqualTo(1);
+
+    // Re b/118372780: Assert that the right deferred elements are passed back, and not any enclosed
+    // elements annotated with annotations from a different step.
+    assertThat(requiresGeneratedCodeProcessor.processArguments())
+        .comparingElementsUsing(setMultimapValuesByString())
+        .containsExactly(
+            ImmutableSetMultimap.of(RequiresGeneratedCode.class, "test.ClassA"),
+            ImmutableSetMultimap.of(RequiresGeneratedCode.class, "test.ClassA"))
+        .inOrder();
+  }
+
+  private static <K, V>
+      Correspondence<SetMultimap<K, V>, SetMultimap<K, String>> setMultimapValuesByString() {
+    return Correspondence.from(
+        (actual, expected) ->
+            ImmutableSetMultimap.copyOf(transformValues(actual, Object::toString)).equals(expected),
+        "is equivalent comparing multimap values by `toString()` to");
+  }
+
+  @Test public void reportsMissingType() {
+    JavaFileObject classAFileObject = JavaFileObjects.forSourceLines("test.ClassA",
+        "package test;",
+        "",
+        "@" + RequiresGeneratedCode.class.getCanonicalName(),
+        "public class ClassA {",
+        "  SomeGeneratedClass bar;",
+        "}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(classAFileObject))
+        .processedWith(new RequiresGeneratedCodeProcessor())
+        .failsToCompile()
+        .withErrorContaining(RequiresGeneratedCodeProcessor.class.getCanonicalName())
+        .in(classAFileObject).onLine(4);
+  }
+
+  @Test
+  public void reportsMissingTypeSuppressedWhenOtherErrors() {
+    JavaFileObject classAFileObject =
+        JavaFileObjects.forSourceLines(
+            "test.ClassA",
+            "package test;",
+            "",
+            "@" + CauseError.class.getCanonicalName(),
+            "public class ClassA {}");
+    assertAbout(javaSources())
+        .that(ImmutableList.of(classAFileObject))
+        .processedWith(new CauseErrorProcessor())
+        .failsToCompile()
+        .withErrorCount(1)
+        .withErrorContaining("purposeful");
+  }
+
+  private static void generateClass(Filer filer, String generatedClassName) {
+    PrintWriter writer = null;
+    try {
+      writer = new PrintWriter(filer.createSourceFile("test." + generatedClassName).openWriter());
+      writer.println("package test;");
+      writer.println("public class " + generatedClassName + " {}");
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    } finally {
+      if (writer != null) {
+        writer.close();
+      }
+    }
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/GeneratedAnnotationsTest.java b/common/src/test/java/com/google/auto/common/GeneratedAnnotationsTest.java
new file mode 100644
index 0000000..1c816c1
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/GeneratedAnnotationsTest.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.truth.Truth.assertThat;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.junit.Assume.assumeTrue;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.reflect.Reflection;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.TypeSpec;
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.nio.file.Files;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaCompiler.CompilationTask;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import javax.tools.ToolProvider;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** {@link GeneratedAnnotations}Test */
+@RunWith(JUnit4.class)
+public class GeneratedAnnotationsTest {
+
+  @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+  private static final String JAVAX_ANNOTATION_PROCESSING_GENERATED =
+      "javax.annotation.processing.Generated";
+  private static final String JAVAX_ANNOTATION_GENERATED = "javax.annotation.Generated";
+
+  /**
+   * A toy annotation processor for testing. Matches on all annotations, and unconditionally
+   * generates a source that uses {@code @Generated}.
+   */
+  @SupportedAnnotationTypes("*")
+  public static class TestProcessor extends AbstractProcessor {
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latestSupported();
+    }
+
+    private boolean first = true;
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      if (first) {
+        TypeSpec.Builder type = TypeSpec.classBuilder("G");
+        GeneratedAnnotationSpecs.generatedAnnotationSpec(
+                processingEnv.getElementUtils(),
+                processingEnv.getSourceVersion(),
+                TestProcessor.class)
+            .ifPresent(type::addAnnotation);
+        JavaFile javaFile = JavaFile.builder("", type.build()).build();
+        try {
+          javaFile.writeTo(processingEnv.getFiler());
+        } catch (IOException e) {
+          throw new UncheckedIOException(e);
+        }
+        first = false;
+      }
+      return false;
+    }
+  }
+
+  /**
+   * Run {@link TestProcessor} in a compilation with the given {@code options}, and prevent the
+   * compilation from accessing classes with the qualified names in {@code maskFromClasspath}.
+   */
+  private String runProcessor(ImmutableList<String> options, String packageToMask)
+      throws IOException {
+    File tempDir = temporaryFolder.newFolder();
+    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+    StandardJavaFileManager standardFileManager =
+        compiler.getStandardFileManager(/* diagnostics= */ null, /* locale= */ null, UTF_8);
+    standardFileManager.setLocation(StandardLocation.CLASS_OUTPUT, ImmutableList.of(tempDir));
+    StandardJavaFileManager proxyFileManager =
+        Reflection.newProxy(
+            StandardJavaFileManager.class,
+            new FileManagerInvocationHandler(standardFileManager, packageToMask));
+    CompilationTask task =
+        compiler.getTask(
+            /* out= */ null,
+            proxyFileManager,
+            /* diagnosticListener= */ null,
+            options,
+            /* classes= */ null,
+            ImmutableList.of(
+                new SimpleJavaFileObject(URI.create("test"), Kind.SOURCE) {
+                  @Override
+                  public CharSequence getCharContent(boolean ignoreEncodingErrors)
+                      throws IOException {
+                    return "class Test {}";
+                  }
+                }));
+    task.setProcessors(ImmutableList.of(new TestProcessor()));
+    assertThat(task.call()).isTrue();
+    return new String(Files.readAllBytes(tempDir.toPath().resolve("G.java")), UTF_8);
+  }
+
+  /**
+   * Used to produce a {@link StandardJavaFileManager} where a certain package appears to have
+   * no classes. The results are exactly those from the proxied {@code StandardJavaFileManager}
+   * except for the {@link StandardJavaFileManager#list list} method when its {@code packageName}
+   * argument is the given package, in which case the result is an empty list.
+   *
+   * <p>We can't use {@link javax.tools.ForwardingJavaFileManager} because at least some JDK
+   * versions require the file manager to be a {@code StandardJavaFileManager} when the
+   * {@code --release} flag is given.
+   */
+  private static class FileManagerInvocationHandler implements InvocationHandler {
+    private final StandardJavaFileManager fileManager;
+    private final String packageToMask;
+
+    FileManagerInvocationHandler(StandardJavaFileManager fileManager, String packageToMask) {
+      this.fileManager = fileManager;
+      this.packageToMask = packageToMask;
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+      if (method.getName().equals("list")) {
+        String packageName = (String) args[1];
+        if (packageName.equals(packageToMask)) {
+          return ImmutableList.of();
+        }
+      }
+      return method.invoke(fileManager, args);
+    }
+  }
+
+  @Test
+  public void source8() throws Exception {
+    // Post-JDK8, we need to use --release 8 in order to be able to see the javax.annotation
+    // package, which was deleted from the JDK in that release. On JDK8, there is no --release
+    // option, so we have to use -source 8 -target 8.
+    ImmutableList<String> options =
+        isJdk9OrLater()
+            ? ImmutableList.of("--release", "8")
+            : ImmutableList.of("-source", "8", "-target", "8");
+    String generated = runProcessor(options, null);
+    assertThat(generated).contains(JAVAX_ANNOTATION_GENERATED);
+    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_PROCESSING_GENERATED);
+  }
+
+  @Test
+  public void source8_masked() throws Exception {
+    // It appears that the StandardJavaFileManager hack that removes a package does not work in
+    // conjunction with --release. This is probably a bug. What we find is that
+    // Elements.getTypeElement returns a value for javax.annotation.Generated even though
+    // javax.annotation is being masked. It doesn't seem to go through the StandardJavaFileManager
+    // interface to get it. So, we continue using the -source 8 -target 8 options. Those don't
+    // actually get the JDK8 API when running post-JDK8, so we end up testing what we want.
+    //
+    // An alternative would be to delete this test method. JDK8 always has
+    // javax.annotation.Generated so it isn't really meaningful to test it without.
+    ImmutableList<String> options = ImmutableList.of("-source", "8", "-target", "8");
+    String generated =
+        runProcessor(options, "javax.annotation");
+    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_GENERATED);
+    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_PROCESSING_GENERATED);
+  }
+
+  @Test
+  public void source9() throws Exception {
+    assumeTrue(isJdk9OrLater());
+    String generated = runProcessor(ImmutableList.of("-source", "9", "-target", "9"), null);
+    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_GENERATED);
+    assertThat(generated).contains(JAVAX_ANNOTATION_PROCESSING_GENERATED);
+  }
+
+  @Test
+  public void source9_masked() throws Exception {
+    assumeTrue(isJdk9OrLater());
+    String generated =
+        runProcessor(
+            ImmutableList.of("-source", "9", "-target", "9"), "javax.annotation.processing");
+    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_GENERATED);
+    assertThat(generated).doesNotContain(JAVAX_ANNOTATION_PROCESSING_GENERATED);
+  }
+
+  private static boolean isJdk9OrLater() {
+    return SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0;
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/MoreElementsTest.java b/common/src/test/java/com/google/auto/common/MoreElementsTest.java
new file mode 100644
index 0000000..95043cf
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/MoreElementsTest.java
@@ -0,0 +1,475 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import com.google.common.truth.Expect;
+import com.google.testing.compile.CompilationRule;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.AbstractList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class MoreElementsTest {
+  @Rule public CompilationRule compilation = new CompilationRule();
+  @Rule public Expect expect = Expect.create();
+
+  private PackageElement javaLangPackageElement;
+  private TypeElement objectElement;
+  private TypeElement stringElement;
+
+  @Before
+  public void initializeTestElements() {
+    Elements elements = compilation.getElements();
+    this.javaLangPackageElement = elements.getPackageElement("java.lang");
+    this.objectElement = elements.getTypeElement(Object.class.getCanonicalName());
+    this.stringElement = elements.getTypeElement(String.class.getCanonicalName());
+  }
+
+  @Test
+  public void getPackage() {
+    assertThat(MoreElements.getPackage(stringElement)).isEqualTo(javaLangPackageElement);
+    for (Element childElement : stringElement.getEnclosedElements()) {
+      assertThat(MoreElements.getPackage(childElement)).isEqualTo(javaLangPackageElement);
+    }
+  }
+
+  @Test
+  public void asPackage() {
+    assertThat(MoreElements.asPackage(javaLangPackageElement))
+        .isEqualTo(javaLangPackageElement);
+  }
+
+  @Test
+  public void asPackage_illegalArgument() {
+    try {
+      MoreElements.asPackage(stringElement);
+      fail();
+    } catch (IllegalArgumentException expected) {}
+  }
+
+  @Test public void asTypeElement() {
+    Element typeElement =
+        compilation.getElements().getTypeElement(String.class.getCanonicalName());
+    assertTrue(MoreElements.isType(typeElement));
+    assertThat(MoreElements.asType(typeElement)).isEqualTo(typeElement);
+  }
+
+  @Test public void asTypeElement_notATypeElement() {
+    TypeElement typeElement =
+        compilation.getElements().getTypeElement(String.class.getCanonicalName());
+    for (ExecutableElement e : ElementFilter.methodsIn(typeElement.getEnclosedElements())) {
+      assertFalse(MoreElements.isType(e));
+      try {
+        MoreElements.asType(e);
+        fail();
+      } catch (IllegalArgumentException expected) {
+      }
+    }
+  }
+
+  @Test
+  public void asTypeParameterElement() {
+    Element typeParameterElement =
+        getOnlyElement(
+            compilation
+                .getElements()
+                .getTypeElement(List.class.getCanonicalName())
+                .getTypeParameters());
+    assertThat(MoreElements.asTypeParameter(typeParameterElement)).isEqualTo(typeParameterElement);
+  }
+
+  @Test
+  public void asTypeParameterElement_illegalArgument() {
+    try {
+      MoreElements.asTypeParameter(javaLangPackageElement);
+      fail();
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  @Test
+  public void asType() {
+    assertThat(MoreElements.asType(stringElement)).isEqualTo(stringElement);
+  }
+
+  @Test
+  public void asType_illegalArgument() {
+    assertFalse(MoreElements.isType(javaLangPackageElement));
+    try {
+      MoreElements.asType(javaLangPackageElement);
+      fail();
+    } catch (IllegalArgumentException expected) {}
+  }
+
+  @Test
+  public void asVariable() {
+    for (Element variableElement : ElementFilter.fieldsIn(stringElement.getEnclosedElements())) {
+      assertThat(MoreElements.asVariable(variableElement)).isEqualTo(variableElement);
+    }
+  }
+
+  @Test
+  public void asVariable_illegalArgument() {
+    try {
+      MoreElements.asVariable(javaLangPackageElement);
+      fail();
+    } catch (IllegalArgumentException expected) {}
+  }
+
+  @Test
+  public void asExecutable() {
+    for (Element methodElement : ElementFilter.methodsIn(stringElement.getEnclosedElements())) {
+      assertThat(MoreElements.asExecutable(methodElement)).isEqualTo(methodElement);
+    }
+    for (Element methodElement
+        : ElementFilter.constructorsIn(stringElement.getEnclosedElements())) {
+      assertThat(MoreElements.asExecutable(methodElement)).isEqualTo(methodElement);
+    }
+  }
+
+  @Test
+  public void asExecutable_illegalArgument() {
+    try {
+      MoreElements.asExecutable(javaLangPackageElement);
+      fail();
+    } catch (IllegalArgumentException expected) {}
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  private @interface InnerAnnotation {}
+
+  @Documented
+  @InnerAnnotation
+  private @interface AnnotatedAnnotation {}
+
+  @Test
+  public void isAnnotationPresent() {
+    TypeElement annotatedAnnotationElement =
+        compilation.getElements().getTypeElement(AnnotatedAnnotation.class.getCanonicalName());
+    assertThat(MoreElements.isAnnotationPresent(annotatedAnnotationElement, Documented.class))
+        .isTrue();
+    assertThat(MoreElements.isAnnotationPresent(annotatedAnnotationElement, InnerAnnotation.class))
+        .isTrue();
+    assertThat(MoreElements.isAnnotationPresent(annotatedAnnotationElement, SuppressWarnings.class))
+        .isFalse();
+  }
+
+  @Test
+  public void getAnnotationMirror() {
+    TypeElement element =
+        compilation.getElements().getTypeElement(AnnotatedAnnotation.class.getCanonicalName());
+
+    Optional<AnnotationMirror> documented =
+        MoreElements.getAnnotationMirror(element, Documented.class);
+    Optional<AnnotationMirror> innerAnnotation =
+        MoreElements.getAnnotationMirror(element, InnerAnnotation.class);
+    Optional<AnnotationMirror> suppressWarnings =
+        MoreElements.getAnnotationMirror(element, SuppressWarnings.class);
+
+    expect.that(documented).isPresent();
+    expect.that(innerAnnotation).isPresent();
+    expect.that(suppressWarnings).isAbsent();
+
+    Element annotationElement = documented.get().getAnnotationType().asElement();
+    expect.that(MoreElements.isType(annotationElement)).isTrue();
+    expect.that(MoreElements.asType(annotationElement).getQualifiedName().toString())
+        .isEqualTo(Documented.class.getCanonicalName());
+
+    annotationElement = innerAnnotation.get().getAnnotationType().asElement();
+    expect.that(MoreElements.isType(annotationElement)).isTrue();
+    expect.that(MoreElements.asType(annotationElement).getQualifiedName().toString())
+        .isEqualTo(InnerAnnotation.class.getCanonicalName());
+  }
+
+  private abstract static class ParentClass {
+    static void staticMethod() {}
+
+    abstract String foo();
+
+    private void privateMethod() {}
+  }
+
+  private interface ParentInterface {
+    static void staticMethod() {}
+
+    abstract int bar();
+
+    abstract int bar(long x);
+  }
+
+  private abstract static class Child extends ParentClass implements ParentInterface {
+    static void staticMethod() {}
+
+    @Override
+    public int bar() {
+      return 0;
+    }
+
+    abstract void baz();
+
+    void buh(int x) {}
+
+    void buh(int x, int y) {}
+  }
+
+  @Test
+  public void getLocalAndInheritedMethods_Old() {
+    Elements elements = compilation.getElements();
+    Types types = compilation.getTypes();
+    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);
+    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);
+    TypeElement childType = elements.getTypeElement(Child.class.getCanonicalName());
+    @SuppressWarnings("deprecation")
+    Set<ExecutableElement> childTypeMethods =
+        MoreElements.getLocalAndInheritedMethods(childType, elements);
+    Set<ExecutableElement> objectMethods = visibleMethodsFromObject();
+    assertThat(childTypeMethods).containsAtLeastElementsIn(objectMethods);
+    Set<ExecutableElement> nonObjectMethods = Sets.difference(childTypeMethods, objectMethods);
+    assertThat(nonObjectMethods).containsExactly(
+            getMethod(ParentInterface.class, "bar", longMirror),
+            getMethod(ParentClass.class, "foo"),
+            getMethod(Child.class, "bar"),
+            getMethod(Child.class, "baz"),
+            getMethod(Child.class, "buh", intMirror),
+            getMethod(Child.class, "buh", intMirror, intMirror))
+        .inOrder();;
+  }
+
+  @Test
+  public void getLocalAndInheritedMethods() {
+    Elements elements = compilation.getElements();
+    Types types = compilation.getTypes();
+    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);
+    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);
+    TypeElement childType = elements.getTypeElement(Child.class.getCanonicalName());
+    @SuppressWarnings("deprecation")
+    Set<ExecutableElement> childTypeMethods =
+        MoreElements.getLocalAndInheritedMethods(childType, types, elements);
+    Set<ExecutableElement> objectMethods = visibleMethodsFromObject();
+    assertThat(childTypeMethods).containsAtLeastElementsIn(objectMethods);
+    Set<ExecutableElement> nonObjectMethods = Sets.difference(childTypeMethods, objectMethods);
+    assertThat(nonObjectMethods).containsExactly(
+            getMethod(ParentInterface.class, "bar", longMirror),
+            getMethod(ParentClass.class, "foo"),
+            getMethod(Child.class, "bar"),
+            getMethod(Child.class, "baz"),
+            getMethod(Child.class, "buh", intMirror),
+            getMethod(Child.class, "buh", intMirror, intMirror))
+        .inOrder();
+  }
+
+  @Test
+  public void getAllMethods() {
+    Elements elements = compilation.getElements();
+    Types types = compilation.getTypes();
+    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);
+    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);
+    TypeElement childType = elements.getTypeElement(Child.class.getCanonicalName());
+    @SuppressWarnings("deprecation")
+    Set<ExecutableElement> childTypeMethods =
+        MoreElements.getAllMethods(childType, types, elements);
+    Set<ExecutableElement> objectMethods = allMethodsFromObject();
+    assertThat(childTypeMethods).containsAtLeastElementsIn(objectMethods);
+    Set<ExecutableElement> nonObjectMethods = Sets.difference(childTypeMethods, objectMethods);
+    assertThat(nonObjectMethods).containsExactly(
+            getMethod(ParentInterface.class, "staticMethod"),
+            getMethod(ParentInterface.class, "bar", longMirror),
+            getMethod(ParentClass.class, "staticMethod"),
+            getMethod(ParentClass.class, "foo"),
+            getMethod(ParentClass.class, "privateMethod"),
+            getMethod(Child.class, "staticMethod"),
+            getMethod(Child.class, "bar"),
+            getMethod(Child.class, "baz"),
+            getMethod(Child.class, "buh", intMirror),
+            getMethod(Child.class, "buh", intMirror, intMirror))
+        .inOrder();
+  }
+
+  static class Injectable {}
+
+  public static class MenuManager {
+    public interface ParentComponent extends MenuItemA.ParentComponent, MenuItemB.ParentComponent {}
+  }
+
+  public static class MenuItemA {
+    public interface ParentComponent {
+      Injectable injectable();
+    }
+  }
+
+  public static class MenuItemB {
+    public interface ParentComponent {
+      Injectable injectable();
+    }
+  }
+
+  public static class Main {
+    public interface ParentComponent extends MenuManager.ParentComponent {}
+  }
+
+  // Example from https://github.com/williamlian/daggerbug
+  @Test
+  public void getLocalAndInheritedMethods_DaggerBug() {
+    Elements elementUtils = compilation.getElements();
+    TypeElement main = elementUtils.getTypeElement(Main.ParentComponent.class.getCanonicalName());
+    Set<ExecutableElement> methods = MoreElements.getLocalAndInheritedMethods(
+        main, compilation.getTypes(), elementUtils);
+    assertThat(methods).hasSize(1);
+    ExecutableElement method = methods.iterator().next();
+    assertThat(method.getSimpleName().toString()).isEqualTo("injectable");
+    assertThat(method.getParameters()).isEmpty();
+  }
+
+  private Set<ExecutableElement> visibleMethodsFromObject() {
+    Types types = compilation.getTypes();
+    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);
+    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);
+    Set<ExecutableElement> methods = new HashSet<ExecutableElement>();
+    for (ExecutableElement method : ElementFilter.methodsIn(objectElement.getEnclosedElements())) {
+      if (method.getModifiers().contains(Modifier.PUBLIC)
+          || method.getModifiers().contains(Modifier.PROTECTED)) {
+        methods.add(method);
+      }
+    }
+    assertThat(methods)
+        .containsAtLeast(
+            getMethod(Object.class, "clone"),
+            getMethod(Object.class, "finalize"),
+            getMethod(Object.class, "wait"),
+            getMethod(Object.class, "wait", longMirror),
+            getMethod(Object.class, "wait", longMirror, intMirror));
+    return methods;
+  }
+
+  private Set<ExecutableElement> allMethodsFromObject() {
+    Types types = compilation.getTypes();
+    TypeMirror intMirror = types.getPrimitiveType(TypeKind.INT);
+    TypeMirror longMirror = types.getPrimitiveType(TypeKind.LONG);
+    Set<ExecutableElement> methods = new HashSet<>();
+    methods.addAll(ElementFilter.methodsIn(objectElement.getEnclosedElements()));
+    assertThat(methods)
+        .containsAtLeast(
+            getMethod(Object.class, "clone"),
+            getMethod(Object.class, "registerNatives"),
+            getMethod(Object.class, "finalize"),
+            getMethod(Object.class, "wait"),
+            getMethod(Object.class, "wait", longMirror),
+            getMethod(Object.class, "wait", longMirror, intMirror));
+    return methods;
+  }
+
+  private ExecutableElement getMethod(Class<?> c, String methodName, TypeMirror... parameterTypes) {
+    TypeElement type = compilation.getElements().getTypeElement(c.getCanonicalName());
+    Types types = compilation.getTypes();
+    ExecutableElement found = null;
+    for (ExecutableElement method : ElementFilter.methodsIn(type.getEnclosedElements())) {
+      if (method.getSimpleName().contentEquals(methodName)
+          && method.getParameters().size() == parameterTypes.length) {
+        boolean match = true;
+        for (int i = 0; i < parameterTypes.length; i++) {
+          TypeMirror expectedType = parameterTypes[i];
+          TypeMirror actualType = method.getParameters().get(i).asType();
+          match &= types.isSameType(expectedType, actualType);
+        }
+        if (match) {
+          assertThat(found).isNull();
+          found = method;
+        }
+      }
+    }
+    assertWithMessage(methodName + Arrays.toString(parameterTypes)).that(found).isNotNull();
+    return found;
+  }
+
+  private abstract static class AbstractAbstractList extends AbstractList<String> {}
+
+  private static class ConcreteAbstractList<T> extends AbstractList<T> {
+    @Override
+    public int size() {
+      return 0;
+    }
+
+    @Override
+    public T get(int index) {
+      throw new NoSuchElementException();
+    }
+  }
+
+  private Set<String> abstractMethodNamesFrom(Set<ExecutableElement> methods) {
+    ImmutableSet.Builder<String> abstractMethodNames = ImmutableSet.builder();
+    for (ExecutableElement method : methods) {
+      if (method.getModifiers().contains(Modifier.ABSTRACT)) {
+        abstractMethodNames.add(method.getSimpleName().toString());
+      }
+    }
+    return abstractMethodNames.build();
+  }
+
+  // Test that getLocalAndInheritedMethods does the right thing with AbstractList. That class
+  // inherits from Collection along two paths, via its parent AbstractCollection (which implements
+  // Collection) and via its parent List (which extends Collection). Bugs in the past have meant
+  // that the multiple paths might lead the code into thinking that all the abstract methods of
+  // Collection were still abstract in the AbstractList subclasses here, even though most of them
+  // are implemented in AbstractList.
+  @Test
+  public void getLocalAndInheritedMethods_AbstractList() {
+    Elements elements = compilation.getElements();
+
+    TypeElement abstractType =
+        elements.getTypeElement(AbstractAbstractList.class.getCanonicalName());
+    Set<ExecutableElement> abstractTypeMethods =
+        MoreElements.getLocalAndInheritedMethods(abstractType, elements);
+    assertThat(abstractMethodNamesFrom(abstractTypeMethods)).containsExactly("get", "size");
+
+    TypeElement concreteType =
+        elements.getTypeElement(ConcreteAbstractList.class.getCanonicalName());
+    Set<ExecutableElement> concreteTypeMethods =
+        MoreElements.getLocalAndInheritedMethods(concreteType, elements);
+    assertThat(abstractMethodNamesFrom(concreteTypeMethods)).isEmpty();
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/MoreTypesIsTypeOfTest.java b/common/src/test/java/com/google/auto/common/MoreTypesIsTypeOfTest.java
new file mode 100644
index 0000000..05a0a11
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/MoreTypesIsTypeOfTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.Iterables;
+import com.google.testing.compile.CompilationRule;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests {@link MoreTypes#isTypeOf}.
+ */
+@RunWith(JUnit4.class)
+public class MoreTypesIsTypeOfTest {
+
+  @Rule public CompilationRule compilationRule = new CompilationRule();
+
+  private Elements elements;
+
+  @Before public void setUp() {
+    this.elements = compilationRule.getElements();
+  }
+
+  private interface TestType {}
+
+  @Test public void isTypeOf_DeclaredType() {
+    assertTrue(MoreTypes.isType(typeElementFor(TestType.class).asType()));
+    assertWithMessage("mirror represents the TestType")
+        .that(MoreTypes.isTypeOf(TestType.class, typeElementFor(TestType.class).asType()))
+        .isTrue();
+    assertWithMessage("mirror does not represent a String")
+        .that(MoreTypes.isTypeOf(String.class, typeElementFor(TestType.class).asType()))
+        .isFalse();
+  }
+
+  private interface ArrayType {
+    String[] array();
+  }
+
+  @Test public void isTypeOf_ArrayType() {
+    assertTrue(MoreTypes.isType(typeElementFor(ArrayType.class).asType()));
+    TypeMirror type = extractReturnTypeFromHolder(typeElementFor(ArrayType.class));
+    assertWithMessage("array mirror represents an array Class object")
+        .that(MoreTypes.isTypeOf(String[].class, type))
+        .isTrue();
+  }
+
+  private interface PrimitiveBoolean {
+    boolean method();
+  }
+
+  @Test public void isTypeOf_PrimitiveBoolean() {
+    assertTrue(MoreTypes.isType(typeElementFor(PrimitiveBoolean.class).asType()));
+    TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveBoolean.class));
+    assertWithMessage("mirror of a boolean").that(MoreTypes.isTypeOf(Boolean.TYPE, type)).isTrue();
+  }
+
+  private interface PrimitiveByte {
+    byte method();
+  }
+
+  @Test public void isTypeOf_PrimitiveByte() {
+    assertTrue(MoreTypes.isType(typeElementFor(PrimitiveByte.class).asType()));
+    TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveByte.class));
+    assertWithMessage("mirror of a byte").that(MoreTypes.isTypeOf(Byte.TYPE, type)).isTrue();
+  }
+
+  private interface PrimitiveChar {
+    char method();
+  }
+
+  @Test public void isTypeOf_PrimitiveChar() {
+    assertTrue(MoreTypes.isType(typeElementFor(PrimitiveChar.class).asType()));
+    TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveChar.class));
+    assertWithMessage("mirror of a char").that(MoreTypes.isTypeOf(Character.TYPE, type)).isTrue();
+  }
+
+  private interface PrimitiveDouble {
+    double method();
+  }
+
+  @Test public void isTypeOf_PrimitiveDouble() {
+    assertTrue(MoreTypes.isType(typeElementFor(PrimitiveDouble.class).asType()));
+    TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveDouble.class));
+    assertWithMessage("mirror of a double").that(MoreTypes.isTypeOf(Double.TYPE, type)).isTrue();
+  }
+
+  private interface PrimitiveFloat {
+    float method();
+  }
+
+  @Test public void isTypeOf_PrimitiveFloat() {
+    assertTrue(MoreTypes.isType(typeElementFor(PrimitiveFloat.class).asType()));
+    TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveFloat.class));
+    assertWithMessage("mirror of a float").that(MoreTypes.isTypeOf(Float.TYPE, type)).isTrue();
+  }
+
+  private interface PrimitiveInt {
+    int method();
+  }
+
+  @Test public void isTypeOf_PrimitiveInt() {
+    assertTrue(MoreTypes.isType(typeElementFor(PrimitiveInt.class).asType()));
+    TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveInt.class));
+    assertWithMessage("mirror of a int").that(MoreTypes.isTypeOf(Integer.TYPE, type)).isTrue();
+  }
+
+  private interface PrimitiveLong {
+    long method();
+  }
+
+  @Test public void isTypeOf_PrimitiveLong() {
+    assertTrue(MoreTypes.isType(typeElementFor(PrimitiveLong.class).asType()));
+    TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveLong.class));
+    assertWithMessage("mirror of a long").that(MoreTypes.isTypeOf(Long.TYPE, type)).isTrue();
+  }
+
+  private interface PrimitiveShort {
+    short method();
+  }
+
+  @Test public void isTypeOf_PrimitiveShort() {
+    assertTrue(MoreTypes.isType(typeElementFor(PrimitiveShort.class).asType()));
+    TypeMirror type = extractReturnTypeFromHolder(typeElementFor(PrimitiveShort.class));
+    assertWithMessage("mirror of a short").that(MoreTypes.isTypeOf(Short.TYPE, type)).isTrue();
+  }
+
+  private interface PrimitiveVoid {
+    void method();
+  }
+
+  @Test public void isTypeOf_void() {
+    assertTrue(MoreTypes.isType(typeElementFor(PrimitiveVoid.class).asType()));
+    TypeMirror primitive = extractReturnTypeFromHolder(typeElementFor(PrimitiveVoid.class));
+    assertWithMessage("mirror of a void").that(MoreTypes.isTypeOf(Void.TYPE, primitive)).isTrue();
+  }
+
+  private interface DeclaredVoid {
+    Void method();
+  }
+
+  @Test public void isTypeOf_Void() {
+    assertTrue(MoreTypes.isType(typeElementFor(DeclaredVoid.class).asType()));
+    TypeMirror declared = extractReturnTypeFromHolder(typeElementFor(DeclaredVoid.class));
+    assertWithMessage("mirror of a void").that(MoreTypes.isTypeOf(Void.class, declared)).isTrue();
+  }
+
+  @Test public void isTypeOf_fail() {
+    assertFalse(MoreTypes.isType(
+        getOnlyElement(typeElementFor(DeclaredVoid.class).getEnclosedElements()).asType()));
+    TypeMirror method =
+        getOnlyElement(typeElementFor(DeclaredVoid.class).getEnclosedElements()).asType();
+    try {
+      MoreTypes.isTypeOf(String.class, method);
+      fail();
+    } catch (IllegalArgumentException expected) {}
+  }
+
+  // Utility methods for this test.
+
+  private TypeMirror extractReturnTypeFromHolder(TypeElement typeElement) {
+    Element element = Iterables.getOnlyElement(typeElement.getEnclosedElements());
+    TypeMirror arrayType = MoreElements.asExecutable(element).getReturnType();
+    return arrayType;
+  }
+
+  private TypeElement typeElementFor(Class<?> clazz) {
+    return elements.getTypeElement(clazz.getCanonicalName());
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/MoreTypesTest.java b/common/src/test/java/com/google/auto/common/MoreTypesTest.java
new file mode 100644
index 0000000..3cd360d
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/MoreTypesTest.java
@@ -0,0 +1,501 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.truth.Truth.assertThat;
+import static javax.lang.model.type.TypeKind.NONE;
+import static javax.lang.model.type.TypeKind.VOID;
+import static org.junit.Assert.fail;
+
+import com.google.common.base.Function;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.testing.EquivalenceTester;
+import com.google.common.truth.Expect;
+import com.google.testing.compile.CompilationRule;
+import java.lang.annotation.Annotation;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ErrorType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVisitor;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class MoreTypesTest {
+  @Rule public final CompilationRule compilationRule = new CompilationRule();
+  @Rule public final Expect expect = Expect.create();
+
+  @Test
+  public void equivalence() {
+    Types types = compilationRule.getTypes();
+    Elements elements = compilationRule.getElements();
+    TypeMirror objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType();
+    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
+    TypeElement mapElement = elements.getTypeElement(Map.class.getCanonicalName());
+    TypeElement setElement = elements.getTypeElement(Set.class.getCanonicalName());
+    TypeElement enumElement = elements.getTypeElement(Enum.class.getCanonicalName());
+    TypeElement container = elements.getTypeElement(Container.class.getCanonicalName());
+    TypeElement contained = elements.getTypeElement(Container.Contained.class.getCanonicalName());
+    TypeElement funkyBounds = elements.getTypeElement(FunkyBounds.class.getCanonicalName());
+    TypeElement funkyBounds2 = elements.getTypeElement(FunkyBounds2.class.getCanonicalName());
+    TypeElement funkierBounds = elements.getTypeElement(FunkierBounds.class.getCanonicalName());
+    TypeMirror funkyBoundsVar = ((DeclaredType) funkyBounds.asType()).getTypeArguments().get(0);
+    TypeMirror funkyBounds2Var = ((DeclaredType) funkyBounds2.asType()).getTypeArguments().get(0);
+    TypeMirror funkierBoundsVar = ((DeclaredType) funkierBounds.asType()).getTypeArguments().get(0);
+    DeclaredType mapOfObjectToObjectType =
+        types.getDeclaredType(mapElement, objectType, objectType);
+    TypeMirror mapType = mapElement.asType();
+    DeclaredType setOfSetOfObject =
+        types.getDeclaredType(setElement, types.getDeclaredType(setElement, objectType));
+    DeclaredType setOfSetOfString =
+        types.getDeclaredType(setElement, types.getDeclaredType(setElement, stringType));
+    DeclaredType setOfSetOfSetOfObject = types.getDeclaredType(setElement, setOfSetOfObject);
+    DeclaredType setOfSetOfSetOfString = types.getDeclaredType(setElement, setOfSetOfString);
+    WildcardType wildcard = types.getWildcardType(null, null);
+    DeclaredType containerOfObject = types.getDeclaredType(container, objectType);
+    DeclaredType containerOfString = types.getDeclaredType(container, stringType);
+    TypeMirror containedInObject = types.asMemberOf(containerOfObject, contained);
+    TypeMirror containedInString = types.asMemberOf(containerOfString, contained);
+    EquivalenceTester<TypeMirror> tester = EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence())
+        .addEquivalenceGroup(types.getNullType())
+        .addEquivalenceGroup(types.getNoType(NONE))
+        .addEquivalenceGroup(types.getNoType(VOID))
+        .addEquivalenceGroup(objectType)
+        .addEquivalenceGroup(stringType)
+        .addEquivalenceGroup(containedInObject)
+        .addEquivalenceGroup(containedInString)
+        .addEquivalenceGroup(funkyBounds.asType())
+        .addEquivalenceGroup(funkyBounds2.asType())
+        .addEquivalenceGroup(funkierBounds.asType())
+        .addEquivalenceGroup(funkyBoundsVar, funkyBounds2Var)
+        .addEquivalenceGroup(funkierBoundsVar)
+        // Enum<E extends Enum<E>>
+        .addEquivalenceGroup(enumElement.asType())
+        // Map<K, V>
+        .addEquivalenceGroup(mapType)
+        .addEquivalenceGroup(mapOfObjectToObjectType)
+        // Map<?, ?>
+        .addEquivalenceGroup(types.getDeclaredType(mapElement, wildcard, wildcard))
+        // Map
+        .addEquivalenceGroup(types.erasure(mapType), types.erasure(mapOfObjectToObjectType))
+        .addEquivalenceGroup(types.getDeclaredType(mapElement, objectType, stringType))
+        .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType, objectType))
+        .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType, stringType))
+        .addEquivalenceGroup(setOfSetOfObject)
+        .addEquivalenceGroup(setOfSetOfString)
+        .addEquivalenceGroup(setOfSetOfSetOfObject)
+        .addEquivalenceGroup(setOfSetOfSetOfString)
+        .addEquivalenceGroup(wildcard)
+        // ? extends Object
+        .addEquivalenceGroup(types.getWildcardType(objectType, null))
+        // ? extends String
+        .addEquivalenceGroup(types.getWildcardType(stringType, null))
+        // ? super String
+        .addEquivalenceGroup(types.getWildcardType(null, stringType))
+        // Map<String, Map<String, Set<Object>>>
+        .addEquivalenceGroup(types.getDeclaredType(mapElement, stringType,
+            types.getDeclaredType(mapElement, stringType,
+                types.getDeclaredType(setElement, objectType))))
+        .addEquivalenceGroup(FAKE_ERROR_TYPE)
+        ;
+
+    for (TypeKind kind : TypeKind.values()) {
+      if (kind.isPrimitive()) {
+        PrimitiveType primitiveType = types.getPrimitiveType(kind);
+        TypeMirror boxedPrimitiveType = types.boxedClass(primitiveType).asType();
+        tester.addEquivalenceGroup(primitiveType, types.unboxedType(boxedPrimitiveType));
+        tester.addEquivalenceGroup(boxedPrimitiveType);
+        tester.addEquivalenceGroup(types.getArrayType(primitiveType));
+        tester.addEquivalenceGroup(types.getArrayType(boxedPrimitiveType));
+      }
+    }
+
+    ImmutableSet<Class<?>> testClasses = ImmutableSet.of(
+        ExecutableElementsGroupA.class,
+        ExecutableElementsGroupB.class,
+        ExecutableElementsGroupC.class,
+        ExecutableElementsGroupD.class,
+        ExecutableElementsGroupE.class);
+    for (Class<?> testClass : testClasses) {
+      ImmutableList<TypeMirror> equivalenceGroup = FluentIterable.from(
+          elements.getTypeElement(testClass.getCanonicalName()).getEnclosedElements())
+              .transform(new Function<Element, TypeMirror>() {
+                @Override public TypeMirror apply(Element input) {
+                  return input.asType();
+                }
+              })
+              .toList();
+      tester.addEquivalenceGroup(equivalenceGroup);
+    }
+
+    tester.test();
+  }
+
+  @SuppressWarnings("unused")
+  private static final class ExecutableElementsGroupA {
+    ExecutableElementsGroupA() {}
+    void a() {}
+    public static void b() {}
+  }
+
+  @SuppressWarnings("unused")
+  private static final class ExecutableElementsGroupB {
+    ExecutableElementsGroupB(String s) {}
+    void a(String s) {}
+    public static void b(String s) {}
+  }
+
+  @SuppressWarnings("unused")
+  private static final class ExecutableElementsGroupC {
+    ExecutableElementsGroupC() throws Exception {}
+    void a() throws Exception {}
+    public static void b() throws Exception {}
+  }
+
+  @SuppressWarnings("unused")
+  private static final class ExecutableElementsGroupD {
+    ExecutableElementsGroupD() throws RuntimeException {}
+    void a() throws RuntimeException {}
+    public static void b() throws RuntimeException {}
+  }
+
+  @SuppressWarnings("unused")
+  private static final class ExecutableElementsGroupE {
+    <T> ExecutableElementsGroupE() {}
+    <T> void a() {}
+    public static <T> void b() {}
+  }
+
+  @SuppressWarnings("unused")
+  private static final class Container<T> {
+    private final class Contained {}
+  }
+
+  @SuppressWarnings("unused")
+  private static final class FunkyBounds<T extends Number & Comparable<T>> {}
+
+  @SuppressWarnings("unused")
+  private static final class FunkyBounds2<T extends Number & Comparable<T>> {}
+
+  @SuppressWarnings("unused")
+  private static final class FunkierBounds<T extends Number & Comparable<T> & Cloneable> {}
+
+  @Test public void testReferencedTypes() {
+    Elements elements = compilationRule.getElements();
+    TypeElement testDataElement = elements
+        .getTypeElement(ReferencedTypesTestData.class.getCanonicalName());
+    ImmutableMap<String, VariableElement> fieldIndex =
+        FluentIterable.from(ElementFilter.fieldsIn(testDataElement.getEnclosedElements()))
+            .uniqueIndex(new Function<VariableElement, String>() {
+              @Override public String apply(VariableElement input) {
+                return input.getSimpleName().toString();
+              }
+            });
+
+    TypeElement objectElement =
+        elements.getTypeElement(Object.class.getCanonicalName());
+    TypeElement stringElement =
+        elements.getTypeElement(String.class.getCanonicalName());
+    TypeElement integerElement =
+        elements.getTypeElement(Integer.class.getCanonicalName());
+    TypeElement setElement =
+        elements.getTypeElement(Set.class.getCanonicalName());
+    TypeElement mapElement =
+        elements.getTypeElement(Map.class.getCanonicalName());
+    TypeElement charSequenceElement =
+        elements.getTypeElement(CharSequence.class.getCanonicalName());
+
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f1").asType()))
+        .containsExactly(objectElement);
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f2").asType()))
+        .containsExactly(setElement, stringElement);
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f3").asType()))
+        .containsExactly(mapElement, stringElement, objectElement);
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f4").asType()))
+        .containsExactly(integerElement);
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f5").asType()))
+        .containsExactly(setElement);
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f6").asType()))
+        .containsExactly(setElement, charSequenceElement);
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f7").asType()))
+        .containsExactly(mapElement, stringElement, setElement, charSequenceElement);
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f8").asType()))
+        .containsExactly(stringElement);
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f9").asType()))
+        .containsExactly(stringElement);
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f10").asType())).isEmpty();
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f11").asType())).isEmpty();
+    assertThat(MoreTypes.referencedTypes(fieldIndex.get("f12").asType()))
+        .containsExactly(setElement, stringElement);
+  }
+
+  @SuppressWarnings("unused") // types used in compiler tests
+  private static final class ReferencedTypesTestData {
+    Object f1;
+    Set<String> f2;
+    Map<String, Object> f3;
+    Integer f4;
+    Set<?> f5;
+    Set<? extends CharSequence> f6;
+    Map<String, Set<? extends CharSequence>> f7;
+    String[] f8;
+    String[][] f9;
+    int f10;
+    int[] f11;
+    Set<? super String> f12;
+  }
+
+  private static class Parent<T> {}
+  private static class ChildA extends Parent<Number> {}
+  private static class ChildB extends Parent<String> {}
+  private static class GenericChild<T> extends Parent<T> {}
+  private interface InterfaceType {}
+
+  @Test
+  public void asElement_throws() {
+    TypeMirror javaDotLang =
+        compilationRule.getElements().getPackageElement("java.lang").asType();
+    try {
+      MoreTypes.asElement(javaDotLang);
+      fail();
+    } catch (IllegalArgumentException expected) {}
+
+  }
+
+  @Test
+  public void asElement() {
+    Elements elements = compilationRule.getElements();
+    TypeElement stringElement = elements.getTypeElement("java.lang.String");
+    assertThat(MoreTypes.asElement(stringElement.asType())).isEqualTo(stringElement);
+    TypeParameterElement setParameterElement = Iterables.getOnlyElement(
+        compilationRule.getElements().getTypeElement("java.util.Set").getTypeParameters());
+    assertThat(MoreTypes.asElement(setParameterElement.asType())).isEqualTo(setParameterElement);
+    // we don't test error types because those are very hard to get predictably
+  }
+
+  @Test
+  public void testNonObjectSuperclass() {
+    Types types = compilationRule.getTypes();
+    Elements elements = compilationRule.getElements();
+    TypeMirror numberType = elements.getTypeElement(Number.class.getCanonicalName()).asType();
+    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
+    TypeMirror integerType = elements.getTypeElement(Integer.class.getCanonicalName()).asType();
+    TypeElement parent = elements.getTypeElement(Parent.class.getCanonicalName());
+    TypeElement childA = elements.getTypeElement(ChildA.class.getCanonicalName());
+    TypeElement childB = elements.getTypeElement(ChildB.class.getCanonicalName());
+    TypeElement genericChild = elements.getTypeElement(GenericChild.class.getCanonicalName());
+    TypeMirror genericChildOfNumber = types.getDeclaredType(genericChild, numberType);
+    TypeMirror genericChildOfInteger = types.getDeclaredType(genericChild, integerType);
+    TypeMirror objectType =
+        elements.getTypeElement(Object.class.getCanonicalName()).asType();
+    TypeMirror interfaceType =
+        elements.getTypeElement(InterfaceType.class.getCanonicalName()).asType();
+
+    assertThat(MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) objectType))
+        .isAbsent();
+    assertThat(MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) interfaceType))
+        .isAbsent();
+    assertThat(MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) parent.asType()))
+        .isAbsent();
+
+    Optional<DeclaredType> parentOfChildA =
+        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) childA.asType());
+    Optional<DeclaredType> parentOfChildB =
+        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) childB.asType());
+    Optional<DeclaredType> parentOfGenericChild =
+        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) genericChild.asType());
+    Optional<DeclaredType> parentOfGenericChildOfNumber =
+        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) genericChildOfNumber);
+    Optional<DeclaredType> parentOfGenericChildOfInteger =
+        MoreTypes.nonObjectSuperclass(types, elements, (DeclaredType) genericChildOfInteger);
+
+    EquivalenceTester<TypeMirror> tester = EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence())
+          .addEquivalenceGroup(parentOfChildA.get(),
+              types.getDeclaredType(parent, numberType),
+              parentOfGenericChildOfNumber.get())
+          .addEquivalenceGroup(parentOfChildB.get(), types.getDeclaredType(parent, stringType))
+          .addEquivalenceGroup(parentOfGenericChild.get(), parent.asType())
+          .addEquivalenceGroup(parentOfGenericChildOfInteger.get(),
+              types.getDeclaredType(parent, integerType));
+
+    tester.test();
+  }
+  
+  @Test
+  public void testAsMemberOf_variableElement() {
+    Types types = compilationRule.getTypes();
+    Elements elements = compilationRule.getElements();
+    TypeMirror numberType = elements.getTypeElement(Number.class.getCanonicalName()).asType();
+    TypeMirror stringType = elements.getTypeElement(String.class.getCanonicalName()).asType();
+    TypeMirror integerType = elements.getTypeElement(Integer.class.getCanonicalName()).asType();
+
+    TypeElement paramsElement = elements.getTypeElement(Params.class.getCanonicalName());
+    VariableElement tParam = Iterables.getOnlyElement(Iterables.getOnlyElement(
+        ElementFilter.methodsIn(paramsElement.getEnclosedElements())).getParameters());
+    VariableElement tField =
+        Iterables.getOnlyElement(ElementFilter.fieldsIn(paramsElement.getEnclosedElements())); 
+    
+    DeclaredType numberParams =
+        (DeclaredType) elements.getTypeElement(NumberParams.class.getCanonicalName()).asType();
+    DeclaredType stringParams =
+        (DeclaredType) elements.getTypeElement(StringParams.class.getCanonicalName()).asType();
+    TypeElement genericParams = elements.getTypeElement(GenericParams.class.getCanonicalName());
+    DeclaredType genericParamsOfNumber = types.getDeclaredType(genericParams, numberType);
+    DeclaredType genericParamsOfInteger = types.getDeclaredType(genericParams, integerType);
+    
+    TypeMirror fieldOfNumberParams = MoreTypes.asMemberOf(types, numberParams, tField);
+    TypeMirror paramOfNumberParams = MoreTypes.asMemberOf(types, numberParams, tParam);
+    TypeMirror fieldOfStringParams = MoreTypes.asMemberOf(types, stringParams, tField);
+    TypeMirror paramOfStringParams = MoreTypes.asMemberOf(types, stringParams, tParam);
+    TypeMirror fieldOfGenericOfNumber = MoreTypes.asMemberOf(types, genericParamsOfNumber, tField);
+    TypeMirror paramOfGenericOfNumber = MoreTypes.asMemberOf(types, genericParamsOfNumber, tParam);
+    TypeMirror fieldOfGenericOfInteger =
+        MoreTypes.asMemberOf(types, genericParamsOfInteger, tField);
+    TypeMirror paramOfGenericOfInteger =
+        MoreTypes.asMemberOf(types, genericParamsOfInteger, tParam);
+
+    EquivalenceTester<TypeMirror> tester = EquivalenceTester.<TypeMirror>of(MoreTypes.equivalence())
+        .addEquivalenceGroup(fieldOfNumberParams, paramOfNumberParams, fieldOfGenericOfNumber,
+            paramOfGenericOfNumber, numberType)
+        .addEquivalenceGroup(fieldOfStringParams, paramOfStringParams, stringType)
+        .addEquivalenceGroup(fieldOfGenericOfInteger, paramOfGenericOfInteger, integerType);
+    tester.test();
+  }
+  
+  private static class Params<T> {
+    @SuppressWarnings("unused") T t;
+    @SuppressWarnings("unused") void add(T t) {}
+  }
+  private static class NumberParams extends Params<Number> {}
+  private static class StringParams extends Params<String> {}
+  private static class GenericParams<T> extends Params<T> {}
+
+  private static final ErrorType FAKE_ERROR_TYPE = new ErrorType() {
+    @Override
+    public TypeKind getKind() {
+      return TypeKind.ERROR;
+    }
+
+    @Override
+    public <R, P> R accept(TypeVisitor<R, P> v, P p) {
+      return v.visitError(this, p);
+    }
+
+    @Override
+    public List<? extends TypeMirror> getTypeArguments() {
+      return ImmutableList.of();
+    }
+
+    @Override
+    public TypeMirror getEnclosingType() {
+      return null;
+    }
+
+    @Override
+    public Element asElement() {
+      return null;
+    }
+
+    // JDK8 Compatibility:
+
+    public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationType) {
+      return null;
+    }
+
+    public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
+      return null;
+    }
+
+    public List<? extends AnnotationMirror> getAnnotationMirrors() {
+      return null;
+    }
+  };
+
+  @Test
+  public void testIsConversionFromObjectUnchecked_yes() {
+    Elements elements = compilationRule.getElements();
+    TypeElement unchecked = elements.getTypeElement(Unchecked.class.getCanonicalName());
+    for (VariableElement field : ElementFilter.fieldsIn(unchecked.getEnclosedElements())) {
+      TypeMirror type = field.asType();
+      expect
+          .withMessage("Casting to %s is unchecked", type)
+          .that(MoreTypes.isConversionFromObjectUnchecked(type))
+          .isTrue();
+    }
+  }
+
+  @Test
+  public void testIsConversionFromObjectUnchecked_no() {
+    Elements elements = compilationRule.getElements();
+    TypeElement notUnchecked = elements.getTypeElement(NotUnchecked.class.getCanonicalName());
+    for (VariableElement field : ElementFilter.fieldsIn(notUnchecked.getEnclosedElements())) {
+      TypeMirror type = field.asType();
+      expect
+          .withMessage("Casting to %s is not unchecked", type)
+          .that(MoreTypes.isConversionFromObjectUnchecked(type))
+          .isFalse();
+    }
+  }
+
+  // The type of every field here is such that casting to it provokes an "unchecked" warning.
+  @SuppressWarnings("unused")
+  private static class Unchecked<T> {
+    private List<String> listOfString;
+    private List<? extends CharSequence> listOfExtendsCharSequence;
+    private List<? super CharSequence> listOfSuperCharSequence;
+    private List<T> listOfT;
+    private List<T[]> listOfArrayOfT;
+    private T t;
+    private T[] arrayOfT;
+    private List<T>[] arrayOfListOfT;
+    private Map<?, String> mapWildcardToString;
+    private Map<String, ?> mapStringToWildcard;
+  }
+
+  // The type of every field here is such that casting to it doesn't provoke an "unchecked" warning.
+  @SuppressWarnings("unused")
+  private static class NotUnchecked {
+    private String string;
+    private int integer;
+    private String[] arrayOfString;
+    private int[] arrayOfInt;
+    private Thread.State threadStateEnum;
+    private List<?> listOfWildcard;
+    private List<? extends Object> listOfWildcardExtendsObject;
+    private Map<?, ?> mapWildcardToWildcard;
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/OverridesTest.java b/common/src/test/java/com/google/auto/common/OverridesTest.java
new file mode 100644
index 0000000..afb7976
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/OverridesTest.java
@@ -0,0 +1,666 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.truth.Truth.assertThat;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+
+import com.google.common.base.Converter;
+import com.google.common.base.Optional;
+import com.google.common.base.StandardSystemProperty;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Range;
+import com.google.common.io.Files;
+import com.google.common.truth.Expect;
+import com.google.testing.compile.CompilationRule;
+import java.io.File;
+import java.util.AbstractCollection;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.TypeVisitor;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor6;
+import javax.lang.model.util.Types;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.model.Statement;
+
+/**
+ * Tests that the {@link Overrides} class has behaviour consistent with javac. We test this in
+ * two ways: once with {@link Overrides.ExplicitOverrides} using javac's own {@link Elements} and
+ * {@link Types}, and once with it using the version of those objects from the Eclipse compiler
+ * (ecj).
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(Parameterized.class)
+public class OverridesTest {
+  @Parameterized.Parameters(name = "{0}")
+  public static ImmutableList<CompilerType> data() {
+    return ImmutableList.of(CompilerType.JAVAC, CompilerType.ECJ);
+  }
+
+  @Rule public CompilationRule compilation = new CompilationRule();
+  @Rule public EcjCompilationRule ecjCompilation = new EcjCompilationRule();
+  @Rule public Expect expect = Expect.create();
+
+  public enum CompilerType {
+    JAVAC {
+      @Override
+      void initUtils(OverridesTest test) {
+        test.typeUtils = test.compilation.getTypes();
+        test.elementUtils = test.compilation.getElements();
+      }
+    },
+    ECJ {
+      @Override
+      void initUtils(OverridesTest test) {
+        test.typeUtils = test.ecjCompilation.types;
+        test.elementUtils = test.ecjCompilation.elements;
+      }
+    };
+
+    abstract void initUtils(OverridesTest test);
+  }
+  private final CompilerType compilerType;
+
+  private Types typeUtils;
+  private Elements elementUtils;
+  private Elements javacElementUtils;
+  private Overrides javacOverrides;
+  private Overrides.ExplicitOverrides explicitOverrides;
+
+  public OverridesTest(CompilerType compilerType) {
+    this.compilerType = compilerType;
+  }
+
+  @Before
+  public void initializeTestElements() {
+    javacElementUtils = compilation.getElements();
+    javacOverrides = new Overrides.NativeOverrides(javacElementUtils);
+    compilerType.initUtils(this);
+    explicitOverrides = new Overrides.ExplicitOverrides(typeUtils);
+  }
+
+  static class TypesForInheritance {
+    interface One {
+      void m();
+      void m(String x);
+      void n();
+    }
+
+    interface Two {
+      void m();
+      void m(int x);
+    }
+
+    static class Parent {
+      public void m() {}
+    }
+
+    static class ChildOfParent extends Parent {}
+
+    static class ChildOfOne implements One {
+      @Override public void m() {}
+      @Override public void m(String x) {}
+      @Override public void n() {}
+    }
+
+    static class ChildOfOneAndTwo implements One, Two {
+      @Override public void m() {}
+      @Override public void m(String x) {}
+      @Override public void m(int x) {}
+      @Override public void n() {}
+    }
+
+    static class ChildOfParentAndOne extends Parent implements One {
+      @Override public void m() {}
+      @Override public void m(String x) {}
+      @Override public void n() {}
+    }
+
+    static class ChildOfParentAndOneAndTwo extends Parent implements One, Two {
+      @Override public void m(String x) {}
+      @Override public void m(int x) {}
+      @Override public void n() {}
+    }
+
+    abstract static class AbstractChildOfOne implements One {}
+
+    abstract static class AbstractChildOfOneAndTwo implements One, Two {}
+
+    abstract static class AbstractChildOfParentAndOneAndTwo extends Parent implements One, Two {}
+  }
+
+  static class MoreTypesForInheritance {
+    interface Key {}
+
+    interface BindingType {}
+
+    interface ContributionType {}
+
+    interface HasKey {
+      Key key();
+    }
+
+    interface HasBindingType {
+      BindingType bindingType();
+    }
+
+    interface HasContributionType {
+      ContributionType contributionType();
+    }
+
+    abstract static class BindingDeclaration implements HasKey {
+      abstract Optional<Element> bindingElement();
+      abstract Optional<TypeElement> contributingModule();
+    }
+
+    abstract static class MultibindingDeclaration
+        extends BindingDeclaration implements HasBindingType, HasContributionType {
+      @Override public abstract Key key();
+      @Override public abstract ContributionType contributionType();
+      @Override public abstract BindingType bindingType();
+    }
+  }
+
+  static class TypesForVisibility {
+    public abstract static class PublicGrandparent {
+      public abstract String foo();
+    }
+
+    private static class PrivateParent extends PublicGrandparent {
+      @Override
+      public String foo() {
+        return "foo";
+      }
+    }
+
+    static class Child extends PrivateParent {}
+  }
+
+  static class TypesForGenerics {
+    interface XCollection<E> {
+      boolean add(E x);
+    }
+
+    interface XList<E> extends XCollection<E> {
+      @Override public boolean add(E x);
+    }
+
+    static class StringList implements XList<String> {
+      @Override public boolean add(String x) {
+        return false;
+      }
+    }
+  }
+
+  @SuppressWarnings("rawtypes")
+  static class TypesForRaw {
+    static class RawParent {
+      void frob(List x) {}
+    }
+
+    static class RawChildOfRaw extends RawParent {
+      @Override void frob(List x) {}
+    }
+
+    static class NonRawParent {
+      void frob(List<String> x) {}
+    }
+
+    static class RawChildOfNonRaw extends NonRawParent {
+      @Override void frob(List x) {}
+    }
+  }
+
+  @Test
+  public void overridesInheritance() {
+    checkOverridesInContainedClasses(TypesForInheritance.class);
+  }
+
+  @Test
+  public void overridesMoreInheritance() {
+    checkOverridesInContainedClasses(MoreTypesForInheritance.class);
+  }
+
+  @Test
+  public void overridesVisibility() {
+    checkOverridesInContainedClasses(TypesForVisibility.class);
+  }
+
+  @Test
+  public void overridesGenerics() {
+    checkOverridesInContainedClasses(TypesForGenerics.class);
+  }
+
+  @Test
+  public void overridesRaw() {
+    checkOverridesInContainedClasses(TypesForRaw.class);
+  }
+
+  // Test a tricky diamond inheritance hierarchy:
+  //               Collection
+  //              /          \
+  // AbstractCollection     List
+  //              \          /
+  //              AbstractList
+  // This also tests that we do the right thing with generics, since naively the TypeMirror
+  // that you get for List<E> will not appear to be a subtype of the one you get for Collection<E>
+  // since the two Es are not the same.
+  @Test
+  public void overridesDiamond() {
+    checkOverridesInSet(ImmutableSet.<Class<?>>of(
+        Collection.class, List.class, AbstractCollection.class, AbstractList.class));
+  }
+
+  private void checkOverridesInContainedClasses(Class<?> container) {
+    checkOverridesInSet(ImmutableSet.copyOf(container.getDeclaredClasses()));
+  }
+
+  private void checkOverridesInSet(ImmutableSet<Class<?>> testClasses) {
+    assertThat(testClasses).isNotEmpty();
+    ImmutableSet.Builder<TypeElement> testTypesBuilder = ImmutableSet.builder();
+    for (Class<?> testClass : testClasses) {
+      testTypesBuilder.add(getTypeElement(testClass));
+    }
+    ImmutableSet<TypeElement> testTypes = testTypesBuilder.build();
+    ImmutableSet.Builder<ExecutableElement> testMethodsBuilder = ImmutableSet.builder();
+    for (TypeElement testType : testTypes) {
+      testMethodsBuilder.addAll(methodsIn(testType.getEnclosedElements()));
+    }
+    ImmutableSet<ExecutableElement> testMethods = testMethodsBuilder.build();
+    for (TypeElement in : testTypes) {
+      TypeElement javacIn = javacType(in);
+      List<ExecutableElement> inMethods = methodsIn(elementUtils.getAllMembers(in));
+      for (ExecutableElement overrider : inMethods) {
+        ExecutableElement javacOverrider = javacMethod(overrider);
+        for (ExecutableElement overridden : testMethods) {
+          ExecutableElement javacOverridden = javacMethod(overridden);
+          boolean javacSays = javacOverrides.overrides(javacOverrider, javacOverridden, javacIn);
+          boolean weSay = explicitOverrides.overrides(overrider, overridden, in);
+          if (javacSays != weSay) {
+            expect
+                .withMessage(
+                    "%s.%s overrides %s.%s in %s: javac says %s, we say %s",
+                    overrider.getEnclosingElement(), overrider,
+                    overridden.getEnclosingElement(), overridden,
+                    in,
+                    javacSays, weSay)
+                .fail();
+          }
+        }
+      }
+    }
+  }
+
+  private TypeElement getTypeElement(Class<?> c) {
+    return elementUtils.getTypeElement(c.getCanonicalName());
+  }
+
+  private ExecutableElement getMethod(TypeElement in, String name, TypeKind... parameterTypeKinds) {
+    ExecutableElement found = null;
+    methods:
+    for (ExecutableElement method : methodsIn(in.getEnclosedElements())) {
+      if (method.getSimpleName().contentEquals(name)
+          && method.getParameters().size() == parameterTypeKinds.length) {
+        for (int i = 0; i < parameterTypeKinds.length; i++) {
+          if (method.getParameters().get(i).asType().getKind() != parameterTypeKinds[i]) {
+            continue methods;
+          }
+        }
+        assertThat(found).isNull();
+        found = method;
+      }
+    }
+    assertThat(found).isNotNull();
+    return found;
+  }
+
+  // These skeletal parallels to the real collection classes ensure that the test is independent
+  // of the details of those classes, for example whether List<E> redeclares add(E) even though
+  // it also inherits it from Collection<E>.
+
+  private interface XCollection<E> {
+    boolean add(E e);
+  }
+
+  private interface XList<E> extends XCollection<E> {}
+
+  private abstract static class XAbstractCollection<E> implements XCollection<E> {
+    @Override
+    public boolean add(E e) {
+      return false;
+    }
+  }
+
+  private abstract static class XAbstractList<E>
+      extends XAbstractCollection<E> implements XList<E> {
+    @Override
+    public boolean add(E e) {
+      return true;
+    }
+  }
+
+  private abstract static class XStringList extends XAbstractList<String> {}
+
+  private abstract static class XAbstractStringList implements XList<String> {}
+
+  private abstract static class XNumberList<E extends Number> extends XAbstractList<E> {}
+
+  // Parameter of add(E) in StringList is String.
+  // That means that we successfully recorded E[AbstractList] = String and E[List] = E[AbstractList]
+  // and String made it all the way through.
+  @Test
+  public void methodParameters_StringList() {
+    TypeElement xAbstractList = getTypeElement(XAbstractList.class);
+    TypeElement xStringList = getTypeElement(XStringList.class);
+    TypeElement string = getTypeElement(String.class);
+
+    ExecutableElement add = getMethod(xAbstractList, "add", TypeKind.TYPEVAR);
+    List<TypeMirror> params = explicitOverrides.erasedParameterTypes(add, xStringList);
+    List<TypeMirror> expectedParams = ImmutableList.of(string.asType());
+    assertTypeListsEqual(params, expectedParams);
+  }
+
+  // Parameter of add(E) in AbstractStringList is String.
+  // That means that we successfully recorded E[List] = String and E[Collection] = E[List].
+  @Test
+  public void methodParameters_AbstractStringList() {
+    TypeElement xCollection = getTypeElement(XCollection.class);
+    TypeElement xAbstractStringList = getTypeElement(XAbstractStringList.class);
+    TypeElement string = getTypeElement(String.class);
+
+    ExecutableElement add = getMethod(xCollection, "add", TypeKind.TYPEVAR);
+
+    List<TypeMirror> params = explicitOverrides.erasedParameterTypes(add, xAbstractStringList);
+    List<TypeMirror> expectedParams = ImmutableList.of(string.asType());
+    assertTypeListsEqual(params, expectedParams);
+  }
+
+  // Parameter of add(E) in NumberList is Number.
+  // That means that we successfully recorded E[AbstractList] = Number and on from
+  // there, with Number being used because it is the erasure of <E extends Number>.
+  @Test
+  public void methodParams_NumberList() {
+    TypeElement xCollection = getTypeElement(XCollection.class);
+    TypeElement xNumberList = getTypeElement(XNumberList.class);
+    TypeElement number = getTypeElement(Number.class);
+
+    ExecutableElement add = getMethod(xCollection, "add", TypeKind.TYPEVAR);
+
+    List<TypeMirror> params = explicitOverrides.erasedParameterTypes(add, xNumberList);
+    List<TypeMirror> expectedParams = ImmutableList.of(number.asType());
+    assertTypeListsEqual(params, expectedParams);
+  }
+
+  // This is derived from a class that provoked a StackOverflowError in an earlier version.
+  private abstract static class StringToRangeConverter<T extends Comparable<T>>
+      extends Converter<String, Range<T>> {
+    @Override
+    protected String doBackward(Range<T> b) {
+      return null;
+    }
+  }
+
+  @Test
+  public void methodParams_RecursiveBound() {
+    TypeElement stringToRangeConverter = getTypeElement(StringToRangeConverter.class);
+    TypeElement range = getTypeElement(Range.class);
+    ExecutableElement valueConverter =
+        getMethod(stringToRangeConverter, "doBackward", TypeKind.DECLARED);
+    List<TypeMirror> params =
+        explicitOverrides.erasedParameterTypes(valueConverter, stringToRangeConverter);
+    List<TypeMirror> expectedParams =
+        ImmutableList.<TypeMirror>of(typeUtils.erasure(range.asType()));
+    assertTypeListsEqual(params, expectedParams);
+  }
+
+  @Test
+  public void methodFromSuperclasses() {
+    TypeElement xAbstractCollection = getTypeElement(XAbstractCollection.class);
+    TypeElement xAbstractList = getTypeElement(XAbstractList.class);
+    TypeElement xAbstractStringList = getTypeElement(XAbstractStringList.class);
+    TypeElement xStringList = getTypeElement(XStringList.class);
+
+    ExecutableElement add = getMethod(xAbstractCollection, "add", TypeKind.TYPEVAR);
+
+    ExecutableElement addInAbstractStringList =
+        explicitOverrides.methodFromSuperclasses(xAbstractStringList, add);
+    assertThat(addInAbstractStringList).isNull();
+
+    ExecutableElement addInStringList =
+        explicitOverrides.methodFromSuperclasses(xStringList, add);
+    assertThat(addInStringList.getEnclosingElement()).isEqualTo(xAbstractList);
+  }
+
+  @Test
+  public void methodFromSuperinterfaces() {
+    TypeElement xCollection = getTypeElement(XCollection.class);
+    TypeElement xAbstractList = getTypeElement(XAbstractList.class);
+    TypeElement xAbstractStringList = getTypeElement(XAbstractStringList.class);
+    TypeElement xNumberList = getTypeElement(XNumberList.class);
+    TypeElement xList = getTypeElement(XList.class);
+
+    ExecutableElement add = getMethod(xCollection, "add", TypeKind.TYPEVAR);
+
+    ExecutableElement addInAbstractStringList =
+        explicitOverrides.methodFromSuperinterfaces(xAbstractStringList, add);
+    assertThat(addInAbstractStringList.getEnclosingElement()).isEqualTo(xCollection);
+
+    ExecutableElement addInNumberList =
+        explicitOverrides.methodFromSuperinterfaces(xNumberList, add);
+    assertThat(addInNumberList.getEnclosingElement()).isEqualTo(xAbstractList);
+
+    ExecutableElement addInList =
+        explicitOverrides.methodFromSuperinterfaces(xList, add);
+    assertThat(addInList.getEnclosingElement()).isEqualTo(xCollection);
+  }
+
+  private void assertTypeListsEqual(List<TypeMirror> actual, List<TypeMirror> expected) {
+    assertThat(actual.size()).isEqualTo(expected.size());
+    for (int i = 0; i < actual.size(); i++) {
+      assertThat(typeUtils.isSameType(actual.get(i), expected.get(i))).isTrue();
+    }
+  }
+
+  // TODO(emcmanus): replace this with something from compile-testing when that's available.
+  /**
+   * An equivalent to {@link CompilationRule} that uses ecj (the Eclipse compiler) instead of javac.
+   * If the parameterized test is not selecting ecj then this rule has no effect.
+   */
+  public class EcjCompilationRule implements TestRule {
+    Elements elements;
+    Types types;
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+      if (!compilerType.equals(CompilerType.ECJ)) {
+        return base;
+      }
+      return new EcjCompilationStatement(base);
+    }
+  }
+
+  private class EcjCompilationStatement extends Statement {
+    private final Statement statement;
+
+    EcjCompilationStatement(Statement base) {
+      this.statement = base;
+    }
+
+    @Override
+    public void evaluate() throws Throwable {
+      File tmpDir = File.createTempFile("OverridesTest", "dir");
+      tmpDir.delete();
+      tmpDir.mkdir();
+      File dummySourceFile = new File(tmpDir, "Dummy.java");
+      try {
+        Files.asCharSink(dummySourceFile, UTF_8).write("class Dummy {}");
+        evaluate(dummySourceFile);
+      } finally {
+        dummySourceFile.delete();
+        tmpDir.delete();
+      }
+    }
+
+    private void evaluate(File dummySourceFile) throws Throwable {
+      JavaCompiler compiler = new EclipseCompiler();
+      StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, UTF_8);
+      // This hack is only needed in a Google-internal Java 8 environment where symbolic links make
+      // it hard for ecj to find the boot class path. Elsewhere it is unnecessary but harmless.
+      File rtJar = new File(StandardSystemProperty.JAVA_HOME.value() + "/lib/rt.jar");
+      if (rtJar.exists()) {
+        List<File> bootClassPath = ImmutableList.<File>builder()
+            .add(rtJar)
+            .addAll(fileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH))
+            .build();
+        fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath);
+      }
+      Iterable<? extends JavaFileObject> sources = fileManager.getJavaFileObjects(dummySourceFile);
+      JavaCompiler.CompilationTask task =
+          compiler.getTask(null, fileManager, null, null, null, sources);
+      EcjTestProcessor processor = new EcjTestProcessor(statement);
+      task.setProcessors(ImmutableList.of(processor));
+      assertThat(task.call()).isTrue();
+      processor.maybeThrow();
+    }
+  }
+
+  @SupportedAnnotationTypes("*")
+  private class EcjTestProcessor extends AbstractProcessor {
+    private final Statement statement;
+    private Throwable thrown;
+
+    EcjTestProcessor(Statement statement) {
+      this.statement = statement;
+    }
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latest();
+    }
+
+    @Override
+    public boolean process(
+        Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      if (roundEnv.processingOver()) {
+        ecjCompilation.elements = processingEnv.getElementUtils();
+        ecjCompilation.types = processingEnv.getTypeUtils();
+        try {
+          statement.evaluate();
+        } catch (Throwable t) {
+          thrown = t;
+        }
+      }
+      return false;
+    }
+
+    void maybeThrow() throws Throwable {
+      if (thrown != null) {
+        throw thrown;
+      }
+    }
+  }
+
+  private TypeElement javacType(TypeElement type) {
+    return javacElementUtils.getTypeElement(type.getQualifiedName().toString());
+  }
+
+  private ExecutableElement javacMethod(ExecutableElement method) {
+    if (elementUtils == javacElementUtils) {
+      return method;
+    }
+    TypeElement containingType = MoreElements.asType(method.getEnclosingElement());
+    TypeElement javacContainingType = javacType(containingType);
+    List<ExecutableElement> candidates = new ArrayList<ExecutableElement>();
+    methods:
+    for (ExecutableElement javacMethod : methodsIn(javacContainingType.getEnclosedElements())) {
+      if (javacMethod.getSimpleName().contentEquals(method.getSimpleName())
+          && javacMethod.getParameters().size() == method.getParameters().size()) {
+        for (int i = 0; i < method.getParameters().size(); i++) {
+          VariableElement parameter = method.getParameters().get(i);
+          VariableElement javacParameter = javacMethod.getParameters().get(i);
+          if (!erasedToString(parameter.asType()).equals(erasedToString(javacParameter.asType()))) {
+            continue methods;
+          }
+        }
+        candidates.add(javacMethod);
+      }
+    }
+    if (candidates.size() == 1) {
+      return candidates.get(0);
+    } else {
+      throw new IllegalStateException(
+          "Expected one javac method matching " + method + " but found " + candidates);
+    }
+  }
+
+  private static String erasedToString(TypeMirror type) {
+    return ERASED_STRING_TYPE_VISITOR.visit(type);
+  }
+
+  private static final TypeVisitor<String, Void> ERASED_STRING_TYPE_VISITOR =
+      new SimpleTypeVisitor6<String, Void>() {
+    @Override
+    protected String defaultAction(TypeMirror e, Void p) {
+      return e.toString();
+    }
+
+    @Override
+    public String visitArray(ArrayType t, Void p) {
+      return visit(t.getComponentType()) + "[]";
+    }
+
+    @Override
+    public String visitDeclared(DeclaredType t, Void p) {
+      return MoreElements.asType(t.asElement()).getQualifiedName().toString();
+    }
+
+    @Override
+    public String visitTypeVariable(TypeVariable t, Void p) {
+      return visit(t.getUpperBound());
+    }
+  };
+}
diff --git a/common/src/test/java/com/google/auto/common/SimpleAnnotationMirrorTest.java b/common/src/test/java/com/google/auto/common/SimpleAnnotationMirrorTest.java
new file mode 100644
index 0000000..d73e1b6
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/SimpleAnnotationMirrorTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.testing.compile.CompilationRule;
+import java.util.HashMap;
+import java.util.Map;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.AnnotationValueVisitor;
+import javax.lang.model.element.TypeElement;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link SimpleAnnotationMirror}. */
+@RunWith(JUnit4.class)
+public class SimpleAnnotationMirrorTest {
+  @Rule public final CompilationRule compilation = new CompilationRule();
+
+  @interface EmptyAnnotation {}
+
+  @interface AnnotationWithDefault {
+    int value() default 3;
+  }
+
+  @interface MultipleValues {
+    int value1();
+    int value2();
+  }
+
+  @Test
+  public void emptyAnnotation() {
+    TypeElement emptyAnnotation = getTypeElement(EmptyAnnotation.class);
+    AnnotationMirror simpleAnnotation = SimpleAnnotationMirror.of(emptyAnnotation);
+    assertThat(simpleAnnotation.getAnnotationType()).isEqualTo(emptyAnnotation.asType());
+    assertThat(simpleAnnotation.getElementValues()).isEmpty();
+  }
+
+  @Test
+  public void multipleValues() {
+    TypeElement multipleValues = getTypeElement(MultipleValues.class);
+    Map<String, AnnotationValue> values = new HashMap<>();
+    values.put("value1", intValue(1));
+    values.put("value2", intValue(2));
+    assertThat(SimpleAnnotationMirror.of(multipleValues, values).getElementValues()).hasSize(2);
+  }
+
+  @Test
+  public void extraValues() {
+    TypeElement multipleValues = getTypeElement(MultipleValues.class);
+    Map<String, AnnotationValue> values = new HashMap<>();
+    values.put("value1", intValue(1));
+    values.put("value2", intValue(2));
+    values.put("value3", intValue(3));
+    expectThrows(() -> SimpleAnnotationMirror.of(multipleValues, values));
+  }
+
+  @Test
+  public void defaultValue() {
+    TypeElement withDefaults = getTypeElement(AnnotationWithDefault.class);
+    AnnotationMirror annotation = SimpleAnnotationMirror.of(withDefaults);
+    assertThat(annotation.getElementValues()).hasSize(1);
+    assertThat(getOnlyElement(annotation.getElementValues().values()).getValue()).isEqualTo(3);
+  }
+
+  @Test
+  public void overriddenDefaultValue() {
+    TypeElement withDefaults = getTypeElement(AnnotationWithDefault.class);
+    AnnotationMirror annotation =
+        SimpleAnnotationMirror.of(withDefaults, ImmutableMap.of("value", intValue(4)));
+    assertThat(annotation.getElementValues()).hasSize(1);
+    assertThat(getOnlyElement(annotation.getElementValues().values()).getValue()).isEqualTo(4);
+  }
+
+  @Test
+  public void missingValues() {
+    TypeElement multipleValues = getTypeElement(MultipleValues.class);
+    expectThrows(() -> SimpleAnnotationMirror.of(multipleValues));
+  }
+
+  @Test
+  public void notAnAnnotation() {
+    TypeElement stringElement = getTypeElement(String.class);
+    expectThrows(() -> SimpleAnnotationMirror.of(stringElement));
+  }
+
+  private TypeElement getTypeElement(Class<?> clazz) {
+    return compilation.getElements().getTypeElement(clazz.getCanonicalName());
+  }
+
+  private static void expectThrows(Runnable throwingRunnable) {
+    try {
+      throwingRunnable.run();
+      fail("Expected an IllegalArgumentException");
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  private static AnnotationValue intValue(int value) {
+    return new AnnotationValue() {
+      @Override
+      public Object getValue() {
+        return value;
+      }
+
+      @Override
+      public <R, P> R accept(AnnotationValueVisitor<R, P> annotationValueVisitor, P p) {
+        return annotationValueVisitor.visitInt(value, p);
+      }
+    };
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/SimpleTypeAnnotationValueTest.java b/common/src/test/java/com/google/auto/common/SimpleTypeAnnotationValueTest.java
new file mode 100644
index 0000000..4fc61b5
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/SimpleTypeAnnotationValueTest.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.testing.compile.CompilationRule;
+import java.util.List;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+import javax.lang.model.util.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link SimpleTypeAnnotationValue}. */
+@RunWith(JUnit4.class)
+public class SimpleTypeAnnotationValueTest {
+  @Rule public final CompilationRule compilation = new CompilationRule();
+  private Types types;
+  private Elements elements;
+  private TypeMirror objectType;
+  private PrimitiveType primitiveType;
+
+  @Before
+  public void setUp() {
+    types = compilation.getTypes();
+    elements = compilation.getElements();
+    objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType();
+    primitiveType = types.getPrimitiveType(TypeKind.BOOLEAN);
+  }
+
+  @Test
+  public void primitiveClass() {
+    AnnotationValue annotationValue = SimpleTypeAnnotationValue.of(primitiveType);
+    assertThat(annotationValue.getValue()).isEqualTo(primitiveType);
+  }
+
+  @Test
+  public void arrays() {
+    SimpleTypeAnnotationValue.of(types.getArrayType(objectType));
+    SimpleTypeAnnotationValue.of(types.getArrayType(primitiveType));
+  }
+
+  @Test
+  public void declaredType() {
+    SimpleTypeAnnotationValue.of(objectType);
+  }
+
+  @Test
+  public void visitorMethod() {
+    SimpleTypeAnnotationValue.of(objectType).accept(new SimpleAnnotationValueVisitor8<Void, Void>(){
+      @Override
+      public Void visitType(TypeMirror typeMirror, Void aVoid) {
+        // do nothing, expected case
+        return null;
+      }
+
+      @Override
+      protected Void defaultAction(Object o, Void aVoid) {
+        throw new AssertionError();
+      }
+    }, null);
+  }
+
+  @Test
+  public void parameterizedType() {
+    try {
+      SimpleTypeAnnotationValue.of(
+          types.getDeclaredType(
+              elements.getTypeElement(List.class.getCanonicalName()), objectType));
+      fail("Expected an exception");
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/SuperficialValidationTest.java b/common/src/test/java/com/google/auto/common/SuperficialValidationTest.java
new file mode 100644
index 0000000..15e54ff
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/SuperficialValidationTest.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.testing.compile.JavaFileObjects;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class SuperficialValidationTest {
+  @Test
+  public void missingReturnType() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "abstract class TestClass {",
+        "  abstract MissingType blah();",
+        "}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
+          }
+        })
+        .failsToCompile();
+  }
+
+  @Test
+  public void missingGenericReturnType() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "abstract class TestClass {",
+        "  abstract MissingType<?> blah();",
+        "}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
+          }
+        })
+        .failsToCompile();
+  }
+
+  @Test
+  public void missingReturnTypeTypeParameter() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "import java.util.Map;",
+        "import java.util.Set;",
+        "",
+        "abstract class TestClass {",
+        "  abstract Map<Set<?>, MissingType<?>> blah();",
+        "}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
+          }
+        })
+        .failsToCompile();
+  }
+
+  @Test
+  public void missingTypeParameter() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "class TestClass<T extends MissingType> {}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
+          }
+        })
+        .failsToCompile();
+  }
+
+  @Test
+  public void missingParameterType() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "abstract class TestClass {",
+        "  abstract void foo(MissingType x);",
+        "}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
+          }
+        })
+        .failsToCompile();
+  }
+
+  @Test
+  public void missingAnnotation() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "@MissingAnnotation",
+        "class TestClass {}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
+          }
+        })
+        .failsToCompile();
+  }
+
+  @Test
+  public void handlesRecursiveTypeParams() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "class TestClass<T extends Comparable<T>> {}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isTrue();
+          }
+        })
+        .compilesWithoutError();
+  }
+
+  @Test
+  public void handlesRecursiveType() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "abstract class TestClass {",
+        "  abstract TestClass foo(TestClass x);",
+        "}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isTrue();
+          }
+        })
+        .compilesWithoutError();
+  }
+
+  @Test
+  public void missingWildcardBound() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "import java.util.Set;",
+        "",
+        "class TestClass {",
+        "  Set<? extends MissingType> extendsTest() {",
+        "    return null;",
+        "  }",
+        "",
+        "  Set<? super MissingType> superTest() {",
+        "    return null;",
+        "  }",
+        "}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
+          }
+        })
+        .failsToCompile();
+  }
+
+  @Test
+  public void missingIntersection() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines(
+        "test.TestClass",
+        "package test;",
+        "",
+        "class TestClass<T extends Number & Missing> {}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AssertingProcessor() {
+          @Override void runAssertions() {
+            TypeElement testClassElement =
+                processingEnv.getElementUtils().getTypeElement("test.TestClass");
+            assertThat(SuperficialValidation.validateElement(testClassElement)).isFalse();
+          }
+        })
+        .failsToCompile();
+  }
+
+  @Test
+  public void invalidAnnotationValue() {
+    JavaFileObject javaFileObject = JavaFileObjects.forSourceLines("test.Outer",
+        "package test;",
+        "",
+        "final class Outer {",
+        "  @interface TestAnnotation {",
+        "    Class[] classes();",
+        "  }",
+        "",
+        "  @TestAnnotation(classes = Foo)",
+        "  static class TestClass {}",
+        "}");
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(
+            new AssertingProcessor() {
+              @Override
+              void runAssertions() {
+                TypeElement testClassElement =
+                    processingEnv.getElementUtils().getTypeElement("test.Outer.TestClass");
+                assertWithMessage("testClassElement is valid")
+                    .that(SuperficialValidation.validateElement(testClassElement))
+                    .isFalse();
+              }
+            })
+        .failsToCompile();
+  }
+
+  private abstract static class AssertingProcessor extends AbstractProcessor {
+    @Override
+    public Set<String> getSupportedAnnotationTypes() {
+      return ImmutableSet.of("*");
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      try {
+        runAssertions();
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+      return false;
+    }
+
+    abstract void runAssertions() throws Exception;
+  }
+}
diff --git a/common/src/test/java/com/google/auto/common/VisibilityTest.java b/common/src/test/java/com/google/auto/common/VisibilityTest.java
new file mode 100644
index 0000000..6a80b7a
--- /dev/null
+++ b/common/src/test/java/com/google/auto/common/VisibilityTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.common;
+
+import static com.google.auto.common.Visibility.DEFAULT;
+import static com.google.auto.common.Visibility.PRIVATE;
+import static com.google.auto.common.Visibility.PROTECTED;
+import static com.google.auto.common.Visibility.PUBLIC;
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.testing.compile.CompilationRule;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import javax.lang.model.element.Element;
+import javax.lang.model.util.Elements;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class VisibilityTest {
+  @Rule public CompilationRule compilation = new CompilationRule();
+
+  @Test
+  public void packageVisibility() {
+    assertThat(Visibility.ofElement(compilation.getElements().getPackageElement("java.lang")))
+        .isEqualTo(PUBLIC);
+    assertThat(Visibility.ofElement(
+        compilation.getElements().getPackageElement("com.google.auto.common")))
+            .isEqualTo(PUBLIC);
+  }
+
+  @Test
+  public void moduleVisibility() throws IllegalAccessException, InvocationTargetException {
+    Method getModuleElement;
+    try {
+      getModuleElement = Elements.class.getMethod("getModuleElement", CharSequence.class);
+    } catch (NoSuchMethodException e) {
+      // TODO(ronshapiro): rewrite this test without reflection once we're on Java 9
+      return;
+    }
+    Element moduleElement =
+        (Element) getModuleElement.invoke(compilation.getElements(), "java.base");
+    assertThat(Visibility.ofElement(moduleElement)).isEqualTo(PUBLIC);
+  }
+
+  @SuppressWarnings("unused")
+  public static class PublicClass {
+    public static class NestedPublicClass {}
+    protected static class NestedProtectedClass {}
+    static class NestedDefaultClass {}
+    private static class NestedPrivateClass {}
+  }
+
+  @SuppressWarnings("unused")
+  protected static class ProtectedClass {
+    public static class NestedPublicClass {}
+    protected static class NestedProtectedClass {}
+    static class NestedDefaultClass {}
+    private static class NestedPrivateClass {}
+  }
+
+  @SuppressWarnings("unused")
+  static class DefaultClass {
+    public static class NestedPublicClass {}
+    protected static class NestedProtectedClass {}
+    static class NestedDefaultClass {}
+    private static class NestedPrivateClass {}
+  }
+
+  @SuppressWarnings("unused")
+  private static class PrivateClass {
+    public static class NestedPublicClass {}
+    protected static class NestedProtectedClass {}
+    static class NestedDefaultClass {}
+    private static class NestedPrivateClass {}
+  }
+
+  @Test
+  public void classVisibility() {
+    assertThat(Visibility.ofElement(compilation.getElements().getTypeElement("java.util.Map")))
+        .isEqualTo(PUBLIC);
+    assertThat(Visibility.ofElement(
+        compilation.getElements().getTypeElement("java.util.Map.Entry")))
+            .isEqualTo(PUBLIC);
+    assertThat(Visibility.ofElement(
+        compilation.getElements().getTypeElement(PublicClass.class.getCanonicalName())))
+            .isEqualTo(PUBLIC);
+    assertThat(Visibility.ofElement(
+        compilation.getElements().getTypeElement(ProtectedClass.class.getCanonicalName())))
+            .isEqualTo(PROTECTED);
+    assertThat(Visibility.ofElement(
+        compilation.getElements().getTypeElement(DefaultClass.class.getCanonicalName())))
+            .isEqualTo(DEFAULT);
+    assertThat(Visibility.ofElement(
+        compilation.getElements().getTypeElement(PrivateClass.class.getCanonicalName())))
+            .isEqualTo(PRIVATE);
+  }
+
+  @Test
+  public void effectiveClassVisibility() {
+    assertThat(effectiveVisiblityOfClass(PublicClass.class)).isEqualTo(PUBLIC);
+    assertThat(effectiveVisiblityOfClass(ProtectedClass.class)).isEqualTo(PROTECTED);
+    assertThat(effectiveVisiblityOfClass(DefaultClass.class)).isEqualTo(DEFAULT);
+    assertThat(effectiveVisiblityOfClass(PrivateClass.class)).isEqualTo(PRIVATE);
+
+    assertThat(effectiveVisiblityOfClass(PublicClass.NestedPublicClass.class))
+        .isEqualTo(PUBLIC);
+    assertThat(effectiveVisiblityOfClass(PublicClass.NestedProtectedClass.class))
+        .isEqualTo(PROTECTED);
+    assertThat(effectiveVisiblityOfClass(PublicClass.NestedDefaultClass.class))
+        .isEqualTo(DEFAULT);
+    assertThat(effectiveVisiblityOfClass(PublicClass.NestedPrivateClass.class))
+        .isEqualTo(PRIVATE);
+
+    assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedPublicClass.class))
+        .isEqualTo(PROTECTED);
+    assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedProtectedClass.class))
+        .isEqualTo(PROTECTED);
+    assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedDefaultClass.class))
+        .isEqualTo(DEFAULT);
+    assertThat(effectiveVisiblityOfClass(ProtectedClass.NestedPrivateClass.class))
+        .isEqualTo(PRIVATE);
+
+    assertThat(effectiveVisiblityOfClass(DefaultClass.NestedPublicClass.class))
+        .isEqualTo(DEFAULT);
+    assertThat(effectiveVisiblityOfClass(DefaultClass.NestedProtectedClass.class))
+        .isEqualTo(DEFAULT);
+    assertThat(effectiveVisiblityOfClass(DefaultClass.NestedDefaultClass.class))
+        .isEqualTo(DEFAULT);
+    assertThat(effectiveVisiblityOfClass(DefaultClass.NestedPrivateClass.class))
+        .isEqualTo(PRIVATE);
+
+    assertThat(effectiveVisiblityOfClass(PrivateClass.NestedPublicClass.class))
+        .isEqualTo(PRIVATE);
+    assertThat(effectiveVisiblityOfClass(PrivateClass.NestedProtectedClass.class))
+        .isEqualTo(PRIVATE);
+    assertThat(effectiveVisiblityOfClass(PrivateClass.NestedDefaultClass.class))
+        .isEqualTo(PRIVATE);
+    assertThat(effectiveVisiblityOfClass(PrivateClass.NestedPrivateClass.class))
+        .isEqualTo(PRIVATE);
+  }
+
+  private Visibility effectiveVisiblityOfClass(Class<?> clazz) {
+    return Visibility.effectiveVisibilityOfElement(
+        compilation.getElements().getTypeElement(clazz.getCanonicalName()));
+  }
+}
diff --git a/factory/README.md b/factory/README.md
new file mode 100644
index 0000000..f5874fe
--- /dev/null
+++ b/factory/README.md
@@ -0,0 +1,101 @@
+AutoFactory
+======
+
+A source code generator for JSR-330-compatible factories.
+
+AutoWhat‽
+-------------
+
+[Java][java] is full of [factories](http://en.wikipedia.org/wiki/Factory_method_pattern). They're mechanical, repetitive, typically untested and sometimes the source of subtle bugs. _Sounds like a job for robots!_
+
+AutoFactory generates factories that can be used on their own or with [JSR-330](http://jcp.org/en/jsr/detail?id=330)-compatible [dependency injectors](http://en.wikipedia.org/wiki/Dependency_injection) from a simple annotation. Any combination of parameters can either be passed through factory methods or provided to the factory at construction time. They can implement interfaces or extend abstract classes. They're what you would have written, but without the bugs.
+
+Save time.  Save code.  Save sanity.
+
+Example
+-------
+
+Say you have:
+
+```java
+@AutoFactory
+final class SomeClass {
+  private final String providedDepA;
+  private final String depB;
+
+  SomeClass(@Provided @AQualifier String providedDepA, String depB) {
+    this.providedDepA = providedDepA;
+    this.depB = depB;
+  }
+
+  // …
+}
+```
+
+AutoFactory will generate:
+
+```java
+import javax.annotation.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(value = "com.google.auto.factory.processor.AutoFactoryProcessor")
+final class SomeClassFactory {
+  private final Provider<String> providedDepAProvider;
+  
+  @Inject SomeClassFactory(
+      @AQualifier Provider<String> providedDepAProvider) {
+    this.providedDepAProvider = providedDepAProvider;
+  }
+  
+  SomeClass create(String depB) {
+    return new SomeClass(providedDepAProvider.get(), depB);
+  }
+}
+```
+
+> NOTE: AutoFactory only supports JSR-330 @Qualifier annotations. Older, 
+> framework-specific annotations from Guice, Spring, etc are not
+> supported (though these all support JSR-330)
+
+Download
+--------
+
+In order to activate code generation you will need to
+include `auto-factory-${version}.jar` in your build at 
+compile time.
+
+In a Maven project, one would include the `auto-factory` 
+artifact as an "optional" dependency:
+
+```xml
+<dependencies>
+  <dependency>
+    <groupId>com.google.auto.factory</groupId>
+    <artifactId>auto-factory</artifactId>
+    <version>${version}</version>
+    <optional>true</optional>
+  </dependency>
+</dependencies>
+```
+
+
+License
+-------
+
+    Copyright 2013 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       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.
+
+[java]: https://en.wikipedia.org/wiki/Java_(programming_language)
+
diff --git a/factory/pom.xml b/factory/pom.xml
new file mode 100644
index 0000000..48bcfef
--- /dev/null
+++ b/factory/pom.xml
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2012 Google LLC
+  Copyright (C) 2012 Square, Inc.
+
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.sonatype.oss</groupId>
+    <artifactId>oss-parent</artifactId>
+    <version>7</version>
+  </parent>
+
+  <groupId>com.google.auto.factory</groupId>
+  <artifactId>auto-factory</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>AutoFactory</name>
+  <description>
+    JSR-330-compatible factories.
+  </description>
+  <url>https://github.com/google/auto/tree/master/factory</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <java.version>1.8</java.version>
+    <guava.version>28.2-jre</guava.version>
+    <truth.version>1.0.1</truth.version>
+  </properties>
+
+  <scm>
+    <url>http://github.com/google/auto</url>
+    <connection>scm:git:git://github.com/google/auto.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+
+  <issueManagement>
+    <system>GitHub Issues</system>
+    <url>http://github.com/google/auto/issues</url>
+  </issueManagement>
+
+  <licenses>
+    <license>
+      <name>Apache 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+    </license>
+  </licenses>
+
+  <organization>
+    <name>Google LLC</name>
+    <url>http://www.google.com</url>
+  </organization>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.auto</groupId>
+      <artifactId>auto-common</artifactId>
+      <version>0.10</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value-annotations</artifactId>
+      <version>1.7</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value</artifactId>
+      <version>1.7</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto.service</groupId>
+      <artifactId>auto-service</artifactId>
+      <version>1.0-rc6</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>net.ltgt.gradle.incap</groupId>
+      <artifactId>incap</artifactId>
+      <version>0.2</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>net.ltgt.gradle.incap</groupId>
+      <artifactId>incap-processor</artifactId>
+      <version>0.2</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.googlejavaformat</groupId>
+      <artifactId>google-java-format</artifactId>
+      <version>1.7</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>${guava.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.squareup</groupId>
+      <artifactId>javapoet</artifactId>
+      <version>1.12.1</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <version>1</version>
+    </dependency>
+    <!-- test dependencies -->
+    <dependency>
+      <groupId>com.google.testing.compile</groupId>
+      <artifactId>compile-testing</artifactId>
+      <version>0.18</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.13</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <version>${truth.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+      <version>3.0.2</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.checkerframework</groupId>
+      <artifactId>checker-compat-qual</artifactId>
+      <version>2.5.5</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.7.0</version>
+        <configuration>
+          <source>${java.version}</source>
+          <target>${java.version}</target>
+          <compilerArgument>-Xlint:all</compilerArgument>
+          <showWarnings>true</showWarnings>
+          <showDeprecation>true</showDeprecation>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-java</artifactId>
+            <version>0.9.4</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>3.0.2</version>
+      </plugin>
+      <plugin>
+        <artifactId>maven-invoker-plugin</artifactId>
+        <version>3.0.1</version>
+        <configuration>
+          <addTestClassPath>true</addTestClassPath>
+          <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
+          <pomIncludes>
+            <pomInclude>*/pom.xml</pomInclude>
+          </pomIncludes>
+          <streamLogs>true</streamLogs>
+        </configuration>
+        <executions>
+          <execution>
+            <id>integration-test</id>
+            <goals>
+              <goal>install</goal>
+              <goal>run</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.immutables.tools</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>4</version>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/factory/src/it/functional/pom.xml b/factory/src/it/functional/pom.xml
new file mode 100644
index 0000000..56e8f6f
--- /dev/null
+++ b/factory/src/it/functional/pom.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2013 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<!-- TODO(gak): see if we can manage these dependencies any better -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <!-- TODO(cpovirk): Remove parent entirely? -->
+  <parent>
+    <groupId>org.sonatype.oss</groupId>
+    <artifactId>oss-parent</artifactId>
+    <version>7</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.google.auto.value.it.functional</groupId>
+  <artifactId>functional</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>Auto-Value Functional Integration Test</name>
+  <dependencies>
+    <dependency>
+      <groupId>com.google.auto.factory</groupId>
+      <artifactId>auto-factory</artifactId>
+      <version>@project.version@</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+      <version>3.0.2</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>27.0.1-jre</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.inject</groupId>
+      <artifactId>guice</artifactId>
+      <version>4.1.0</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger</artifactId>
+      <version>2.13</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.dagger</groupId>
+      <artifactId>dagger-compiler</artifactId>
+      <version>2.13</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.12</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <version>0.44</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>3.0.2</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.7.0</version>
+        <configuration>
+          <source>1.8</source>
+          <target>1.8</target>
+          <compilerArgument>-Xlint:all</compilerArgument>
+          <showWarnings>true</showWarnings>
+          <showDeprecation>true</showDeprecation>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-java</artifactId>
+            <version>0.9.4</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/DaggerModule.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/DaggerModule.java
new file mode 100644
index 0000000..be9478f
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/DaggerModule.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import dagger.Module;
+import dagger.Provides;
+
+@Module
+final class DaggerModule {
+  @Provides Dependency provideDependency(DependencyImpl impl) {
+    return impl;
+  }
+
+  @Provides
+  @Qualifier
+  Dependency provideQualifiedDependency(QualifiedDependencyImpl impl) {
+    return impl;
+  }
+
+  @Provides
+  int providePrimitive() {
+    return 1;
+  }
+
+  @Provides
+  @Qualifier
+  int provideQualifiedPrimitive() {
+    return 2;
+  }
+
+  @Provides
+  Number provideNumber() {
+    return 3;
+  }
+}
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/Dependency.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/Dependency.java
new file mode 100644
index 0000000..18d19eb
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/Dependency.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+public interface Dependency {}
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/DependencyImpl.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/DependencyImpl.java
new file mode 100644
index 0000000..4c019ea
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/DependencyImpl.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import javax.inject.Inject;
+
+public class DependencyImpl implements Dependency {
+  @Inject DependencyImpl() {}
+}
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/FactoryComponent.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/FactoryComponent.java
new file mode 100644
index 0000000..7d0a162
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/FactoryComponent.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import dagger.Component;
+
+/** A component to materialize the factory using Dagger 2 */
+@Component(modules = DaggerModule.class)
+interface FactoryComponent {
+  FooFactory factory();
+
+  GenericFooFactory<Number> generatedFactory();
+}
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/FactoryInterface.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/FactoryInterface.java
new file mode 100644
index 0000000..5f9d415
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/FactoryInterface.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+public interface FactoryInterface {
+  Foo generate(String name);
+}
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/Foo.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/Foo.java
new file mode 100644
index 0000000..3cc02d5
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/Foo.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import javax.inject.Provider;
+
+@AutoFactory(implementing = FactoryInterface.class)
+public final class Foo {
+  private final String name;
+  private final Dependency dependency;
+  private final Provider<Dependency> dependencyProvider;
+  private final int primitive;
+  private final int qualifiedPrimitive;
+
+  Foo(
+      String name,
+      @Provided Dependency dependency,
+      @Provided @Qualifier Provider<Dependency> dependencyProvider,
+      @Provided int primitive,
+      @Provided @Qualifier int qualifiedPrimitive) {
+    this.name = name;
+    this.dependency = dependency;
+    this.dependencyProvider = dependencyProvider;
+    this.primitive = primitive;
+    this.qualifiedPrimitive = qualifiedPrimitive;
+  }
+
+  // Generates second factory method with a different name for the Dependency dependency.
+  // Tests http://b/21632171.
+  Foo(
+      Object name,
+      @Provided Dependency dependency2,
+      @Provided @Qualifier Provider<Dependency> dependencyProvider,
+      @Provided int primitive,
+      @Provided @Qualifier int qualifiedPrimitive) {
+    this(name.toString(), dependency2, dependencyProvider, primitive, qualifiedPrimitive);
+  }
+
+  String name() {
+    return name;
+  }
+
+  Dependency dependency() {
+    return dependency;
+  }
+
+  Provider<Dependency> dependencyProvider() {
+    return dependencyProvider;
+  }
+
+  int primitive() {
+    return primitive;
+  }
+
+  int qualifiedPrimitive() {
+    return qualifiedPrimitive;
+  }
+}
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java
new file mode 100644
index 0000000..f7c13b4
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/GenericFoo.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import java.util.List;
+import javax.inject.Provider;
+
+@AutoFactory
+public class GenericFoo<A, B extends List<? extends A>, C, E extends Enum<E>> {
+
+  private final A depA;
+  private final B depB;
+  private final IntAccessor depDIntAccessor;
+  private final StringAccessor depDStringAccessor;
+  private final E depE;
+
+  <D extends IntAccessor & StringAccessor> GenericFoo(
+      @Provided Provider<A> depA,
+      B depB,
+      D depD,
+      E depE) {
+    this.depA = depA.get();
+    this.depB = depB;
+    this.depDIntAccessor = depD;
+    this.depDStringAccessor = depD;
+    this.depE = depE;
+  }
+
+  public A getDepA() {
+    return depA;
+  }
+
+  public B getDepB() {
+    return depB;
+  }
+
+  public C passThrough(C value) {
+    return value;
+  }
+
+  public IntAccessor getDepDIntAccessor() {
+    return depDIntAccessor;
+  }
+
+  public StringAccessor getDepDStringAccessor() {
+    return depDStringAccessor;
+  }
+
+  public E getDepE() {
+    return depE;
+  }
+
+  public interface IntAccessor {}
+
+  public interface StringAccessor {}
+
+  public interface IntAndStringAccessor extends IntAccessor, StringAccessor {}
+
+  public enum DepE {
+    VALUE_1,
+    VALUE_2
+  }
+}
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/GuiceModule.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/GuiceModule.java
new file mode 100644
index 0000000..45d4d26
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/GuiceModule.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import com.google.inject.AbstractModule;
+
+public class GuiceModule extends AbstractModule {
+  @Override protected void configure() {
+    bind(Dependency.class).to(DependencyImpl.class);
+    bind(Dependency.class).annotatedWith(Qualifier.class).to(QualifiedDependencyImpl.class);
+    bind(Integer.class).toInstance(1);
+    bind(Integer.class).annotatedWith(Qualifier.class).toInstance(2);
+    bind(Number.class).toInstance(3);
+  }
+}
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/QualifiedDependencyImpl.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/QualifiedDependencyImpl.java
new file mode 100644
index 0000000..ff36813
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/QualifiedDependencyImpl.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import javax.inject.Inject;
+
+public class QualifiedDependencyImpl implements Dependency {
+  @Inject
+  QualifiedDependencyImpl() {}
+}
diff --git a/factory/src/it/functional/src/main/java/com/google/auto/factory/Qualifier.java b/factory/src/it/functional/src/main/java/com/google/auto/factory/Qualifier.java
new file mode 100644
index 0000000..a1780e0
--- /dev/null
+++ b/factory/src/it/functional/src/main/java/com/google/auto/factory/Qualifier.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@javax.inject.Qualifier
+@Retention(RetentionPolicy.RUNTIME)
+@interface Qualifier {}
diff --git a/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java b/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java
new file mode 100644
index 0000000..ebd8336
--- /dev/null
+++ b/factory/src/it/functional/src/test/java/com/google/auto/factory/DependencyInjectionIntegrationTest.java
@@ -0,0 +1,112 @@
+package com.google.auto.factory;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.auto.factory.GenericFoo.DepE;
+import com.google.auto.factory.GenericFoo.IntAndStringAccessor;
+import com.google.common.collect.ImmutableList;
+import com.google.inject.Guice;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import java.util.ArrayList;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class DependencyInjectionIntegrationTest {
+
+  private static final IntAndStringAccessor INT_AND_STRING_ACCESSOR = new IntAndStringAccessor() {};
+
+  @Test public void daggerInjectedFactory() {
+    FooFactory fooFactory = DaggerFactoryComponent.create().factory();
+    Foo one = fooFactory.create("A");
+    Foo two = fooFactory.create("B");
+    assertThat(one.name()).isEqualTo("A");
+    assertThat(one.dependency()).isNotNull();
+    assertThat(one.dependencyProvider()).isNotNull();
+    assertThat(one.dependencyProvider().get()).isInstanceOf(QualifiedDependencyImpl.class);
+    assertThat(one.primitive()).isEqualTo(1);
+    assertThat(one.qualifiedPrimitive()).isEqualTo(2);
+    assertThat(two.name()).isEqualTo("B");
+    assertThat(two.dependency()).isNotNull();
+    assertThat(two.dependency()).isNotEqualTo(one.dependency());
+    assertThat(two.dependencyProvider()).isNotNull();
+    assertThat(two.dependencyProvider().get()).isInstanceOf(QualifiedDependencyImpl.class);
+    assertThat(two.primitive()).isEqualTo(1);
+    assertThat(two.qualifiedPrimitive()).isEqualTo(2);
+  }
+
+  @Test
+  public void daggerInjectedGenericFactory() {
+    GenericFooFactory<Number> genericFooFactory =
+        DaggerFactoryComponent.create().generatedFactory();
+    GenericFoo<Number, ImmutableList<Long>, String, DepE> three =
+        genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR, DepE.VALUE_1);
+    ArrayList<Double> intAndStringAccessorArrayList = new ArrayList<>();
+    intAndStringAccessorArrayList.add(4.0);
+    GenericFoo<Number, ArrayList<Double>, Long, DepE> four = genericFooFactory.create(
+        intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2);
+    assertThat(three.getDepA()).isEqualTo(3);
+    ImmutableList<Long> unusedLongList = three.getDepB();
+    assertThat(three.getDepB()).containsExactly(3L);
+    assertThat(three.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
+    assertThat(three.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
+    assertThat(three.passThrough("value")).isEqualTo("value");
+    assertThat(three.getDepE()).isEqualTo(DepE.VALUE_1);
+    assertThat(four.getDepA()).isEqualTo(3);
+    ArrayList<Double> unusedDoubleList = four.getDepB();
+    assertThat(four.getDepB()).isInstanceOf(ArrayList.class);
+    assertThat(four.getDepB()).containsExactly(4.0);
+    assertThat(four.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
+    assertThat(four.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
+    assertThat(four.passThrough(5L)).isEqualTo(5L);
+    assertThat(four.getDepE()).isEqualTo(DepE.VALUE_2);
+  }
+
+  @Test public void guiceInjectedFactory() {
+    FooFactory fooFactory = Guice.createInjector(new GuiceModule()).getInstance(FooFactory.class);
+    Foo one = fooFactory.create("A");
+    Foo two = fooFactory.create("B");
+    assertThat(one.name()).isEqualTo("A");
+    assertThat(one.dependency()).isNotNull();
+    assertThat(one.dependencyProvider()).isNotNull();
+    assertThat(one.dependencyProvider().get()).isInstanceOf(QualifiedDependencyImpl.class);
+    assertThat(one.primitive()).isEqualTo(1);
+    assertThat(one.qualifiedPrimitive()).isEqualTo(2);
+    assertThat(two.name()).isEqualTo("B");
+    assertThat(two.dependency()).isNotNull();
+    assertThat(two.dependency()).isNotEqualTo(one.dependency());
+    assertThat(two.dependencyProvider()).isNotNull();
+    assertThat(two.dependencyProvider().get()).isInstanceOf(QualifiedDependencyImpl.class);
+    assertThat(two.primitive()).isEqualTo(1);
+    assertThat(two.qualifiedPrimitive()).isEqualTo(2);
+  }
+
+  @Test
+  public void guiceInjectedGenericFactory() {
+    GenericFooFactory<Number> genericFooFactory =
+        Guice.createInjector(new GuiceModule())
+            .getInstance(Key.get(new TypeLiteral<GenericFooFactory<Number>>() {}));
+    GenericFoo<Number, ImmutableList<Long>, String, DepE> three =
+        genericFooFactory.create(ImmutableList.of(3L), INT_AND_STRING_ACCESSOR, DepE.VALUE_1);
+    ArrayList<Double> intAndStringAccessorArrayList = new ArrayList<>();
+    intAndStringAccessorArrayList.add(4.0);
+    GenericFoo<Number, ArrayList<Double>, Long, DepE> four = genericFooFactory.create(
+        intAndStringAccessorArrayList, INT_AND_STRING_ACCESSOR, DepE.VALUE_2);
+    assertThat(three.getDepA()).isEqualTo(3);
+    ImmutableList<Long> unusedLongList = three.getDepB();
+    assertThat(three.getDepB()).containsExactly(3L);
+    assertThat(three.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
+    assertThat(three.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
+    assertThat(three.passThrough("value")).isEqualTo("value");
+    assertThat(three.getDepE()).isEqualTo(DepE.VALUE_1);
+    assertThat(four.getDepA()).isEqualTo(3);
+    ArrayList<Double> unusedDoubleList = four.getDepB();
+    assertThat(four.getDepB()).containsExactly(4.0);
+    assertThat(four.getDepDIntAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
+    assertThat(four.getDepDStringAccessor()).isEqualTo(INT_AND_STRING_ACCESSOR);
+    assertThat(four.passThrough(5L)).isEqualTo(5L);
+    assertThat(four.getDepE()).isEqualTo(DepE.VALUE_2);
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/AutoFactory.java b/factory/src/main/java/com/google/auto/factory/AutoFactory.java
new file mode 100644
index 0000000..2ef84cc
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/AutoFactory.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Target;
+
+/**
+ * An annotation to be applied to elements for which a factory should be automatically generated.
+ *
+ * <h2>Visibility</h2>
+ * <p>The visibility of the generated factories will always be either {@code public} or default
+ * visibility. The visibility of any given factory method is determined by the visibility of the
+ * type being created. The generated factory is {@code public} if any of the factory methods are.
+ * Any method that implements an interface method is necessarily public and any method that
+ * overrides an abstract method has the same visibility as that method.
+ *
+ * @author Gregory Kick
+ */
+@Target({ TYPE, CONSTRUCTOR })
+public @interface AutoFactory {
+  /**
+   * The <i>simple</i> name of the generated factory; the factory is always generated in the same
+   * package as the annotated type.  The default value (the empty string) will result in a factory
+   * with the name of the type being created with {@code Factory} appended to the end. For example,
+   * the default name for a factory for {@code MyType} will be {@code MyTypeFactory}.
+   *
+   * <p>If the annotated type is nested, then the generated factory's name will start with the
+   * enclosing type names, separated by underscores. For example, the default name for a factory for
+   * {@code Outer.Inner.ReallyInner} is {@code Outer_Inner_ReallyInnerFactory}. If {@code className}
+   * is {@code Foo}, then the factory name is {@code Outer_Inner_Foo}.
+   */
+  String className() default "";
+
+  /**
+   * A list of interfaces that the generated factory is required to implement.
+   */
+  Class<?>[] implementing() default { };
+
+  /**
+   * The type that the generated factory is require to extend.
+   */
+  Class<?> extending() default Object.class;
+
+  /**
+   * Whether or not the generated factory should be final.
+   * Defaults to disallowing subclasses (generating the factory as final).
+   */
+  boolean allowSubclasses() default false;
+}
diff --git a/factory/src/main/java/com/google/auto/factory/Provided.java b/factory/src/main/java/com/google/auto/factory/Provided.java
new file mode 100644
index 0000000..e81e4aa
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/Provided.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory;
+
+import static java.lang.annotation.ElementType.PARAMETER;
+
+import java.lang.annotation.Target;
+
+/**
+ * An annotation to be applied to parameters that should be provided by an
+ * {@linkplain javax.inject.Inject injected} {@link javax.inject.Provider} in a generated factory.
+ *
+ * @author Gregory Kick
+ */
+@Target(PARAMETER)
+public @interface Provided { }
diff --git a/factory/src/main/java/com/google/auto/factory/processor/AnnotationValues.java b/factory/src/main/java/com/google/auto/factory/processor/AnnotationValues.java
new file mode 100644
index 0000000..b767c47
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/AnnotationValues.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import java.util.List;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.SimpleAnnotationValueVisitor6;
+import javax.lang.model.util.SimpleTypeVisitor6;
+
+final class AnnotationValues {
+  private AnnotationValues() {}
+
+  static boolean asBoolean(AnnotationValue value) {
+    return value.accept(
+        new SimpleAnnotationValueVisitor6<Boolean, Void>() {
+          @Override protected Boolean defaultAction(Object o, Void p) {
+            throw new IllegalArgumentException();
+          }
+
+          @Override public Boolean visitBoolean(boolean b, Void p) {
+            return b;
+          }
+        }, null);
+  }
+
+  static TypeElement asType(AnnotationValue value) {
+    return value.accept(
+        new SimpleAnnotationValueVisitor6<TypeElement, Void>() {
+          @Override protected TypeElement defaultAction(Object o, Void p) {
+            throw new IllegalArgumentException();
+          }
+
+          @Override public TypeElement visitType(TypeMirror t, Void p) {
+            return t.accept(
+                new SimpleTypeVisitor6<TypeElement, Void>() {
+                  @Override
+                  protected TypeElement defaultAction(TypeMirror e, Void p) {
+                    throw new AssertionError();
+                  }
+
+                  @Override
+                  public TypeElement visitDeclared(DeclaredType t, Void p) {
+                    return Iterables.getOnlyElement(ElementFilter.typesIn(
+                        ImmutableList.of(t.asElement())));
+                  }
+                }, null);
+          }
+        }, null);
+  }
+
+  static ImmutableList<? extends AnnotationValue> asList(AnnotationValue value) {
+    return value.accept(
+        new SimpleAnnotationValueVisitor6<ImmutableList<? extends AnnotationValue>, Void>() {
+          @Override
+          protected ImmutableList<? extends AnnotationValue> defaultAction(Object o, Void p) {
+            throw new IllegalArgumentException();
+          }
+
+          @Override
+          public ImmutableList<? extends AnnotationValue> visitArray(
+              List<? extends AnnotationValue> vals, Void p) {
+            return ImmutableList.copyOf(vals);
+          }
+        }, null);
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java
new file mode 100644
index 0000000..ad4ccb8
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryDeclaration.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.auto.common.MoreElements.getPackage;
+import static com.google.auto.factory.processor.Elements2.isValidSupertypeForClass;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static javax.lang.model.element.ElementKind.PACKAGE;
+import static javax.lang.model.util.ElementFilter.typesIn;
+import static javax.tools.Diagnostic.Kind.ERROR;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.processing.Messager;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+
+/**
+ * This is a value object that mirrors the static declaration of an {@link AutoFactory} annotation.
+ *
+ * @author Gregory Kick
+ */
+@AutoValue
+abstract class AutoFactoryDeclaration {
+  abstract TypeElement targetType();
+  abstract Element target();
+  abstract Optional<String> className();
+  abstract TypeElement extendingType();
+  abstract ImmutableSet<TypeElement> implementingTypes();
+  abstract boolean allowSubclasses();
+  abstract AnnotationMirror mirror();
+  abstract ImmutableMap<String, AnnotationValue> valuesMap();
+
+  String getFactoryName() {
+    CharSequence packageName = getPackage(targetType()).getQualifiedName();
+    StringBuilder builder = new StringBuilder(packageName);
+    if (packageName.length() > 0) {
+      builder.append('.');
+    }
+    if (className().isPresent()) {
+      builder.append(className().get());
+    } else {
+      for (String enclosingSimpleName : targetEnclosingSimpleNames()) {
+        builder.append(enclosingSimpleName).append('_');
+      }
+      builder.append(targetType().getSimpleName()).append("Factory");
+    }
+    return builder.toString();
+  }
+
+  private ImmutableList<String> targetEnclosingSimpleNames() {
+    ImmutableList.Builder<String> simpleNames = ImmutableList.builder();
+    for (Element element = targetType().getEnclosingElement();
+        !element.getKind().equals(PACKAGE);
+        element = element.getEnclosingElement()) {
+      simpleNames.add(element.getSimpleName().toString());
+    }
+    return simpleNames.build().reverse();
+  }
+
+  static final class Factory {
+    private final Elements elements;
+    private final Messager messager;
+
+    Factory(Elements elements, Messager messager) {
+      this.elements = elements;
+      this.messager = messager;
+    }
+
+    Optional<AutoFactoryDeclaration> createIfValid(Element element) {
+      checkNotNull(element);
+      AnnotationMirror mirror = Mirrors.getAnnotationMirror(element, AutoFactory.class).get();
+      checkArgument(Mirrors.getQualifiedName(mirror.getAnnotationType()).
+          contentEquals(AutoFactory.class.getName()));
+      Map<String, AnnotationValue> values =
+          Mirrors.simplifyAnnotationValueMap(elements.getElementValuesWithDefaults(mirror));
+      checkState(values.size() == 4);
+
+      // className value is a string, so we can just call toString
+      AnnotationValue classNameValue = values.get("className");
+      String className = classNameValue.getValue().toString();
+      if (!className.isEmpty() && !isValidIdentifier(className)) {
+        messager.printMessage(ERROR,
+            String.format("\"%s\" is not a valid Java identifier", className),
+            element, mirror, classNameValue);
+        return Optional.absent();
+      }
+
+      AnnotationValue extendingValue = checkNotNull(values.get("extending"));
+      TypeElement extendingType = AnnotationValues.asType(extendingValue);
+      if (extendingType == null) {
+        messager.printMessage(ERROR, "Unable to find the type: "
+            + extendingValue.getValue().toString(),
+                element, mirror, extendingValue);
+        return Optional.absent();
+      } else if (!isValidSupertypeForClass(extendingType)) {
+        messager.printMessage(ERROR,
+            String.format("%s is not a valid supertype for a factory. "
+                + "Supertypes must be non-final classes.",
+                    extendingType.getQualifiedName()),
+            element, mirror, extendingValue);
+        return Optional.absent();
+      }
+      ImmutableList<ExecutableElement> noParameterConstructors =
+          FluentIterable.from(ElementFilter.constructorsIn(extendingType.getEnclosedElements()))
+              .filter(new Predicate<ExecutableElement>() {
+                @Override public boolean apply(ExecutableElement constructor) {
+                  return constructor.getParameters().isEmpty();
+                }
+              })
+              .toList();
+      if (noParameterConstructors.size() == 0) {
+        messager.printMessage(ERROR,
+            String.format("%s is not a valid supertype for a factory. "
+                + "Factory supertypes must have a no-arg constructor.",
+                    extendingType.getQualifiedName()),
+            element, mirror, extendingValue);
+        return Optional.absent();
+      } else if (noParameterConstructors.size() > 1) {
+        throw new IllegalStateException("Multiple constructors with no parameters??");
+      }
+
+      AnnotationValue implementingValue = checkNotNull(values.get("implementing"));
+      ImmutableSet.Builder<TypeElement> builder = ImmutableSet.builder();
+      for (AnnotationValue implementingTypeValue : AnnotationValues.asList(implementingValue)) {
+        builder.add(AnnotationValues.asType(implementingTypeValue));
+      }
+      ImmutableSet<TypeElement> implementingTypes = builder.build();
+
+      AnnotationValue allowSubclassesValue = checkNotNull(values.get("allowSubclasses"));
+      boolean allowSubclasses = AnnotationValues.asBoolean(allowSubclassesValue);
+
+      return Optional.<AutoFactoryDeclaration>of(
+          new AutoValue_AutoFactoryDeclaration(
+              getAnnotatedType(element),
+              element,
+              className.isEmpty() ? Optional.<String>absent() : Optional.of(className),
+              extendingType,
+              implementingTypes,
+              allowSubclasses,
+              mirror,
+              ImmutableMap.copyOf(values)));
+    }
+
+    private static TypeElement getAnnotatedType(Element element) {
+      List<TypeElement> types = ImmutableList.of();
+      while (types.isEmpty()) {
+        types = typesIn(Arrays.asList(element));
+        element = element.getEnclosingElement();
+      }
+      return getOnlyElement(types);
+    }
+
+    static boolean isValidIdentifier(String identifier) {
+      return SourceVersion.isIdentifier(identifier) && !SourceVersion.isKeyword(identifier);
+    }
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java
new file mode 100644
index 0000000..cf3d5eb
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/AutoFactoryProcessor.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import com.google.auto.service.AutoService;
+import com.google.common.base.Optional;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Iterables;
+import com.google.googlejavaformat.java.filer.FormattingFiler;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic.Kind;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;
+
+/**
+ * The annotation processor that generates factories for {@link AutoFactory} annotations.
+ *
+ * @author Gregory Kick
+ */
+@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)
+@AutoService(Processor.class)
+public final class AutoFactoryProcessor extends AbstractProcessor {
+  private FactoryDescriptorGenerator factoryDescriptorGenerator;
+  private AutoFactoryDeclaration.Factory declarationFactory;
+  private ProvidedChecker providedChecker;
+  private Messager messager;
+  private Elements elements;
+  private Types types;
+  private FactoryWriter factoryWriter;
+
+  @Override
+  public synchronized void init(ProcessingEnvironment processingEnv) {
+    super.init(processingEnv);
+    elements = processingEnv.getElementUtils();
+    types = processingEnv.getTypeUtils();
+    messager = processingEnv.getMessager();
+    factoryWriter =
+        new FactoryWriter(
+            new FormattingFiler(processingEnv.getFiler()),
+            elements,
+            processingEnv.getSourceVersion());
+    providedChecker = new ProvidedChecker(messager);
+    declarationFactory = new AutoFactoryDeclaration.Factory(elements, messager);
+    factoryDescriptorGenerator =
+        new FactoryDescriptorGenerator(messager, types, declarationFactory);
+  }
+
+  @Override
+  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    try {
+      doProcess(roundEnv);
+    } catch (Throwable e) {
+      messager.printMessage(Kind.ERROR, "Failed to process @AutoFactory annotations:\n"
+          + Throwables.getStackTraceAsString(e));
+    }
+    return false;
+  }
+
+  private void doProcess(RoundEnvironment roundEnv) {
+    for (Element element : roundEnv.getElementsAnnotatedWith(Provided.class)) {
+      providedChecker.checkProvidedParameter(element);
+    }
+
+    ImmutableListMultimap.Builder<String, FactoryMethodDescriptor> indexedMethods =
+        ImmutableListMultimap.builder();
+    ImmutableSetMultimap.Builder<String, ImplementationMethodDescriptor>
+        implementationMethodDescriptorsBuilder = ImmutableSetMultimap.builder();
+    for (Element element : roundEnv.getElementsAnnotatedWith(AutoFactory.class)) {
+      Optional<AutoFactoryDeclaration> declaration = declarationFactory.createIfValid(element);
+      if (declaration.isPresent()) {
+        String factoryName = declaration.get().getFactoryName();
+        TypeElement extendingType = declaration.get().extendingType();
+        implementationMethodDescriptorsBuilder.putAll(
+            factoryName, implementationMethods(extendingType, element));
+        for (TypeElement implementingType : declaration.get().implementingTypes()) {
+          implementationMethodDescriptorsBuilder.putAll(
+              factoryName, implementationMethods(implementingType, element));
+        }
+      }
+
+      ImmutableSet<FactoryMethodDescriptor> descriptors =
+          factoryDescriptorGenerator.generateDescriptor(element);
+      for (FactoryMethodDescriptor descriptor : descriptors) {
+        indexedMethods.put(descriptor.factoryName(), descriptor);
+      }
+    }
+
+    ImmutableSetMultimap<String, ImplementationMethodDescriptor>
+        implementationMethodDescriptors = implementationMethodDescriptorsBuilder.build();
+
+    for (Entry<String, Collection<FactoryMethodDescriptor>> entry
+        : indexedMethods.build().asMap().entrySet()) {
+      ImmutableSet.Builder<TypeMirror> extending = ImmutableSet.builder();
+      ImmutableSortedSet.Builder<TypeMirror> implementing =
+          ImmutableSortedSet.orderedBy(
+              new Comparator<TypeMirror>() {
+                @Override
+                public int compare(TypeMirror first, TypeMirror second) {
+                  String firstName = MoreTypes.asTypeElement(first).getQualifiedName().toString();
+                  String secondName = MoreTypes.asTypeElement(second).getQualifiedName().toString();
+                  return firstName.compareTo(secondName);
+                }
+              });
+      boolean publicType = false;
+      Boolean allowSubclasses = null;
+      boolean skipCreation = false;
+      for (FactoryMethodDescriptor methodDescriptor : entry.getValue()) {
+        extending.add(methodDescriptor.declaration().extendingType().asType());
+        for (TypeElement implementingType : methodDescriptor.declaration().implementingTypes()) {
+          implementing.add(implementingType.asType());
+        }
+        publicType |= methodDescriptor.publicMethod();
+        if (allowSubclasses == null) {
+          allowSubclasses = methodDescriptor.declaration().allowSubclasses();
+        } else if (!allowSubclasses.equals(methodDescriptor.declaration().allowSubclasses())) {
+          skipCreation = true;
+          messager.printMessage(Kind.ERROR,
+              "Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.",
+              methodDescriptor.declaration().target(),
+              methodDescriptor.declaration().mirror(),
+              methodDescriptor.declaration().valuesMap().get("allowSubclasses"));
+        }
+      }
+      if (!skipCreation) {
+        try {
+          factoryWriter.writeFactory(
+              FactoryDescriptor.create(
+                  entry.getKey(),
+                  Iterables.getOnlyElement(extending.build()),
+                  implementing.build(),
+                  publicType,
+                  ImmutableSet.copyOf(entry.getValue()),
+                  implementationMethodDescriptors.get(entry.getKey()),
+                  allowSubclasses));
+        } catch (IOException e) {
+          messager.printMessage(Kind.ERROR, "failed: " + e);
+        }
+      }
+    }
+  }
+
+  private ImmutableSet<ImplementationMethodDescriptor> implementationMethods(
+      TypeElement supertype, Element autoFactoryElement) {
+    ImmutableSet.Builder<ImplementationMethodDescriptor> implementationMethodsBuilder =
+        ImmutableSet.builder();
+    for (ExecutableElement implementationMethod :
+        ElementFilter.methodsIn(elements.getAllMembers(supertype))) {
+      if (implementationMethod.getModifiers().contains(Modifier.ABSTRACT)) {
+        ExecutableType methodType =
+            Elements2.getExecutableElementAsMemberOf(
+                types, implementationMethod, supertype);
+        ImmutableSet<Parameter> passedParameters =
+            Parameter.forParameterList(
+                implementationMethod.getParameters(), methodType.getParameterTypes(), types);
+        implementationMethodsBuilder.add(
+            ImplementationMethodDescriptor.builder()
+                .name(implementationMethod.getSimpleName().toString())
+                .returnType(getAnnotatedType(autoFactoryElement))
+                .publicMethod()
+                .passedParameters(passedParameters)
+                .isVarArgs(implementationMethod.isVarArgs())
+                .build());
+      }
+    }
+    return implementationMethodsBuilder.build();
+  }
+
+  private TypeMirror getAnnotatedType(Element element) {
+    List<TypeElement> types = ImmutableList.of();
+    while (types.isEmpty()) {
+      types = ElementFilter.typesIn(Arrays.asList(element));
+      element = element.getEnclosingElement();
+    }
+    return Iterables.getOnlyElement(types).asType();
+  }
+
+  @Override
+  public Set<String> getSupportedAnnotationTypes() {
+    return ImmutableSet.of(AutoFactory.class.getName(), Provided.class.getName());
+  }
+
+  @Override
+  public SourceVersion getSupportedSourceVersion() {
+    return SourceVersion.latestSupported();
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/Elements2.java b/factory/src/main/java/com/google/auto/factory/processor/Elements2.java
new file mode 100644
index 0000000..30230f7
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/Elements2.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.lang.model.element.ElementKind.CLASS;
+import static javax.lang.model.element.ElementKind.PACKAGE;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.STATIC;
+
+import com.google.common.collect.ImmutableSet;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Types;
+
+final class Elements2 {
+  private Elements2() { }
+
+  static ImmutableSet<ExecutableElement> getConstructors(TypeElement type) {
+    checkNotNull(type);
+    checkArgument(type.getKind() == CLASS);
+    return ImmutableSet.copyOf(ElementFilter.constructorsIn(type.getEnclosedElements()));
+  }
+
+  static boolean isValidSupertypeForClass(TypeElement type) {
+    if (!type.getKind().equals(CLASS)) {
+      return false;
+    }
+    if (type.getModifiers().contains(FINAL)) {
+      return false;
+    }
+    if (!type.getEnclosingElement().getKind().equals(PACKAGE)
+        && !type.getModifiers().contains(STATIC)) {
+      return false;
+    }
+    if (type.getSimpleName().length() == 0) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Given an executable element in a supertype, returns its ExecutableType when it is viewed as a
+   * member of a subtype.
+   */
+  static ExecutableType getExecutableElementAsMemberOf(
+      Types types, ExecutableElement executableElement, TypeElement subTypeElement) {
+    checkNotNull(types);
+    checkNotNull(executableElement);
+    checkNotNull(subTypeElement);
+    TypeMirror subTypeMirror = subTypeElement.asType();
+    if (!subTypeMirror.getKind().equals(TypeKind.DECLARED)) {
+      throw new IllegalStateException(
+          "Expected subTypeElement.asType() to return a class/interface type.");
+    }
+    TypeMirror subExecutableTypeMirror = types.asMemberOf(
+        (DeclaredType) subTypeMirror, executableElement);
+    if (!subExecutableTypeMirror.getKind().equals(TypeKind.EXECUTABLE)) {
+      throw new IllegalStateException("Expected subExecutableTypeMirror to be an executable type.");
+    }
+    return (ExecutableType) subExecutableTypeMirror;
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java
new file mode 100644
index 0000000..68ae678
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptor.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.base.CharMatcher;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSetMultimap;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map.Entry;
+import java.util.Set;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A value object representing a factory to be generated.
+ *
+ * @author Gregory Kick
+ */
+@AutoValue
+abstract class FactoryDescriptor {
+  private static final CharMatcher invalidIdentifierCharacters =
+      new CharMatcher() {
+        @Override
+        public boolean matches(char c) {
+          return !Character.isJavaIdentifierPart(c);
+        }
+      };
+
+  abstract String name();
+  abstract TypeMirror extendingType();
+  abstract ImmutableSet<TypeMirror> implementingTypes();
+  abstract boolean publicType();
+  abstract ImmutableSet<FactoryMethodDescriptor> methodDescriptors();
+  abstract ImmutableSet<ImplementationMethodDescriptor> implementationMethodDescriptors();
+  abstract boolean allowSubclasses();
+  abstract ImmutableMap<Key, ProviderField> providers();
+
+  final AutoFactoryDeclaration declaration() {
+    return Iterables.getFirst(methodDescriptors(), null).declaration();
+  }
+
+  private static class UniqueNameSet {
+    private final Set<String> uniqueNames = new HashSet<String>();
+
+    /**
+     * Generates a unique name using {@code base}. If {@code base} has not yet been added, it will
+     * be returned as-is. If your {@code base} is healthy, this will always return {@code base}.
+     */
+    String getUniqueName(CharSequence base) {
+      String name = base.toString();
+      for (int differentiator = 2; !uniqueNames.add(name); differentiator++) {
+        name = base.toString() + differentiator;
+      }
+      return name;
+    }
+  }
+
+  static FactoryDescriptor create(
+      String name,
+      TypeMirror extendingType,
+      ImmutableSet<TypeMirror> implementingTypes,
+      boolean publicType,
+      ImmutableSet<FactoryMethodDescriptor> methodDescriptors,
+      ImmutableSet<ImplementationMethodDescriptor> implementationMethodDescriptors,
+      boolean allowSubclasses) {
+    ImmutableSetMultimap.Builder<Key, Parameter> parametersForProviders =
+        ImmutableSetMultimap.builder();
+    for (FactoryMethodDescriptor descriptor : methodDescriptors) {
+      for (Parameter parameter : descriptor.providedParameters()) {
+        parametersForProviders.put(parameter.key(), parameter);
+      }
+    }
+    ImmutableMap.Builder<Key, ProviderField> providersBuilder = ImmutableMap.builder();
+    UniqueNameSet uniqueNames = new UniqueNameSet();
+    for (Entry<Key, Collection<Parameter>> entry :
+        parametersForProviders.build().asMap().entrySet()) {
+      Key key = entry.getKey();
+      switch (entry.getValue().size()) {
+        case 0:
+          throw new AssertionError();
+        case 1:
+          Parameter parameter = Iterables.getOnlyElement(entry.getValue());
+          providersBuilder.put(
+              key,
+              ProviderField.create(
+                  uniqueNames.getUniqueName(parameter.name() + "Provider"),
+                  key,
+                  parameter.nullable()));
+          break;
+        default:
+          String providerName =
+              uniqueNames.getUniqueName(
+                  invalidIdentifierCharacters.replaceFrom(key.toString(), '_') + "Provider");
+          Optional<AnnotationMirror> nullable = Optional.absent();
+          for (Parameter param : entry.getValue()) {
+            nullable = nullable.or(param.nullable());
+          }
+          providersBuilder.put(key, ProviderField.create(providerName, key, nullable));
+          break;
+      }
+    }
+
+    ImmutableBiMap<FactoryMethodDescriptor, ImplementationMethodDescriptor>
+        duplicateMethodDescriptors =
+            createDuplicateMethodDescriptorsBiMap(
+                methodDescriptors, implementationMethodDescriptors);
+
+    ImmutableSet<FactoryMethodDescriptor> deduplicatedMethodDescriptors =
+        getDeduplicatedMethodDescriptors(methodDescriptors, duplicateMethodDescriptors);
+
+    ImmutableSet<ImplementationMethodDescriptor> deduplicatedImplementationMethodDescriptors =
+        ImmutableSet.copyOf(
+            Sets.difference(implementationMethodDescriptors, duplicateMethodDescriptors.values()));
+
+    return new AutoValue_FactoryDescriptor(
+        name,
+        extendingType,
+        implementingTypes,
+        publicType,
+        deduplicatedMethodDescriptors,
+        deduplicatedImplementationMethodDescriptors,
+        allowSubclasses,
+        providersBuilder.build());
+  }
+
+  /**
+   * Creates a bi-map of duplicate {@link ImplementationMethodDescriptor}s by their respective
+   * {@link FactoryMethodDescriptor}.
+   */
+  private static ImmutableBiMap<FactoryMethodDescriptor, ImplementationMethodDescriptor>
+      createDuplicateMethodDescriptorsBiMap(
+          ImmutableSet<FactoryMethodDescriptor> factoryMethodDescriptors,
+          ImmutableSet<ImplementationMethodDescriptor> implementationMethodDescriptors) {
+
+    ImmutableBiMap.Builder<FactoryMethodDescriptor, ImplementationMethodDescriptor> builder =
+        ImmutableBiMap.builder();
+
+    for (FactoryMethodDescriptor factoryMethodDescriptor : factoryMethodDescriptors) {
+      for (ImplementationMethodDescriptor implementationMethodDescriptor :
+          implementationMethodDescriptors) {
+
+        boolean areDuplicateMethodDescriptors =
+            areDuplicateMethodDescriptors(factoryMethodDescriptor, implementationMethodDescriptor);
+        if (areDuplicateMethodDescriptors) {
+          builder.put(factoryMethodDescriptor, implementationMethodDescriptor);
+          break;
+        }
+      }
+    }
+
+    return builder.build();
+  }
+
+  /**
+   * Returns a set of deduplicated {@link FactoryMethodDescriptor}s from the set of original
+   * descriptors and the bi-map of duplicate descriptors.
+   *
+   * <p>Modifies the duplicate {@link FactoryMethodDescriptor}s such that they are overriding and
+   * reflect properties from the {@link ImplementationMethodDescriptor} they are implementing.
+   */
+  private static ImmutableSet<FactoryMethodDescriptor> getDeduplicatedMethodDescriptors(
+      ImmutableSet<FactoryMethodDescriptor> methodDescriptors,
+      ImmutableBiMap<FactoryMethodDescriptor, ImplementationMethodDescriptor>
+          duplicateMethodDescriptors) {
+
+    ImmutableSet.Builder<FactoryMethodDescriptor> deduplicatedMethodDescriptors =
+        ImmutableSet.builder();
+
+    for (FactoryMethodDescriptor methodDescriptor : methodDescriptors) {
+      ImplementationMethodDescriptor duplicateMethodDescriptor =
+          duplicateMethodDescriptors.get(methodDescriptor);
+
+      FactoryMethodDescriptor newMethodDescriptor =
+         (duplicateMethodDescriptor != null)
+              ? methodDescriptor
+                  .toBuilder()
+                  .overridingMethod(true)
+                  .publicMethod(duplicateMethodDescriptor.publicMethod())
+                  .returnType(duplicateMethodDescriptor.returnType())
+                  .build()
+              : methodDescriptor;
+      deduplicatedMethodDescriptors.add(newMethodDescriptor);
+    }
+
+    return deduplicatedMethodDescriptors.build();
+  }
+
+  /**
+   * Returns true if the given {@link FactoryMethodDescriptor} and
+   * {@link ImplementationMethodDescriptor} are duplicates.
+   *
+   * <p>Descriptors are duplicates if they have the same name and if they have the same passed types
+   * in the same order.
+   */
+  private static boolean areDuplicateMethodDescriptors(
+      FactoryMethodDescriptor factory,
+      ImplementationMethodDescriptor implementation) {
+
+    if (!factory.name().equals(implementation.name())) {
+      return false;
+    }
+
+    // Descriptors are identical if they have the same passed types in the same order.
+    return Iterables.elementsEqual(
+        Iterables.transform(factory.passedParameters(), Parameter::type),
+        Iterables.transform(implementation.passedParameters(), Parameter::type));
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java
new file mode 100644
index 0000000..d2331f4
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryDescriptorGenerator.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.tools.Diagnostic.Kind.ERROR;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import com.google.common.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimaps;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.ElementKindVisitor6;
+import javax.lang.model.util.Types;
+
+/**
+ * A service that traverses an element and returns the set of factory methods defined therein.
+ *
+ * @author Gregory Kick
+ */
+final class FactoryDescriptorGenerator {
+  private final Messager messager;
+  private final Types types;
+  private final AutoFactoryDeclaration.Factory declarationFactory;
+
+  FactoryDescriptorGenerator(
+      Messager messager,
+      Types types,
+      AutoFactoryDeclaration.Factory declarationFactory) {
+    this.messager = messager;
+    this.types = types;
+    this.declarationFactory = declarationFactory;
+  }
+
+  ImmutableSet<FactoryMethodDescriptor> generateDescriptor(Element element) {
+    final AnnotationMirror mirror = Mirrors.getAnnotationMirror(element, AutoFactory.class).get();
+    final Optional<AutoFactoryDeclaration> declaration = declarationFactory.createIfValid(element);
+    if (!declaration.isPresent()) {
+      return ImmutableSet.of();
+    }
+    return element.accept(new ElementKindVisitor6<ImmutableSet<FactoryMethodDescriptor>, Void>() {
+      @Override
+      protected ImmutableSet<FactoryMethodDescriptor> defaultAction(Element e, Void p) {
+        throw new AssertionError("@AutoFactory applied to an impossible element");
+      }
+
+      @Override
+      public ImmutableSet<FactoryMethodDescriptor> visitTypeAsClass(TypeElement type, Void p) {
+        if (type.getModifiers().contains(ABSTRACT)) {
+          // applied to an abstract factory
+          messager.printMessage(ERROR,
+              "Auto-factory doesn't support being applied to abstract classes.", type, mirror);
+          return ImmutableSet.of();
+        } else {
+          // applied to the type to be created
+          ImmutableSet<ExecutableElement> constructors = Elements2.getConstructors(type);
+          if (constructors.isEmpty()) {
+            return generateDescriptorForDefaultConstructor(declaration.get(), type);
+          } else {
+            return FluentIterable.from(constructors)
+                .transform(new Function<ExecutableElement, FactoryMethodDescriptor>() {
+                  @Override public FactoryMethodDescriptor apply(ExecutableElement constructor) {
+                    return generateDescriptorForConstructor(declaration.get(), constructor);
+                  }
+                })
+                .toSet();
+          }
+        }
+      }
+
+      @Override
+      public ImmutableSet<FactoryMethodDescriptor> visitTypeAsInterface(TypeElement type, Void p) {
+        // applied to the factory interface
+        messager.printMessage(ERROR,
+            "Auto-factory doesn't support being applied to interfaces.", type, mirror);
+        return ImmutableSet.of();
+      }
+
+      @Override
+      public ImmutableSet<FactoryMethodDescriptor> visitExecutableAsConstructor(ExecutableElement e,
+          Void p) {
+        // applied to a constructor of a type to be created
+        return ImmutableSet.of(generateDescriptorForConstructor(declaration.get(), e));
+      }
+    }, null);
+  }
+
+  FactoryMethodDescriptor generateDescriptorForConstructor(final AutoFactoryDeclaration declaration,
+      ExecutableElement constructor) {
+    checkNotNull(constructor);
+    checkArgument(constructor.getKind() == ElementKind.CONSTRUCTOR);
+    TypeElement classElement = MoreElements.asType(constructor.getEnclosingElement());
+    ImmutableListMultimap<Boolean, ? extends VariableElement> parameterMap =
+        Multimaps.index(constructor.getParameters(), Functions.forPredicate(
+            new Predicate<VariableElement>() {
+              @Override
+              public boolean apply(VariableElement parameter) {
+                return isAnnotationPresent(parameter, Provided.class);
+              }
+            }));
+    ImmutableSet<Parameter> providedParameters =
+        Parameter.forParameterList(parameterMap.get(true), types);
+    ImmutableSet<Parameter> passedParameters =
+        Parameter.forParameterList(parameterMap.get(false), types);
+    return FactoryMethodDescriptor.builder(declaration)
+        .name("create")
+        .returnType(classElement.asType())
+        .publicMethod(classElement.getModifiers().contains(PUBLIC))
+        .providedParameters(providedParameters)
+        .passedParameters(passedParameters)
+        .creationParameters(Parameter.forParameterList(constructor.getParameters(), types))
+        .isVarArgs(constructor.isVarArgs())
+        .build();
+  }
+
+  private ImmutableSet<FactoryMethodDescriptor> generateDescriptorForDefaultConstructor(
+      AutoFactoryDeclaration declaration, TypeElement type) {
+    return ImmutableSet.of(
+        FactoryMethodDescriptor.builder(declaration)
+            .name("create")
+            .returnType(type.asType())
+            .publicMethod(type.getModifiers().contains(PUBLIC))
+            .passedParameters(ImmutableSet.<Parameter>of())
+            .creationParameters(ImmutableSet.<Parameter>of())
+            .providedParameters(ImmutableSet.<Parameter>of())
+            .build());
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryMethodDescriptor.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryMethodDescriptor.java
new file mode 100644
index 0000000..c3a0159
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryMethodDescriptor.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A value object representing a factory method to be generated.
+ *
+ * @author Gregory Kick
+ */
+@AutoValue
+abstract class FactoryMethodDescriptor {
+  abstract AutoFactoryDeclaration declaration();
+  abstract String name();
+  abstract TypeMirror returnType();
+  abstract boolean publicMethod();
+  abstract boolean overridingMethod();
+  abstract ImmutableSet<Parameter> passedParameters();
+  abstract ImmutableSet<Parameter> providedParameters();
+  abstract ImmutableSet<Parameter> creationParameters();
+  abstract Builder toBuilder();
+  abstract boolean isVarArgs();
+
+  final String factoryName() {
+    return declaration().getFactoryName();
+  }
+
+  static Builder builder(AutoFactoryDeclaration declaration) {
+    return new AutoValue_FactoryMethodDescriptor.Builder()
+        .declaration(checkNotNull(declaration))
+        .publicMethod(false)
+        .overridingMethod(false)
+        .isVarArgs(false);
+  }
+
+  @AutoValue.Builder
+  static abstract class Builder {
+    abstract Builder declaration(AutoFactoryDeclaration declaration);
+    abstract Builder name(String name);
+    abstract Builder returnType(TypeMirror returnType);
+    abstract Builder publicMethod(boolean publicMethod);
+    abstract Builder overridingMethod(boolean overridingMethod);
+    abstract Builder passedParameters(Iterable<Parameter> passedParameters);
+    abstract Builder providedParameters(Iterable<Parameter> providedParameters);
+    abstract Builder creationParameters(Iterable<Parameter> creationParameters);
+    abstract Builder isVarArgs(boolean isVarargs);
+    abstract FactoryMethodDescriptor buildImpl();
+
+    FactoryMethodDescriptor build() {
+      FactoryMethodDescriptor descriptor = buildImpl();
+      checkState(descriptor.creationParameters().equals(
+          Sets.union(descriptor.passedParameters(), descriptor.providedParameters())));
+      return descriptor;
+    }
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java b/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java
new file mode 100644
index 0000000..3bb68e1
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/FactoryWriter.java
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotationSpec;
+import static com.squareup.javapoet.MethodSpec.constructorBuilder;
+import static com.squareup.javapoet.MethodSpec.methodBuilder;
+import static com.squareup.javapoet.TypeSpec.classBuilder;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.lang.model.element.Modifier.STATIC;
+
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeVariableName;
+import java.io.IOException;
+import java.util.Iterator;
+import javax.annotation.processing.Filer;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.util.Elements;
+
+final class FactoryWriter {
+
+  private final Filer filer;
+  private final Elements elements;
+  private final SourceVersion sourceVersion;
+
+  FactoryWriter(Filer filer, Elements elements, SourceVersion sourceVersion) {
+    this.filer = filer;
+    this.elements = elements;
+    this.sourceVersion = sourceVersion;
+  }
+
+  private static final Joiner ARGUMENT_JOINER = Joiner.on(", ");
+
+  void writeFactory(final FactoryDescriptor descriptor)
+      throws IOException {
+    String factoryName = getSimpleName(descriptor.name()).toString();
+    TypeSpec.Builder factory =
+        classBuilder(factoryName)
+            .addOriginatingElement(descriptor.declaration().targetType());
+    generatedAnnotationSpec(
+            elements,
+            sourceVersion,
+            AutoFactoryProcessor.class,
+            "https://github.com/google/auto/tree/master/factory")
+        .ifPresent(factory::addAnnotation);
+    if (!descriptor.allowSubclasses()) {
+      factory.addModifiers(FINAL);
+    }
+    if (descriptor.publicType()) {
+      factory.addModifiers(PUBLIC);
+    }
+
+    factory.superclass(TypeName.get(descriptor.extendingType()));
+    for (TypeMirror implementingType : descriptor.implementingTypes()) {
+      factory.addSuperinterface(TypeName.get(implementingType));
+    }
+
+    ImmutableSet<TypeVariableName> factoryTypeVariables = getFactoryTypeVariables(descriptor);
+
+    addFactoryTypeParameters(factory, factoryTypeVariables);
+    addConstructorAndProviderFields(factory, descriptor);
+    addFactoryMethods(factory, descriptor, factoryTypeVariables);
+    addImplementationMethods(factory, descriptor);
+    addCheckNotNullMethod(factory, descriptor);
+
+    JavaFile.builder(getPackage(descriptor.name()), factory.build())
+        .skipJavaLangImports(true)
+        .build()
+        .writeTo(filer);
+  }
+
+  private static void addFactoryTypeParameters(
+      TypeSpec.Builder factory, ImmutableSet<TypeVariableName> typeVariableNames) {
+    factory.addTypeVariables(typeVariableNames);
+  }
+
+  private static void addConstructorAndProviderFields(
+      TypeSpec.Builder factory, FactoryDescriptor descriptor) {
+    MethodSpec.Builder constructor = constructorBuilder().addAnnotation(Inject.class);
+    if (descriptor.publicType()) {
+      constructor.addModifiers(PUBLIC);
+    }
+    Iterator<ProviderField> providerFields = descriptor.providers().values().iterator();
+    for (int argumentIndex = 1; providerFields.hasNext(); argumentIndex++) {
+      ProviderField provider = providerFields.next();
+      TypeName typeName = TypeName.get(provider.key().type().get()).box();
+      TypeName providerType = ParameterizedTypeName.get(ClassName.get(Provider.class), typeName);
+      factory.addField(providerType, provider.name(), PRIVATE, FINAL);
+      if (provider.key().qualifier().isPresent()) {
+        // only qualify the constructor parameter
+        providerType = providerType.annotated(AnnotationSpec.get(provider.key().qualifier().get()));
+      }
+      constructor.addParameter(providerType, provider.name());
+      constructor.addStatement("this.$1L = checkNotNull($1L, $2L)", provider.name(), argumentIndex);
+    }
+
+    factory.addMethod(constructor.build());
+  }
+
+  private static void addFactoryMethods(
+      TypeSpec.Builder factory,
+      FactoryDescriptor descriptor,
+      ImmutableSet<TypeVariableName> factoryTypeVariables) {
+    for (FactoryMethodDescriptor methodDescriptor : descriptor.methodDescriptors()) {
+      MethodSpec.Builder method =
+          MethodSpec.methodBuilder(methodDescriptor.name())
+              .addTypeVariables(getMethodTypeVariables(methodDescriptor, factoryTypeVariables))
+              .returns(TypeName.get(methodDescriptor.returnType()))
+              .varargs(methodDescriptor.isVarArgs());
+      if (methodDescriptor.overridingMethod()) {
+        method.addAnnotation(Override.class);
+      }
+      if (methodDescriptor.publicMethod()) {
+        method.addModifiers(PUBLIC);
+      }
+      CodeBlock.Builder args = CodeBlock.builder();
+      method.addParameters(parameters(methodDescriptor.passedParameters()));
+      Iterator<Parameter> parameters = methodDescriptor.creationParameters().iterator();
+      for (int argumentIndex = 1; parameters.hasNext(); argumentIndex++) {
+        Parameter parameter = parameters.next();
+        boolean checkNotNull = !parameter.nullable().isPresent();
+        CodeBlock argument;
+        if (methodDescriptor.passedParameters().contains(parameter)) {
+          argument = CodeBlock.of(parameter.name());
+          if (parameter.isPrimitive()) {
+            checkNotNull = false;
+          }
+        } else {
+          ProviderField provider = descriptor.providers().get(parameter.key());
+          argument = CodeBlock.of(provider.name());
+          if (parameter.isProvider()) {
+            // Providers are checked for nullness in the Factory's constructor.
+            checkNotNull = false;
+          } else {
+            argument = CodeBlock.of("$L.get()", argument);
+          }
+        }
+        if (checkNotNull) {
+          argument = CodeBlock.of("checkNotNull($L, $L)", argument, argumentIndex);
+        }
+        args.add(argument);
+        if (parameters.hasNext()) {
+          args.add(", ");
+        }
+      }
+      method.addStatement("return new $T($L)", methodDescriptor.returnType(), args.build());
+      factory.addMethod(method.build());
+    }
+  }
+
+  private static void addImplementationMethods(
+      TypeSpec.Builder factory, FactoryDescriptor descriptor) {
+    for (ImplementationMethodDescriptor methodDescriptor :
+        descriptor.implementationMethodDescriptors()) {
+      MethodSpec.Builder implementationMethod =
+          methodBuilder(methodDescriptor.name())
+              .addAnnotation(Override.class)
+              .returns(TypeName.get(methodDescriptor.returnType()))
+              .varargs(methodDescriptor.isVarArgs());
+      if (methodDescriptor.publicMethod()) {
+        implementationMethod.addModifiers(PUBLIC);
+      }
+      implementationMethod.addParameters(parameters(methodDescriptor.passedParameters()));
+      implementationMethod.addStatement(
+          "return create($L)",
+          FluentIterable.from(methodDescriptor.passedParameters())
+              .transform(
+                  new Function<Parameter, String>() {
+                    @Override
+                    public String apply(Parameter parameter) {
+                      return parameter.name();
+                    }
+                  })
+              .join(ARGUMENT_JOINER));
+      factory.addMethod(implementationMethod.build());
+    }
+  }
+
+  /**
+   * {@link ParameterSpec}s to match {@code parameters}. Note that the type of the {@link
+   * ParameterSpec}s match {@link Parameter#type()} and not {@link Key#type()}.
+   */
+  private static Iterable<ParameterSpec> parameters(Iterable<Parameter> parameters) {
+    ImmutableList.Builder<ParameterSpec> builder = ImmutableList.builder();
+    for (Parameter parameter : parameters) {
+      ParameterSpec.Builder parameterBuilder =
+          ParameterSpec.builder(TypeName.get(parameter.type().get()), parameter.name());
+      for (AnnotationMirror annotation :
+          Iterables.concat(parameter.nullable().asSet(), parameter.key().qualifier().asSet())) {
+        parameterBuilder.addAnnotation(AnnotationSpec.get(annotation));
+      }
+      builder.add(parameterBuilder.build());
+    }
+    return builder.build();
+  }
+
+  private static void addCheckNotNullMethod(
+      TypeSpec.Builder factory, FactoryDescriptor descriptor) {
+    if (shouldGenerateCheckNotNull(descriptor)) {
+      TypeVariableName typeVariable = TypeVariableName.get("T");
+      factory.addMethod(
+          methodBuilder("checkNotNull")
+              .addModifiers(PRIVATE, STATIC)
+              .addTypeVariable(typeVariable)
+              .returns(typeVariable)
+              .addParameter(typeVariable, "reference")
+              .addParameter(TypeName.INT, "argumentIndex")
+              .beginControlFlow("if (reference == null)")
+              .addStatement(
+                  "throw new $T($S + argumentIndex)",
+                  NullPointerException.class,
+                  "@AutoFactory method argument is null but is not marked @Nullable. Argument "
+                      + "index: ")
+              .endControlFlow()
+              .addStatement("return reference")
+              .build());
+    }
+  }
+
+  private static boolean shouldGenerateCheckNotNull(FactoryDescriptor descriptor) {
+    if (!descriptor.providers().isEmpty()) {
+      return true;
+    }
+    for (FactoryMethodDescriptor method : descriptor.methodDescriptors()) {
+      for (Parameter parameter : method.creationParameters()) {
+        if (!parameter.nullable().isPresent() && !parameter.type().get().getKind().isPrimitive()) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private static CharSequence getSimpleName(CharSequence fullyQualifiedName) {
+    int lastDot = lastIndexOf(fullyQualifiedName, '.');
+    return fullyQualifiedName.subSequence(lastDot + 1, fullyQualifiedName.length());
+  }
+
+  private static String getPackage(CharSequence fullyQualifiedName) {
+    int lastDot = lastIndexOf(fullyQualifiedName, '.');
+    return lastDot == -1 ? "" : fullyQualifiedName.subSequence(0, lastDot).toString();
+  }
+
+  private static int lastIndexOf(CharSequence charSequence, char c) {
+    for (int i = charSequence.length() - 1; i >= 0; i--) {
+      if (charSequence.charAt(i) == c) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  private static ImmutableSet<TypeVariableName> getFactoryTypeVariables(
+      FactoryDescriptor descriptor) {
+    ImmutableSet.Builder<TypeVariableName> typeVariables = ImmutableSet.builder();
+    for (ProviderField provider : descriptor.providers().values()) {
+      typeVariables.addAll(getReferencedTypeParameterNames(provider.key().type().get()));
+    }
+    return typeVariables.build();
+  }
+
+  private static ImmutableSet<TypeVariableName> getMethodTypeVariables(
+      FactoryMethodDescriptor methodDescriptor,
+      ImmutableSet<TypeVariableName> factoryTypeVariables) {
+    ImmutableSet.Builder<TypeVariableName> typeVariables = ImmutableSet.builder();
+    typeVariables.addAll(getReferencedTypeParameterNames(methodDescriptor.returnType()));
+    for (Parameter parameter : methodDescriptor.passedParameters()) {
+      typeVariables.addAll(getReferencedTypeParameterNames(parameter.type().get()));
+    }
+    return Sets.difference(typeVariables.build(), factoryTypeVariables).immutableCopy();
+  }
+
+  private static ImmutableSet<TypeVariableName> getReferencedTypeParameterNames(TypeMirror type) {
+    ImmutableSet.Builder<TypeVariableName> typeVariableNames = ImmutableSet.builder();
+    for (TypeVariable typeVariable : TypeVariables.getReferencedTypeVariables(type)) {
+      typeVariableNames.add(TypeVariableName.get(typeVariable));
+    }
+    return typeVariableNames.build();
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/ImplementationMethodDescriptor.java b/factory/src/main/java/com/google/auto/factory/processor/ImplementationMethodDescriptor.java
new file mode 100644
index 0000000..9ddc249
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/ImplementationMethodDescriptor.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableSet;
+import javax.lang.model.type.TypeMirror;
+
+@AutoValue
+abstract class ImplementationMethodDescriptor {
+  abstract String name();
+  abstract TypeMirror returnType();
+  abstract boolean publicMethod();
+  abstract ImmutableSet<Parameter> passedParameters();
+  abstract boolean isVarArgs();
+
+  static Builder builder() {
+    return new AutoValue_ImplementationMethodDescriptor.Builder()
+        .publicMethod(true)
+        .isVarArgs(false);
+  }
+
+  @AutoValue.Builder
+  static abstract class Builder {
+    abstract Builder name(String name);
+    
+    abstract Builder returnType(TypeMirror returnTypeElement);
+
+    abstract Builder publicMethod(boolean publicMethod);
+
+    final Builder publicMethod() {
+      return publicMethod(true);
+    }
+
+    abstract Builder passedParameters(Iterable<Parameter> passedParameters);
+
+    abstract Builder isVarArgs(boolean isVarargs);
+
+    abstract ImplementationMethodDescriptor build();
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/Key.java b/factory/src/main/java/com/google/auto/factory/processor/Key.java
new file mode 100644
index 0000000..04bd4f3
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/Key.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.auto.factory.processor.Mirrors.isProvider;
+import static com.google.auto.factory.processor.Mirrors.unwrapOptionalEquivalence;
+import static com.google.auto.factory.processor.Mirrors.wrapOptionalInEquivalence;
+
+import com.google.auto.common.AnnotationMirrors;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Optional;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import javax.inject.Qualifier;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
+
+/**
+ * A value object for types and qualifiers.
+ *
+ * @author Gregory Kick
+ */
+@AutoValue
+// TODO(ronshapiro): reuse dagger.model.Key?
+abstract class Key {
+
+  abstract Equivalence.Wrapper<TypeMirror> type();
+
+  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> qualifierWrapper();
+
+  Optional<AnnotationMirror> qualifier() {
+    return unwrapOptionalEquivalence(qualifierWrapper());
+  }
+
+  /**
+   * Constructs a key based on the type {@code type} and any {@link Qualifier}s in {@code
+   * annotations}.
+   *
+   * <p>If {@code type} is a {@code Provider<T>}, the returned {@link Key}'s {@link #type()} is
+   * {@code T}. If {@code type} is a primitive, the returned {@link Key}'s {@link #type()} is the
+   * corresponding {@linkplain Types#boxedClass(PrimitiveType) boxed type}.
+   *
+   * <p>For example:
+   * <table>
+   *   <tr><th>Input type                <th>{@code Key.type()}
+   *   <tr><td>{@code String}            <td>{@code String}
+   *   <tr><td>{@code Provider<String>}  <td>{@code String}
+   *   <tr><td>{@code int}               <td>{@code Integer}
+   * </table>
+   */
+  static Key create(
+      TypeMirror type, Iterable<? extends AnnotationMirror> annotations, Types types) {
+    ImmutableSet.Builder<AnnotationMirror> qualifiers = ImmutableSet.builder();
+    for (AnnotationMirror annotation : annotations) {
+      if (isAnnotationPresent(annotation.getAnnotationType().asElement(), Qualifier.class)) {
+        qualifiers.add(annotation);
+      }
+    }
+
+    // TODO(gak): check for only one qualifier rather than using the first
+    Optional<AnnotationMirror> qualifier = FluentIterable.from(qualifiers.build()).first();
+
+    TypeMirror keyType =
+        isProvider(type)
+            ? MoreTypes.asDeclared(type).getTypeArguments().get(0)
+            : boxedType(type, types);
+    return new AutoValue_Key(
+        MoreTypes.equivalence().wrap(keyType),
+        wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), qualifier));
+  }
+
+  /**
+   * If {@code type} is a primitive type, returns the boxed equivalent; otherwise returns
+   * {@code type}.
+   */
+  private static TypeMirror boxedType(TypeMirror type, Types types) {
+    return type.getKind().isPrimitive()
+        ? types.boxedClass(MoreTypes.asPrimitiveType(type)).asType()
+        : type;
+  }
+
+  @Override
+  public String toString() {
+    String typeQualifiedName = MoreTypes.asTypeElement(type().get()).toString();
+    return qualifier().isPresent()
+        ? qualifier().get() + "/" + typeQualifiedName
+        : typeQualifiedName;
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/Mirrors.java b/factory/src/main/java/com/google/auto/factory/processor/Mirrors.java
new file mode 100644
index 0000000..c5b7d8b
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/Mirrors.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableMap;
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.Map.Entry;
+import javax.inject.Provider;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleElementVisitor6;
+
+final class Mirrors {
+  private Mirrors() { }
+
+  static Name getQualifiedName(DeclaredType type) {
+    return type.asElement().accept(new SimpleElementVisitor6<Name, Void>() {
+      @Override
+      protected Name defaultAction(Element e, Void p) {
+        throw new AssertionError("DeclaredTypes should be TypeElements");
+      }
+
+      @Override
+      public Name visitType(TypeElement e, Void p) {
+        return e.getQualifiedName();
+      }
+    }, null);
+  }
+
+  /** {@code true} if {@code type} is a {@link Provider}. */
+  static boolean isProvider(TypeMirror type) {
+    return MoreTypes.isType(type) && MoreTypes.isTypeOf(Provider.class, type);
+  }
+
+  /**
+   * Returns an annotation value map  with {@link String} keys instead of {@link ExecutableElement}
+   * instances.
+   */
+  static ImmutableMap<String, AnnotationValue> simplifyAnnotationValueMap(
+      Map<? extends ExecutableElement, ? extends AnnotationValue> annotationValueMap) {
+    ImmutableMap.Builder<String, AnnotationValue> builder = ImmutableMap.builder();
+    for (Entry<? extends ExecutableElement, ? extends AnnotationValue> entry
+        : annotationValueMap.entrySet()) {
+      builder.put(entry.getKey().getSimpleName().toString(), entry.getValue());
+    }
+    return builder.build();
+  }
+
+  /**
+   * Get the {@link AnnotationMirror} for the type {@code annotationType} present on the given
+   * {@link Element} if it exists.
+   */
+  static Optional<AnnotationMirror> getAnnotationMirror(Element element,
+      Class<? extends Annotation> annotationType) {
+    String annotationName = annotationType.getName();
+    for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) {
+      if (getQualifiedName(annotationMirror.getAnnotationType()).contentEquals(annotationName)) {
+        return Optional.of(annotationMirror);
+      }
+    }
+    return Optional.absent();
+  }
+
+  /**
+   * Wraps an {@link Optional} of a type in an {@code Optional} of a {@link Equivalence.Wrapper} for
+   * that type.
+   */
+  // TODO(ronshapiro): this is used in AutoFactory and Dagger, consider moving it into auto-common.
+  static <T> Optional<Equivalence.Wrapper<T>> wrapOptionalInEquivalence(
+      Equivalence<T> equivalence, Optional<T> optional) {
+    return optional.isPresent()
+        ? Optional.of(equivalence.wrap(optional.get()))
+        : Optional.<Equivalence.Wrapper<T>>absent();
+  }
+
+  /**
+   * Unwraps an {@link Optional} of a {@link Equivalence.Wrapper} into an {@code Optional} of the
+   * underlying type.
+   */
+  static <T> Optional<T> unwrapOptionalEquivalence(
+      Optional<Equivalence.Wrapper<T>> wrappedOptional) {
+    return wrappedOptional.isPresent()
+        ? Optional.of(wrappedOptional.get().get())
+        : Optional.<T>absent();
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/Parameter.java b/factory/src/main/java/com/google/auto/factory/processor/Parameter.java
new file mode 100644
index 0000000..781225a
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/Parameter.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.auto.factory.processor.Mirrors.unwrapOptionalEquivalence;
+import static com.google.auto.factory.processor.Mirrors.wrapOptionalInEquivalence;
+import static com.google.common.base.Preconditions.checkArgument;
+
+import com.google.auto.common.AnnotationMirrors;
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import java.util.List;
+import java.util.Set;
+import javax.inject.Provider;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
+
+/**
+ * Model for a parameter from an {@link com.google.auto.factory.AutoFactory} constructor or
+ * implementation method.
+ */
+@AutoValue
+abstract class Parameter {
+
+  /**
+   * The original type of the parameter, while {@code key().type()} erases the wrapped {@link
+   * Provider}, if any.
+   */
+  abstract Equivalence.Wrapper<TypeMirror> type();
+
+  boolean isProvider() {
+    return Mirrors.isProvider(type().get());
+  }
+
+  boolean isPrimitive() {
+    return type().get().getKind().isPrimitive();
+  }
+
+  /** The name of the parameter. */
+  abstract String name();
+
+  abstract Key key();
+  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> nullableWrapper();
+
+  Optional<AnnotationMirror> nullable() {
+    return unwrapOptionalEquivalence(nullableWrapper());
+  }
+
+  private static Parameter forVariableElement(
+      VariableElement variable, TypeMirror type, Types types) {
+    Optional<AnnotationMirror> nullable = Optional.absent();
+    Iterable<? extends AnnotationMirror> annotations =
+        Iterables.concat(variable.getAnnotationMirrors(), type.getAnnotationMirrors());
+    for (AnnotationMirror annotation : annotations) {
+      if (isNullable(annotation)) {
+        nullable = Optional.of(annotation);
+        break;
+      }
+    }
+
+    Key key = Key.create(type, annotations, types);
+    return new AutoValue_Parameter(
+        MoreTypes.equivalence().wrap(type),
+        variable.getSimpleName().toString(),
+        key,
+        wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), nullable));
+  }
+
+  private static boolean isNullable(AnnotationMirror annotation) {
+    TypeElement annotationType = MoreElements.asType(annotation.getAnnotationType().asElement());
+    return annotationType.getSimpleName().contentEquals("Nullable")
+        || annotationType
+            .getQualifiedName()
+            .toString()
+            // For NullableDecl and NullableType compatibility annotations
+            .startsWith("org.checkerframework.checker.nullness.compatqual.Nullable");
+  }
+
+  static ImmutableSet<Parameter> forParameterList(
+      List<? extends VariableElement> variables,
+      List<? extends TypeMirror> variableTypes,
+      Types types) {
+    checkArgument(variables.size() == variableTypes.size());
+    ImmutableSet.Builder<Parameter> builder = ImmutableSet.builder();
+    Set<String> names = Sets.newHashSetWithExpectedSize(variables.size());
+    for (int i = 0; i < variables.size(); i++) {
+      Parameter parameter = forVariableElement(variables.get(i), variableTypes.get(i), types);
+      checkArgument(names.add(parameter.name()));
+      builder.add(parameter);
+    }
+    ImmutableSet<Parameter> parameters = builder.build();
+    checkArgument(variables.size() == parameters.size());
+    return parameters;
+  }
+
+  static ImmutableSet<Parameter> forParameterList(
+      List<? extends VariableElement> variables, Types types) {
+    List<TypeMirror> variableTypes = Lists.newArrayListWithExpectedSize(variables.size());
+    for (VariableElement var : variables) {
+      variableTypes.add(var.asType());
+    }
+    return forParameterList(variables, variableTypes, types);
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java b/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java
new file mode 100644
index 0000000..fe4c1fd
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/ProvidedChecker.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.common.base.Preconditions.checkArgument;
+import static javax.tools.Diagnostic.Kind.ERROR;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import javax.annotation.processing.Messager;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.util.ElementKindVisitor6;
+
+final class ProvidedChecker {
+  private final Messager messager;
+
+  ProvidedChecker(Messager messager) {
+    this.messager = messager;
+  }
+
+  void checkProvidedParameter(Element element) {
+    checkArgument(isAnnotationPresent(element, Provided.class), "%s not annoated with @Provided",
+        element);
+    element.accept(new ElementKindVisitor6<Void, Void>() {
+      @Override
+      protected Void defaultAction(Element e, Void p) {
+        throw new AssertionError("Provided can only be applied to parameters");
+      }
+
+      @Override
+      public Void visitVariableAsParameter(final VariableElement providedParameter, Void p) {
+        providedParameter.getEnclosingElement().accept(new ElementKindVisitor6<Void, Void>() {
+          @Override
+          protected Void defaultAction(Element e, Void p) {
+            raiseError(providedParameter, "@%s may only be applied to constructor parameters");
+            return null;
+          }
+
+          @Override
+          public Void visitExecutableAsConstructor(ExecutableElement constructor, Void p) {
+            if (!(annotatedWithAutoFactory(constructor)
+                || annotatedWithAutoFactory(constructor.getEnclosingElement()))) {
+              raiseError(providedParameter,
+                  "@%s may only be applied to constructors requesting an auto-factory");
+            }
+            return null;
+          }
+        }, p);
+        return null;
+      }
+    }, null);
+  }
+
+  private void raiseError(VariableElement providedParameter, String messageFormat) {
+    messager.printMessage(ERROR, String.format(messageFormat, Provided.class.getSimpleName()),
+        providedParameter, Mirrors.getAnnotationMirror(providedParameter, Provided.class).get());
+  }
+
+  private static boolean annotatedWithAutoFactory(Element e) {
+    return isAnnotationPresent(e, AutoFactory.class);
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/ProviderField.java b/factory/src/main/java/com/google/auto/factory/processor/ProviderField.java
new file mode 100644
index 0000000..855c1fe
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/ProviderField.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.auto.factory.processor.Mirrors.unwrapOptionalEquivalence;
+import static com.google.auto.factory.processor.Mirrors.wrapOptionalInEquivalence;
+
+import com.google.auto.common.AnnotationMirrors;
+import com.google.auto.value.AutoValue;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Optional;
+import javax.lang.model.element.AnnotationMirror;
+
+@AutoValue
+abstract class ProviderField {
+  abstract String name();
+  abstract Key key();
+  abstract Optional<Equivalence.Wrapper<AnnotationMirror>> nullableWrapper();
+
+  Optional<AnnotationMirror> nullable() {
+    return unwrapOptionalEquivalence(nullableWrapper());
+  }
+
+  static ProviderField create(String name, Key key, Optional<AnnotationMirror> nullable) {
+    return new AutoValue_ProviderField(
+        name, key, wrapOptionalInEquivalence(AnnotationMirrors.equivalence(), nullable));
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java b/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java
new file mode 100644
index 0000000..1f89473
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/TypeVariables.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.HashSet;
+import java.util.Set;
+import javax.lang.model.element.Element;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.IntersectionType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.UnionType;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.SimpleTypeVisitor8;
+
+final class TypeVariables {
+  private TypeVariables() {}
+
+  static ImmutableSet<TypeVariable> getReferencedTypeVariables(TypeMirror type) {
+    checkNotNull(type);
+    return type.accept(ReferencedTypeVariables.INSTANCE, new HashSet<>());
+  }
+
+  private static final class ReferencedTypeVariables extends
+      SimpleTypeVisitor8<ImmutableSet<TypeVariable>, Set<Element>> {
+
+    private static final ReferencedTypeVariables INSTANCE = new ReferencedTypeVariables();
+
+    ReferencedTypeVariables() {
+      super(ImmutableSet.of());
+    }
+
+    @Override
+    public ImmutableSet<TypeVariable> visitArray(ArrayType t, Set<Element> visited) {
+      return t.getComponentType().accept(this, visited);
+    }
+
+    @Override
+    public ImmutableSet<TypeVariable> visitDeclared(
+        DeclaredType t, Set<Element> visited) {
+      if (!visited.add(t.asElement())) {
+        return ImmutableSet.of();
+      }
+      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
+      for (TypeMirror typeArgument : t.getTypeArguments()) {
+        typeVariables.addAll(typeArgument.accept(this, visited));
+      }
+      return typeVariables.build();
+    }
+
+    @Override
+    public ImmutableSet<TypeVariable> visitTypeVariable(
+        TypeVariable t, Set<Element> visited) {
+      if (!visited.add(t.asElement())) {
+        return ImmutableSet.of();
+      }
+      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
+      typeVariables.add(t);
+      typeVariables.addAll(t.getLowerBound().accept(this, visited));
+      typeVariables.addAll(t.getUpperBound().accept(this, visited));
+      return typeVariables.build();
+    }
+
+    @Override
+    public ImmutableSet<TypeVariable> visitUnion(
+        UnionType t, Set<Element> visited) {
+      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
+      for (TypeMirror unionType : t.getAlternatives()) {
+        typeVariables.addAll(unionType.accept(this, visited));
+      }
+      return typeVariables.build();
+    }
+
+    @Override
+    public ImmutableSet<TypeVariable> visitIntersection(
+        IntersectionType t, Set<Element> visited) {
+      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
+      for (TypeMirror intersectionType : t.getBounds()) {
+        typeVariables.addAll(intersectionType.accept(this, visited));
+      }
+      return typeVariables.build();
+    }
+
+    @Override
+    public ImmutableSet<TypeVariable> visitWildcard(
+        WildcardType t, Set<Element> visited) {
+      ImmutableSet.Builder<TypeVariable> typeVariables = ImmutableSet.builder();
+      TypeMirror extendsBound = t.getExtendsBound();
+      if (extendsBound != null) {
+        typeVariables.addAll(extendsBound.accept(this, visited));
+      }
+      TypeMirror superBound = t.getSuperBound();
+      if (superBound != null) {
+        typeVariables.addAll(superBound.accept(this, visited));
+      }
+      return typeVariables.build();
+    }
+  }
+}
diff --git a/factory/src/main/java/com/google/auto/factory/processor/package-info.java b/factory/src/main/java/com/google/auto/factory/processor/package-info.java
new file mode 100644
index 0000000..7339020
--- /dev/null
+++ b/factory/src/main/java/com/google/auto/factory/processor/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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.
+ */
+/**
+ * This package contains the annotation processor that implements the
+ * {@link com.google.auto.factory.AutoFactory} API.
+ */
+package com.google.auto.factory.processor;
\ No newline at end of file
diff --git a/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryDeclarationTest.java b/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryDeclarationTest.java
new file mode 100644
index 0000000..1b23a65
--- /dev/null
+++ b/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryDeclarationTest.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.auto.factory.processor.AutoFactoryDeclaration.Factory.isValidIdentifier;
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class AutoFactoryDeclarationTest {
+  @Test public void identifiers() {
+    assertThat(isValidIdentifier("String")).isTrue();
+    assertThat(isValidIdentifier("9CantStartWithNumber")).isFalse();
+    assertThat(isValidIdentifier("enum")).isFalse();
+    assertThat(isValidIdentifier("goto")).isFalse();
+    assertThat(isValidIdentifier("InvalidCharacter!")).isFalse();
+  }
+}
diff --git a/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java b/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java
new file mode 100644
index 0000000..3088bb2
--- /dev/null
+++ b/factory/src/test/java/com/google/auto/factory/processor/AutoFactoryProcessorTest.java
@@ -0,0 +1,475 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.factory.processor;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+import static com.google.testing.compile.JavaSourcesSubject.assertThat;
+import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.Resources;
+import com.google.testing.compile.CompilationRule;
+import com.google.testing.compile.JavaFileObjects;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Collections;
+import java.util.List;
+import javax.lang.model.SourceVersion;
+import javax.tools.JavaFileObject;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Functional tests for the {@link AutoFactoryProcessor}.
+ */
+@RunWith(JUnit4.class)
+public class AutoFactoryProcessorTest {
+
+  @Rule public final CompilationRule compilationRule = new CompilationRule();
+
+  @Test public void simpleClass() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/SimpleClass.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/SimpleClassFactory.java"));
+  }
+
+  @Test
+  public void nestedClasses() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/NestedClasses.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(
+            loadExpectedFile("expected/NestedClasses_SimpleNestedClassFactory.java"),
+            loadExpectedFile("expected/NestedClassCustomNamedFactory.java"));
+  }
+
+  @Test public void simpleClassNonFinal() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/SimpleClassNonFinal.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/SimpleClassNonFinalFactory.java"));
+  }
+
+  @Test public void publicClass() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/PublicClass.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/PublicClassFactory.java"));
+  }
+
+  @Test public void simpleClassCustomName() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/SimpleClassCustomName.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/CustomNamedFactory.java"));
+  }
+
+  @Test public void simpleClassMixedDeps() {
+    assertAbout(javaSources())
+        .that(
+            ImmutableSet.of(
+                JavaFileObjects.forResource("good/SimpleClassMixedDeps.java"),
+                JavaFileObjects.forResource("support/AQualifier.java")))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/SimpleClassMixedDepsFactory.java"));
+  }
+
+  @Test public void simpleClassPassedDeps() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/SimpleClassPassedDeps.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/SimpleClassPassedDepsFactory.java"));
+  }
+
+  @Test public void simpleClassProvidedDeps() {
+    assertAbout(javaSources())
+        .that(
+            ImmutableSet.of(
+                JavaFileObjects.forResource("support/AQualifier.java"),
+                JavaFileObjects.forResource("support/BQualifier.java"),
+                JavaFileObjects.forResource("good/SimpleClassProvidedDeps.java")))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/SimpleClassProvidedDepsFactory.java"));
+  }
+
+  @Test
+  public void simpleClassProvidedProviderDeps() {
+    assertAbout(javaSources())
+        .that(
+            ImmutableSet.of(
+                JavaFileObjects.forResource("support/AQualifier.java"),
+                JavaFileObjects.forResource("support/BQualifier.java"),
+                JavaFileObjects.forResource("good/SimpleClassProvidedProviderDeps.java")))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/SimpleClassProvidedProviderDepsFactory.java"));
+  }
+
+  @Test public void constructorAnnotated() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/ConstructorAnnotated.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/ConstructorAnnotatedFactory.java"));
+  }
+
+  @Test public void constructorAnnotatedNonFinal() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/ConstructorAnnotatedNonFinal.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/ConstructorAnnotatedNonFinalFactory.java"));
+  }
+
+  @Test public void simpleClassImplementingMarker() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/SimpleClassImplementingMarker.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/SimpleClassImplementingMarkerFactory.java"));
+  }
+
+  @Test public void simpleClassImplementingSimpleInterface() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/SimpleClassImplementingSimpleInterface.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(
+            loadExpectedFile("expected/SimpleClassImplementingSimpleInterfaceFactory.java"));
+  }
+
+  @Test public void mixedDepsImplementingInterfaces() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/MixedDepsImplementingInterfaces.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/MixedDepsImplementingInterfacesFactory.java"));
+  }
+
+  @Test public void failsWithMixedFinals() {
+    JavaFileObject file = JavaFileObjects.forResource("bad/MixedFinals.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.")
+            .in(file).onLine(24)
+         .and().withErrorContaining(
+            "Cannot mix allowSubclasses=true and allowSubclasses=false in one factory.")
+            .in(file).onLine(27);
+  }
+
+  @Test public void providedButNoAutoFactory() {
+    JavaFileObject file = JavaFileObjects.forResource("bad/ProvidedButNoAutoFactory.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "@Provided may only be applied to constructors requesting an auto-factory")
+                .in(file).onLine(21).atColumn(38);
+  }
+
+  @Test public void providedOnMethodParameter() {
+    JavaFileObject file = JavaFileObjects.forResource("bad/ProvidedOnMethodParameter.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "@Provided may only be applied to constructor parameters")
+                .in(file).onLine(21).atColumn(23);
+  }
+
+  @Test public void invalidCustomName() {
+    JavaFileObject file = JavaFileObjects.forResource("bad/InvalidCustomName.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .failsToCompile()
+        .withErrorContaining("\"SillyFactory!\" is not a valid Java identifier")
+            .in(file).onLine(20);
+  }
+
+  @Test public void factoryExtendingAbstractClass() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/FactoryExtendingAbstractClass.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/FactoryExtendingAbstractClassFactory.java"));
+  }
+
+  @Test public void factoryExtendingAbstractClass_withConstructorParams() {
+    JavaFileObject file =
+        JavaFileObjects.forResource("good/FactoryExtendingAbstractClassWithConstructorParams.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "tests.FactoryExtendingAbstractClassWithConstructorParams.AbstractFactory "
+                + "is not a valid supertype for a factory. "
+                + "Factory supertypes must have a no-arg constructor.")
+                    .in(file).onLine(21);
+  }
+
+  @Test public void factoryExtendingAbstractClass_multipleConstructors() {
+    JavaFileObject file = JavaFileObjects.forResource(
+        "good/FactoryExtendingAbstractClassWithMultipleConstructors.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError();
+  }
+
+  @Test public void factoryExtendingInterface() {
+    JavaFileObject file = JavaFileObjects.forResource("bad/InterfaceSupertype.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .failsToCompile()
+        .withErrorContaining("java.lang.Runnable is not a valid supertype for a factory. "
+            + "Supertypes must be non-final classes.")
+                .in(file).onLine(20);
+  }
+
+  @Test public void factoryExtendingEnum() {
+    JavaFileObject file = JavaFileObjects.forResource("bad/EnumSupertype.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .failsToCompile()
+        .withErrorContaining(
+            "java.util.concurrent.TimeUnit is not a valid supertype for a factory. "
+                + "Supertypes must be non-final classes.")
+                    .in(file).onLine(21);
+  }
+
+  @Test public void factoryExtendingFinalClass() {
+    JavaFileObject file = JavaFileObjects.forResource("bad/FinalSupertype.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .failsToCompile()
+        .withErrorContaining("java.lang.Boolean is not a valid supertype for a factory. "
+            + "Supertypes must be non-final classes.")
+                .in(file).onLine(20);
+  }
+
+  @Test public void factoryImplementingGenericInterfaceExtension() {
+    JavaFileObject file =
+        JavaFileObjects.forResource("good/FactoryImplementingGenericInterfaceExtension.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(
+            loadExpectedFile("expected/FactoryImplementingGenericInterfaceExtensionFactory.java"));
+  }
+
+  @Test public void multipleFactoriesImpementingInterface() {
+    JavaFileObject file =
+        JavaFileObjects.forResource("good/MultipleFactoriesImplementingInterface.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(
+            loadExpectedFile("expected/MultipleFactoriesImplementingInterface_ClassAFactory.java"),
+            loadExpectedFile("expected/MultipleFactoriesImplementingInterface_ClassBFactory.java"));
+  }
+
+  @Test public void classUsingQualifierWithArgs() {
+    assertAbout(javaSources())
+        .that(
+            ImmutableSet.of(
+                JavaFileObjects.forResource("support/QualifierWithArgs.java"),
+                JavaFileObjects.forResource("good/ClassUsingQualifierWithArgs.java")))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/ClassUsingQualifierWithArgsFactory.java"));
+  }
+
+  @Test public void factoryImplementingInterfaceWhichRedeclaresCreateMethods() {
+    JavaFileObject file =
+        JavaFileObjects.forResource("good/FactoryImplementingCreateMethod.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(
+            loadExpectedFile("expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java"));
+  }
+
+  @Test public void nullableParams() {
+    assertAbout(javaSources())
+        .that(
+            ImmutableSet.of(
+                JavaFileObjects.forResource("good/SimpleClassNullableParameters.java"),
+                JavaFileObjects.forResource("support/AQualifier.java"),
+                JavaFileObjects.forResource("support/BQualifier.java")))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/SimpleClassNullableParametersFactory.java"));
+  }
+
+  @Test public void customNullableType() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/CustomNullable.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/CustomNullableFactory.java"));
+  }
+
+  @Test public void checkerFrameworkNullableType() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/CheckerFrameworkNullable.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/CheckerFrameworkNullableFactory.java"));
+  }
+
+  @Test public void multipleProvidedParamsWithSameKey() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/MultipleProvidedParamsSameKey.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/MultipleProvidedParamsSameKeyFactory.java"));
+  }
+
+  @Test public void providerArgumentToCreateMethod() {
+    assertAbout(javaSource())
+        .that(JavaFileObjects.forResource("good/ProviderArgumentToCreateMethod.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/ProviderArgumentToCreateMethodFactory.java"));
+  }
+
+  @Test public void multipleFactoriesConflictingParameterNames() {
+    assertThat(
+            JavaFileObjects.forResource("good/MultipleFactoriesConflictingParameterNames.java"),
+            JavaFileObjects.forResource("support/AQualifier.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(
+            loadExpectedFile("expected/MultipleFactoriesConflictingParameterNamesFactory.java"));
+  }
+
+  @Test public void factoryVarargs() {
+    assertThat(JavaFileObjects.forResource("good/SimpleClassVarargs.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/SimpleClassVarargsFactory.java"));
+  }
+
+  @Test public void onlyPrimitives() {
+    assertThat(JavaFileObjects.forResource("good/OnlyPrimitives.java"))
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/OnlyPrimitivesFactory.java"));
+  }
+
+  @Test
+  public void defaultPackage() {
+    JavaFileObject file = JavaFileObjects.forResource("good/DefaultPackage.java");
+    assertAbout(javaSource())
+        .that(file)
+        .processedWith(new AutoFactoryProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(loadExpectedFile("expected/DefaultPackageFactory.java"));
+  }
+
+  private JavaFileObject loadExpectedFile(String resourceName) {
+    try {
+      List<String> sourceLines = Resources.readLines(Resources.getResource(resourceName), UTF_8);
+      if (!isJavaxAnnotationProcessingGeneratedAvailable()) {
+        replaceGeneratedImport(sourceLines);
+      }
+      return JavaFileObjects.forSourceLines(
+          resourceName.replace('/', '.').replace(".java", ""), sourceLines);
+    } catch (IOException e) {
+      throw new UncheckedIOException(e);
+    }
+  }
+
+  private boolean isJavaxAnnotationProcessingGeneratedAvailable() {
+    return SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0;
+  }
+
+  private static void replaceGeneratedImport(List<String> sourceLines) {
+    int i = 0;
+    int firstImport = Integer.MAX_VALUE;
+    int lastImport = -1;
+    for (String line : sourceLines) {
+      if (line.startsWith("import ") && !line.startsWith("import static ")) {
+        firstImport = Math.min(firstImport, i);
+        lastImport = Math.max(lastImport, i);
+      }
+      i++;
+    }
+    if (lastImport >= 0) {
+      List<String> importLines = sourceLines.subList(firstImport, lastImport + 1);
+      importLines.replaceAll(
+          line ->
+              line.startsWith("import javax.annotation.processing.Generated;")
+                  ? "import javax.annotation.Generated;"
+                  : line);
+      Collections.sort(importLines);
+    }
+  }
+}
diff --git a/factory/src/test/resources/bad/EnumSupertype.java b/factory/src/test/resources/bad/EnumSupertype.java
new file mode 100644
index 0000000..00913b0
--- /dev/null
+++ b/factory/src/test/resources/bad/EnumSupertype.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import java.util.concurrent.TimeUnit;
+
+@AutoFactory(extending = TimeUnit.class)
+final class InterfaceSupertype {}
diff --git a/factory/src/test/resources/bad/FinalSupertype.java b/factory/src/test/resources/bad/FinalSupertype.java
new file mode 100644
index 0000000..4822f11
--- /dev/null
+++ b/factory/src/test/resources/bad/FinalSupertype.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+@AutoFactory(extending = Boolean.class)
+final class InterfaceSupertype {}
diff --git a/factory/src/test/resources/bad/InterfaceSupertype.java b/factory/src/test/resources/bad/InterfaceSupertype.java
new file mode 100644
index 0000000..2bdce5e
--- /dev/null
+++ b/factory/src/test/resources/bad/InterfaceSupertype.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+@AutoFactory(extending = Runnable.class)
+final class InterfaceSupertype {}
diff --git a/factory/src/test/resources/bad/InvalidCustomName.java b/factory/src/test/resources/bad/InvalidCustomName.java
new file mode 100644
index 0000000..5734ee7
--- /dev/null
+++ b/factory/src/test/resources/bad/InvalidCustomName.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+@AutoFactory(className = "SillyFactory!")
+final class InvalidCustomName { }
diff --git a/factory/src/test/resources/bad/MixedFinals.java b/factory/src/test/resources/bad/MixedFinals.java
new file mode 100644
index 0000000..4b9ef20
--- /dev/null
+++ b/factory/src/test/resources/bad/MixedFinals.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+final class MixedFinals {
+  @AutoFactory(allowSubclasses = false)
+  MixedFinals() {}
+
+  @AutoFactory(allowSubclasses = true)
+  MixedFinals(String s) {}
+
+  @AutoFactory(allowSubclasses = true)
+  MixedFinals(String s, Integer i) {}
+}
diff --git a/factory/src/test/resources/bad/ProvidedButNoAutoFactory.java b/factory/src/test/resources/bad/ProvidedButNoAutoFactory.java
new file mode 100644
index 0000000..40269a4
--- /dev/null
+++ b/factory/src/test/resources/bad/ProvidedButNoAutoFactory.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.Provided;
+
+final class ProvidedButNoAutoFactory {
+  ProvidedButNoAutoFactory(Object a, @Provided Object b) {}
+}
diff --git a/factory/src/test/resources/bad/ProvidedOnMethodParameter.java b/factory/src/test/resources/bad/ProvidedOnMethodParameter.java
new file mode 100644
index 0000000..ab5982a
--- /dev/null
+++ b/factory/src/test/resources/bad/ProvidedOnMethodParameter.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.Provided;
+
+final class ProvidedOnMethodParameter {
+  void blah(Object a, @Provided Object b) {}
+}
diff --git a/factory/src/test/resources/expected/CheckerFrameworkNullableFactory.java b/factory/src/test/resources/expected/CheckerFrameworkNullableFactory.java
new file mode 100644
index 0000000..79175c7
--- /dev/null
+++ b/factory/src/test/resources/expected/CheckerFrameworkNullableFactory.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+import org.checkerframework.checker.nullness.compatqual.NullableDecl;
+import org.checkerframework.checker.nullness.compatqual.NullableType;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+)
+final class CheckerFrameworkNullableFactory {
+
+  private final Provider<String> java_lang_StringProvider;
+
+  @Inject
+  CheckerFrameworkNullableFactory(
+      Provider<String> java_lang_StringProvider) {
+    this.java_lang_StringProvider = checkNotNull(java_lang_StringProvider, 1);
+  }
+
+  CheckerFrameworkNullable create(
+      @NullableDecl String nullableDecl, @NullableType String nullableType) {
+    return new CheckerFrameworkNullable(
+        nullableDecl,
+        java_lang_StringProvider.get(),
+        nullableType,
+        java_lang_StringProvider.get());
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/ClassUsingQualifierWithArgsFactory.java b/factory/src/test/resources/expected/ClassUsingQualifierWithArgsFactory.java
new file mode 100644
index 0000000..b5bd89c
--- /dev/null
+++ b/factory/src/test/resources/expected/ClassUsingQualifierWithArgsFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class ClassUsingQualifierWithArgsFactory {
+  private final Provider<String> providedDepAProvider;
+
+  @Inject ClassUsingQualifierWithArgsFactory(
+      @QualifierWithArgs(name="Fred", count=3) Provider<String> providedDepAProvider) {
+    this.providedDepAProvider = checkNotNull(providedDepAProvider, 1);
+  }
+
+  ClassUsingQualifierWithArgs create() {
+    return new ClassUsingQualifierWithArgs(checkNotNull(providedDepAProvider.get(), 1));
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/ConstructorAnnotatedFactory.java b/factory/src/test/resources/expected/ConstructorAnnotatedFactory.java
new file mode 100644
index 0000000..6e9d242
--- /dev/null
+++ b/factory/src/test/resources/expected/ConstructorAnnotatedFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class ConstructorAnnotatedFactory {
+  private final Provider<Object> objProvider;
+
+  @Inject ConstructorAnnotatedFactory(Provider<Object> objProvider) {
+    this.objProvider = checkNotNull(objProvider, 1);
+  }
+
+  ConstructorAnnotated create() {
+    return new ConstructorAnnotated();
+  }
+
+  ConstructorAnnotated create(String s) {
+    return new ConstructorAnnotated(checkNotNull(s, 1));
+  }
+
+  ConstructorAnnotated create(int i) {
+    return new ConstructorAnnotated(checkNotNull(objProvider.get(), 1), i);
+  }
+
+  ConstructorAnnotated create(char c) {
+    return new ConstructorAnnotated(checkNotNull(objProvider.get(), 1), c);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/ConstructorAnnotatedNonFinalFactory.java b/factory/src/test/resources/expected/ConstructorAnnotatedNonFinalFactory.java
new file mode 100644
index 0000000..f662642
--- /dev/null
+++ b/factory/src/test/resources/expected/ConstructorAnnotatedNonFinalFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+class ConstructorAnnotatedNonFinalFactory {
+  private final Provider<Object> objProvider;
+
+  @Inject ConstructorAnnotatedNonFinalFactory(Provider<Object> objProvider) {
+    this.objProvider = checkNotNull(objProvider, 1);
+  }
+
+  ConstructorAnnotatedNonFinal create() {
+    return new ConstructorAnnotatedNonFinal();
+  }
+
+  ConstructorAnnotatedNonFinal create(String s) {
+    return new ConstructorAnnotatedNonFinal(checkNotNull(s, 1));
+  }
+
+  ConstructorAnnotatedNonFinal create(int i) {
+    return new ConstructorAnnotatedNonFinal(checkNotNull(objProvider.get(), 1), i);
+  }
+
+  ConstructorAnnotatedNonFinal create(char c) {
+    return new ConstructorAnnotatedNonFinal(checkNotNull(objProvider.get(), 1), c);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/CustomNamedFactory.java b/factory/src/test/resources/expected/CustomNamedFactory.java
new file mode 100644
index 0000000..c388387
--- /dev/null
+++ b/factory/src/test/resources/expected/CustomNamedFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class CustomNamedFactory {
+  @Inject CustomNamedFactory() {}
+
+  SimpleClassCustomName create() {
+    return new SimpleClassCustomName();
+  }
+}
diff --git a/factory/src/test/resources/expected/CustomNullableFactory.java b/factory/src/test/resources/expected/CustomNullableFactory.java
new file mode 100644
index 0000000..31bb5bf
--- /dev/null
+++ b/factory/src/test/resources/expected/CustomNullableFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class CustomNullableFactory {
+
+  private final Provider<Object> objectProvider;
+
+  @Inject
+  CustomNullableFactory(Provider<Object> objectProvider) {
+    this.objectProvider = checkNotNull(objectProvider, 1);
+  }
+
+  CustomNullable create(@CustomNullable.Nullable String string) {
+    return new CustomNullable(string, objectProvider.get());
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/DefaultPackageFactory.java b/factory/src/test/resources/expected/DefaultPackageFactory.java
new file mode 100644
index 0000000..d1d4cc8
--- /dev/null
+++ b/factory/src/test/resources/expected/DefaultPackageFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+    value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+    comments = "https://github.com/google/auto/tree/master/factory"
+    )
+public final class DefaultPackageFactory {
+  @Inject
+  public DefaultPackageFactory() {}
+
+  public DefaultPackage create() {
+    return new DefaultPackage();
+  }
+}
diff --git a/factory/src/test/resources/expected/FactoryExtendingAbstractClassFactory.java b/factory/src/test/resources/expected/FactoryExtendingAbstractClassFactory.java
new file mode 100644
index 0000000..c56afb0
--- /dev/null
+++ b/factory/src/test/resources/expected/FactoryExtendingAbstractClassFactory.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class FactoryExtendingAbstractClassFactory
+    extends FactoryExtendingAbstractClass.AbstractFactory {
+  @Inject FactoryExtendingAbstractClassFactory() {}
+
+  FactoryExtendingAbstractClass create() {
+    return new FactoryExtendingAbstractClass();
+  }
+
+  @Override public FactoryExtendingAbstractClass newInstance() {
+    return create();
+  }
+}
diff --git a/factory/src/test/resources/expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java b/factory/src/test/resources/expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java
new file mode 100644
index 0000000..f23dc9a
--- /dev/null
+++ b/factory/src/test/resources/expected/FactoryImplementingCreateMethod_ConcreteClassFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import java.util.List;
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class FactoryImplementingCreateMethod_ConcreteClassFactory
+    implements FactoryImplementingCreateMethod.FactoryInterfaceWithCreateMethod {
+
+  @Inject
+  FactoryImplementingCreateMethod_ConcreteClassFactory() {}
+
+  @Override
+  public FactoryImplementingCreateMethod.ConcreteClass create() {
+    return new FactoryImplementingCreateMethod.ConcreteClass();
+  }
+
+  @Override
+  public FactoryImplementingCreateMethod.ConcreteClass create(int aDifferentArgumentName) {
+    return new FactoryImplementingCreateMethod.ConcreteClass(aDifferentArgumentName);
+  }
+
+  @Override
+  public FactoryImplementingCreateMethod.ConcreteClass create(List<Integer> genericWithDifferentArgumentName) {
+    return new FactoryImplementingCreateMethod.ConcreteClass(
+        checkNotNull(genericWithDifferentArgumentName, 1));
+  }
+
+  FactoryImplementingCreateMethod.ConcreteClass create(int a, boolean b) {
+    return new FactoryImplementingCreateMethod.ConcreteClass(a, b);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/FactoryImplementingGenericInterfaceExtensionFactory.java b/factory/src/test/resources/expected/FactoryImplementingGenericInterfaceExtensionFactory.java
new file mode 100644
index 0000000..3bfc526
--- /dev/null
+++ b/factory/src/test/resources/expected/FactoryImplementingGenericInterfaceExtensionFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class FactoryImplementingGenericInterfaceExtensionFactory
+    implements FactoryImplementingGenericInterfaceExtension.MyFactory {
+  private final Provider<String> sProvider;
+  @Inject
+  FactoryImplementingGenericInterfaceExtensionFactory(Provider<String> sProvider) {
+    this.sProvider = checkNotNull(sProvider, 1);
+  }
+  FactoryImplementingGenericInterfaceExtension create(Integer i) {
+    return new FactoryImplementingGenericInterfaceExtension(
+        checkNotNull(sProvider.get(), 1), checkNotNull(i, 2));
+  }
+  @Override
+  public FactoryImplementingGenericInterfaceExtension make(Integer arg) {
+    return create(arg);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/MixedDepsImplementingInterfacesFactory.java b/factory/src/test/resources/expected/MixedDepsImplementingInterfacesFactory.java
new file mode 100644
index 0000000..19f2c13
--- /dev/null
+++ b/factory/src/test/resources/expected/MixedDepsImplementingInterfacesFactory.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+/**
+ * @author Gregory Kick
+ */
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+)
+final class MixedDepsImplementingInterfacesFactory
+    implements MixedDepsImplementingInterfaces.FromInt, MixedDepsImplementingInterfaces.FromObject,
+        MixedDepsImplementingInterfaces.MarkerA, MixedDepsImplementingInterfaces.MarkerB {
+  private final Provider<String> sProvider;
+
+  @Inject MixedDepsImplementingInterfacesFactory(Provider<String> sProvider) {
+    this.sProvider = checkNotNull(sProvider, 1);
+  }
+
+  MixedDepsImplementingInterfaces create(int i) {
+    return new MixedDepsImplementingInterfaces(checkNotNull(sProvider.get(), 1), i);
+  }
+
+  MixedDepsImplementingInterfaces create(Object o) {
+    return new MixedDepsImplementingInterfaces(checkNotNull(o, 1));
+  }
+
+  @Override public MixedDepsImplementingInterfaces fromInt(int i) {
+    return create(i);
+  }
+
+  @Override public MixedDepsImplementingInterfaces fromObject(Object o) {
+    return create(o);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/MultipleFactoriesConflictingParameterNamesFactory.java b/factory/src/test/resources/expected/MultipleFactoriesConflictingParameterNamesFactory.java
new file mode 100644
index 0000000..fac6e13
--- /dev/null
+++ b/factory/src/test/resources/expected/MultipleFactoriesConflictingParameterNamesFactory.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+    value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+    comments = "https://github.com/google/auto/tree/master/factory"
+)
+final class MultipleFactoriesConflictingParameterNamesFactory {
+
+  private final Provider<String> stringProvider;
+  private final Provider<Object> java_lang_ObjectProvider;
+  private final Provider<String> stringProvider2;
+  private final Provider<Object> _tests_AQualifier_java_lang_ObjectProvider;
+
+  @Inject
+  MultipleFactoriesConflictingParameterNamesFactory(
+      Provider<String> stringProvider,
+      Provider<Object> java_lang_ObjectProvider,
+      @AQualifier Provider<String> stringProvider2,
+      @AQualifier Provider<Object> _tests_AQualifier_java_lang_ObjectProvider) {
+    this.stringProvider = checkNotNull(stringProvider, 1);
+    this.java_lang_ObjectProvider = checkNotNull(java_lang_ObjectProvider, 2);
+    this.stringProvider2 = checkNotNull(stringProvider2, 3);
+    this._tests_AQualifier_java_lang_ObjectProvider =
+        checkNotNull(_tests_AQualifier_java_lang_ObjectProvider, 4);
+  }
+
+  MultipleFactoriesConflictingParameterNames create(Object unused) {
+    return new MultipleFactoriesConflictingParameterNames(
+        checkNotNull(stringProvider.get(), 1),
+        checkNotNull(java_lang_ObjectProvider.get(), 2),
+        java_lang_ObjectProvider,
+        checkNotNull(unused, 4));
+  }
+
+  MultipleFactoriesConflictingParameterNames create() {
+    return new MultipleFactoriesConflictingParameterNames(
+        checkNotNull(stringProvider2.get(), 1),
+        checkNotNull(_tests_AQualifier_java_lang_ObjectProvider.get(), 2),
+        _tests_AQualifier_java_lang_ObjectProvider);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassAFactory.java b/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassAFactory.java
new file mode 100644
index 0000000..5ee2b2f
--- /dev/null
+++ b/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassAFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class MultipleFactoriesImplementingInterface_ClassAFactory
+    implements MultipleFactoriesImplementingInterface.Base.Factory {
+  @Inject
+  MultipleFactoriesImplementingInterface_ClassAFactory() {}
+
+  MultipleFactoriesImplementingInterface.ClassA create() {
+    return new MultipleFactoriesImplementingInterface.ClassA();
+  }
+
+  @Override
+  public MultipleFactoriesImplementingInterface.ClassA abstractNonDefaultCreate() {
+    return create();
+  }
+}
diff --git a/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassBFactory.java b/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassBFactory.java
new file mode 100644
index 0000000..f654068
--- /dev/null
+++ b/factory/src/test/resources/expected/MultipleFactoriesImplementingInterface_ClassBFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class MultipleFactoriesImplementingInterface_ClassBFactory
+    implements MultipleFactoriesImplementingInterface.Base.Factory {
+  @Inject
+  MultipleFactoriesImplementingInterface_ClassBFactory() {}
+
+  MultipleFactoriesImplementingInterface.ClassB create() {
+    return new MultipleFactoriesImplementingInterface.ClassB();
+  }
+
+  @Override
+  public MultipleFactoriesImplementingInterface.ClassB abstractNonDefaultCreate() {
+    return create();
+  }
+}
diff --git a/factory/src/test/resources/expected/MultipleProvidedParamsSameKeyFactory.java b/factory/src/test/resources/expected/MultipleProvidedParamsSameKeyFactory.java
new file mode 100644
index 0000000..de7bad7
--- /dev/null
+++ b/factory/src/test/resources/expected/MultipleProvidedParamsSameKeyFactory.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class MultipleProvidedParamsSameKeyFactory {
+  private final Provider<String> java_lang_StringProvider;
+
+  @Inject
+  MultipleProvidedParamsSameKeyFactory(Provider<String> java_lang_StringProvider) {
+    this.java_lang_StringProvider = checkNotNull(java_lang_StringProvider, 1);
+  }
+
+  MultipleProvidedParamsSameKey create() {
+    return new MultipleProvidedParamsSameKey(
+        checkNotNull(java_lang_StringProvider.get(), 1),
+        checkNotNull(java_lang_StringProvider.get(), 2),
+        java_lang_StringProvider.get(),
+        java_lang_StringProvider,
+        java_lang_StringProvider);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/NestedClassCustomNamedFactory.java b/factory/src/test/resources/expected/NestedClassCustomNamedFactory.java
new file mode 100644
index 0000000..bf6a468
--- /dev/null
+++ b/factory/src/test/resources/expected/NestedClassCustomNamedFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class NestedClassCustomNamedFactory {
+  @Inject NestedClassCustomNamedFactory() {}
+
+  NestedClasses.SimpleNestedClassWithCustomFactory create() {
+    return new NestedClasses.SimpleNestedClassWithCustomFactory();
+  }
+}
diff --git a/factory/src/test/resources/expected/NestedClasses_SimpleNestedClassFactory.java b/factory/src/test/resources/expected/NestedClasses_SimpleNestedClassFactory.java
new file mode 100644
index 0000000..f982e86
--- /dev/null
+++ b/factory/src/test/resources/expected/NestedClasses_SimpleNestedClassFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class NestedClasses_SimpleNestedClassFactory {
+  @Inject NestedClasses_SimpleNestedClassFactory() {}
+
+  NestedClasses.SimpleNestedClass create() {
+    return new NestedClasses.SimpleNestedClass();
+  }
+}
diff --git a/factory/src/test/resources/expected/OnlyPrimitivesFactory.java b/factory/src/test/resources/expected/OnlyPrimitivesFactory.java
new file mode 100644
index 0000000..ec60c58
--- /dev/null
+++ b/factory/src/test/resources/expected/OnlyPrimitivesFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class OnlyPrimitivesFactory {
+  @Inject OnlyPrimitivesFactory() {}
+
+  OnlyPrimitives create(int i, long l) {
+    return new OnlyPrimitives(i, l);
+  }
+}
diff --git a/factory/src/test/resources/expected/ProviderArgumentToCreateMethodFactory.java b/factory/src/test/resources/expected/ProviderArgumentToCreateMethodFactory.java
new file mode 100644
index 0000000..4d1a4cf
--- /dev/null
+++ b/factory/src/test/resources/expected/ProviderArgumentToCreateMethodFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+    value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+    comments = "https://github.com/google/auto/tree/master/factory"
+)
+final class ProviderArgumentToCreateMethodFactory
+    implements ProviderArgumentToCreateMethod.CustomCreator{
+  @Inject ProviderArgumentToCreateMethodFactory() {}
+
+  ProviderArgumentToCreateMethod create(Provider<String> stringProvider) {
+    return new ProviderArgumentToCreateMethod(checkNotNull(stringProvider, 1));
+  }
+
+  @Override
+  public ProviderArgumentToCreateMethod newInstance(Provider<String> stringProvider) {
+    return create(stringProvider);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/PublicClassFactory.java b/factory/src/test/resources/expected/PublicClassFactory.java
new file mode 100644
index 0000000..06671dc
--- /dev/null
+++ b/factory/src/test/resources/expected/PublicClassFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+public final class PublicClassFactory {
+  @Inject public PublicClassFactory() {}
+
+  public PublicClass create() {
+    return new PublicClass();
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassFactory.java b/factory/src/test/resources/expected/SimpleClassFactory.java
new file mode 100644
index 0000000..308d2cd
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class SimpleClassFactory {
+  @Inject SimpleClassFactory() {}
+
+  SimpleClass create() {
+    return new SimpleClass();
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassImplementingMarkerFactory.java b/factory/src/test/resources/expected/SimpleClassImplementingMarkerFactory.java
new file mode 100644
index 0000000..6c611e9
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassImplementingMarkerFactory.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import java.util.RandomAccess;
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class SimpleClassImplementingMarkerFactory implements RandomAccess {
+  @Inject SimpleClassImplementingMarkerFactory() {}
+
+  SimpleClassImplementingMarker create() {
+    return new SimpleClassImplementingMarker();
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassImplementingSimpleInterfaceFactory.java b/factory/src/test/resources/expected/SimpleClassImplementingSimpleInterfaceFactory.java
new file mode 100644
index 0000000..720e7d0
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassImplementingSimpleInterfaceFactory.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class SimpleClassImplementingSimpleInterfaceFactory
+    implements SimpleClassImplementingSimpleInterface.SimpleInterface {
+  @Inject SimpleClassImplementingSimpleInterfaceFactory() {}
+
+  SimpleClassImplementingSimpleInterface create() {
+    return new SimpleClassImplementingSimpleInterface();
+  }
+
+  @Override public SimpleClassImplementingSimpleInterface newInstance() {
+    return create();
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassMixedDepsFactory.java b/factory/src/test/resources/expected/SimpleClassMixedDepsFactory.java
new file mode 100644
index 0000000..ccdea61
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassMixedDepsFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class SimpleClassMixedDepsFactory {
+  private final Provider<String> providedDepAProvider;
+
+  @Inject SimpleClassMixedDepsFactory(
+      @AQualifier Provider<String> providedDepAProvider) {
+    this.providedDepAProvider = checkNotNull(providedDepAProvider, 1);
+  }
+
+  SimpleClassMixedDeps create(String depB) {
+    return new SimpleClassMixedDeps(
+        checkNotNull(providedDepAProvider.get(), 1), checkNotNull(depB, 2));
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassNonFinalFactory.java b/factory/src/test/resources/expected/SimpleClassNonFinalFactory.java
new file mode 100644
index 0000000..d323812
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassNonFinalFactory.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+class SimpleClassNonFinalFactory {
+  @Inject SimpleClassNonFinalFactory() {}
+
+  SimpleClassNonFinal create() {
+    return new SimpleClassNonFinal();
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassNullableParametersFactory.java b/factory/src/test/resources/expected/SimpleClassNullableParametersFactory.java
new file mode 100644
index 0000000..e354038
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassNullableParametersFactory.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.Nullable;
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class SimpleClassNullableParametersFactory {
+  private final Provider<String> providedNullableProvider;
+
+  private final Provider<String> providedQualifiedNullableProvider;
+
+  @Inject
+  SimpleClassNullableParametersFactory(
+      Provider<String> providedNullableProvider,
+      @BQualifier Provider<String> providedQualifiedNullableProvider) {
+    this.providedNullableProvider = checkNotNull(providedNullableProvider, 1);
+    this.providedQualifiedNullableProvider = checkNotNull(providedQualifiedNullableProvider, 2);
+  }
+
+  SimpleClassNullableParameters create(
+      @Nullable String nullable, @Nullable @AQualifier String qualifiedNullable) {
+    return new SimpleClassNullableParameters(
+        nullable,
+        qualifiedNullable,
+        providedNullableProvider.get(),
+        providedQualifiedNullableProvider.get());
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassPassedDepsFactory.java b/factory/src/test/resources/expected/SimpleClassPassedDepsFactory.java
new file mode 100644
index 0000000..3260c36
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassPassedDepsFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class SimpleClassPassedDepsFactory {
+  @Inject SimpleClassPassedDepsFactory() {}
+
+  SimpleClassPassedDeps create(String depA, String depB) {
+    return new SimpleClassPassedDeps(checkNotNull(depA, 1), checkNotNull(depB, 2));
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassProvidedDepsFactory.java b/factory/src/test/resources/expected/SimpleClassProvidedDepsFactory.java
new file mode 100644
index 0000000..05d1e5a
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassProvidedDepsFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class SimpleClassProvidedDepsFactory {
+  private final Provider<Integer> providedPrimitiveAProvider;
+  private final Provider<Integer> providedPrimitiveBProvider;
+  private final Provider<String> providedDepAProvider;
+  private final Provider<String> providedDepBProvider;
+
+  @Inject
+  SimpleClassProvidedDepsFactory(
+      @AQualifier Provider<Integer> providedPrimitiveAProvider,
+      @BQualifier Provider<Integer> providedPrimitiveBProvider,
+      @AQualifier Provider<String> providedDepAProvider,
+      @BQualifier Provider<String> providedDepBProvider) {
+    this.providedPrimitiveAProvider = checkNotNull(providedPrimitiveAProvider, 1);
+    this.providedPrimitiveBProvider = checkNotNull(providedPrimitiveBProvider, 2);
+    this.providedDepAProvider = checkNotNull(providedDepAProvider, 3);
+    this.providedDepBProvider = checkNotNull(providedDepBProvider, 4);
+  }
+
+  SimpleClassProvidedDeps create() {
+    return new SimpleClassProvidedDeps(
+        checkNotNull(providedPrimitiveAProvider.get(), 1),
+        checkNotNull(providedPrimitiveBProvider.get(), 2),
+        checkNotNull(providedDepAProvider.get(), 3),
+        checkNotNull(providedDepBProvider.get(), 4));
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassProvidedProviderDepsFactory.java b/factory/src/test/resources/expected/SimpleClassProvidedProviderDepsFactory.java
new file mode 100644
index 0000000..aafdcec
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassProvidedProviderDepsFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+import javax.inject.Provider;
+
+@Generated(
+  value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+  comments = "https://github.com/google/auto/tree/master/factory"
+  )
+final class SimpleClassProvidedProviderDepsFactory {
+  private final Provider<String> providedDepAProvider;
+  private final Provider<String> providedDepBProvider;
+
+  @Inject
+  SimpleClassProvidedProviderDepsFactory(
+      @AQualifier Provider<String> providedDepAProvider,
+      @BQualifier Provider<String> providedDepBProvider) {
+    this.providedDepAProvider = checkNotNull(providedDepAProvider, 1);
+    this.providedDepBProvider = checkNotNull(providedDepBProvider, 2);
+  }
+
+  SimpleClassProvidedProviderDeps create() {
+    return new SimpleClassProvidedProviderDeps(providedDepAProvider, providedDepBProvider);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/expected/SimpleClassVarargsFactory.java b/factory/src/test/resources/expected/SimpleClassVarargsFactory.java
new file mode 100644
index 0000000..51c7f46
--- /dev/null
+++ b/factory/src/test/resources/expected/SimpleClassVarargsFactory.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import javax.annotation.processing.Generated;
+import javax.inject.Inject;
+
+@Generated(
+    value = "com.google.auto.factory.processor.AutoFactoryProcessor",
+    comments = "https://github.com/google/auto/tree/master/factory"
+)
+final class SimpleClassVarargsFactory implements SimpleClassVarargs.InterfaceWithVarargs {
+  @Inject SimpleClassVarargsFactory() {}
+
+  SimpleClassVarargs create(String... args) {
+    return new SimpleClassVarargs(checkNotNull(args, 1));
+  }
+
+  @Override
+  public SimpleClassVarargs build(String... args) {
+    return create(args);
+  }
+
+  private static <T> T checkNotNull(T reference, int argumentIndex) {
+    if (reference == null) {
+      throw new NullPointerException(
+          "@AutoFactory method argument is null but is not marked @Nullable. Argument index: "
+              + argumentIndex);
+    }
+    return reference;
+  }
+}
diff --git a/factory/src/test/resources/good/CheckerFrameworkNullable.java b/factory/src/test/resources/good/CheckerFrameworkNullable.java
new file mode 100644
index 0000000..7f2a0fe
--- /dev/null
+++ b/factory/src/test/resources/good/CheckerFrameworkNullable.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import org.checkerframework.checker.nullness.compatqual.NullableDecl;
+import org.checkerframework.checker.nullness.compatqual.NullableType;
+
+@AutoFactory
+final class CheckerFrameworkNullable {
+
+  CheckerFrameworkNullable(
+      @NullableDecl String nullableDecl,
+      @Provided @NullableDecl String providedNullableDecl,
+      @NullableType String nullableType,
+      @Provided @NullableType String providedNullableType) {}
+}
diff --git a/factory/src/test/resources/good/ClassUsingQualifierWithArgs.java b/factory/src/test/resources/good/ClassUsingQualifierWithArgs.java
new file mode 100644
index 0000000..4a5b8c3
--- /dev/null
+++ b/factory/src/test/resources/good/ClassUsingQualifierWithArgs.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+/**
+ * @author Justine Tunney
+ */
+@AutoFactory
+@SuppressWarnings("unused")
+final class ClassUsingQualifierWithArgs {
+  private final String providedDepA;
+
+  ClassUsingQualifierWithArgs(
+      @Provided @QualifierWithArgs(name = "Fred", count = 3) String providedDepA) {
+    this.providedDepA = providedDepA;
+  }
+}
diff --git a/factory/src/test/resources/good/ConstructorAnnotated.java b/factory/src/test/resources/good/ConstructorAnnotated.java
new file mode 100644
index 0000000..fdc02f3
--- /dev/null
+++ b/factory/src/test/resources/good/ConstructorAnnotated.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+final class ConstructorAnnotated {
+  @AutoFactory ConstructorAnnotated() {}
+  ConstructorAnnotated(Object obj) {}
+  @AutoFactory ConstructorAnnotated(String s) {}
+  @AutoFactory ConstructorAnnotated(@Provided Object obj, int i) {}
+  @AutoFactory ConstructorAnnotated(@Provided Object obj, char c) {}
+}
diff --git a/factory/src/test/resources/good/ConstructorAnnotatedNonFinal.java b/factory/src/test/resources/good/ConstructorAnnotatedNonFinal.java
new file mode 100644
index 0000000..5bed1e6
--- /dev/null
+++ b/factory/src/test/resources/good/ConstructorAnnotatedNonFinal.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+final class ConstructorAnnotatedNonFinal {
+  @AutoFactory(allowSubclasses = true) ConstructorAnnotatedNonFinal() {}
+  ConstructorAnnotatedNonFinal(Object obj) {}
+  @AutoFactory(allowSubclasses = true) ConstructorAnnotatedNonFinal(String s) {}
+  @AutoFactory(allowSubclasses = true) ConstructorAnnotatedNonFinal(@Provided Object obj, int i) {}
+  @AutoFactory(allowSubclasses = true) ConstructorAnnotatedNonFinal(@Provided Object obj, char c) {}
+}
diff --git a/factory/src/test/resources/good/CustomNullable.java b/factory/src/test/resources/good/CustomNullable.java
new file mode 100644
index 0000000..bdf2e7c
--- /dev/null
+++ b/factory/src/test/resources/good/CustomNullable.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+@AutoFactory
+final class CustomNullable {
+
+  private final String string;
+  private final Object object;
+
+  CustomNullable(
+      @CustomNullable.Nullable String string, @CustomNullable.Nullable @Provided Object object) {
+    this.string = string;
+    this.object = object;
+  }
+
+  @interface Nullable {}
+}
diff --git a/factory/src/test/resources/good/DefaultPackage.java b/factory/src/test/resources/good/DefaultPackage.java
new file mode 100644
index 0000000..f4efee6
--- /dev/null
+++ b/factory/src/test/resources/good/DefaultPackage.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+import com.google.auto.factory.AutoFactory;
+
+@AutoFactory
+public final class DefaultPackage {}
diff --git a/factory/src/test/resources/good/FactoryExtendingAbstractClass.java b/factory/src/test/resources/good/FactoryExtendingAbstractClass.java
new file mode 100644
index 0000000..5511e99
--- /dev/null
+++ b/factory/src/test/resources/good/FactoryExtendingAbstractClass.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import tests.FactoryExtendingAbstractClass.AbstractFactory;
+
+@AutoFactory(extending = AbstractFactory.class)
+final class FactoryExtendingAbstractClass {
+  static abstract class AbstractFactory {
+    abstract FactoryExtendingAbstractClass newInstance();
+  }
+}
diff --git a/factory/src/test/resources/good/FactoryExtendingAbstractClassWithConstructorParams.java b/factory/src/test/resources/good/FactoryExtendingAbstractClassWithConstructorParams.java
new file mode 100644
index 0000000..98c5f66
--- /dev/null
+++ b/factory/src/test/resources/good/FactoryExtendingAbstractClassWithConstructorParams.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import tests.FactoryExtendingAbstractClassWithConstructorParams.AbstractFactory;
+
+@AutoFactory(extending = AbstractFactory.class)
+final class FactoryExtendingAbstractClassWithConstructorParams {
+  static abstract class AbstractFactory {
+    protected AbstractFactory(Object obj) {}
+    
+    abstract FactoryExtendingAbstractClassWithConstructorParams newInstance();
+  }
+}
diff --git a/factory/src/test/resources/good/FactoryExtendingAbstractClassWithMultipleConstructors.java b/factory/src/test/resources/good/FactoryExtendingAbstractClassWithMultipleConstructors.java
new file mode 100644
index 0000000..43e94ce
--- /dev/null
+++ b/factory/src/test/resources/good/FactoryExtendingAbstractClassWithMultipleConstructors.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import tests.FactoryExtendingAbstractClassWithMultipleConstructors.AbstractFactory;
+
+@AutoFactory(extending = AbstractFactory.class)
+final class FactoryExtendingAbstractClassWithMultipleConstructors {
+  static abstract class AbstractFactory {
+    protected AbstractFactory(Object obj) {}
+    protected AbstractFactory() {}
+    
+    abstract FactoryExtendingAbstractClassWithMultipleConstructors newInstance();
+  }
+}
diff --git a/factory/src/test/resources/good/FactoryImplementingCreateMethod.java b/factory/src/test/resources/good/FactoryImplementingCreateMethod.java
new file mode 100644
index 0000000..db15eef
--- /dev/null
+++ b/factory/src/test/resources/good/FactoryImplementingCreateMethod.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import java.util.List;
+
+final class FactoryImplementingCreateMethod {
+
+  interface Interface {}
+
+  interface FactoryInterfaceWithCreateMethod {
+    Interface create();
+
+    Interface create(int a);
+    
+    Interface create(List<Integer> generic);
+  }
+
+  @AutoFactory(implementing = FactoryInterfaceWithCreateMethod.class)
+  static class ConcreteClass implements Interface {
+    // Will generate a method with a signature that matches one from the interface.
+    ConcreteClass() {}
+
+    // Will generate a method with a signature that matches one from the interface.
+    ConcreteClass(int aDifferentArgumentName) {}
+
+    // Will generate a method with a signature that matches one from the interface.
+    ConcreteClass(List<Integer> genericWithDifferentArgumentName) {}
+
+    ConcreteClass(int a, boolean b) {}
+  }
+}
diff --git a/factory/src/test/resources/good/FactoryImplementingGenericInterfaceExtension.java b/factory/src/test/resources/good/FactoryImplementingGenericInterfaceExtension.java
new file mode 100644
index 0000000..0d0565f
--- /dev/null
+++ b/factory/src/test/resources/good/FactoryImplementingGenericInterfaceExtension.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+class FactoryImplementingGenericInterfaceExtension {
+
+  @AutoFactory(implementing = MyFactory.class)
+  FactoryImplementingGenericInterfaceExtension(@Provided String s, Integer i) {}
+
+  interface MyFactory
+      extends GenericFactory<FactoryImplementingGenericInterfaceExtension, Integer> {}
+
+  interface GenericFactory<T, S> {
+    T make(S arg);
+  }
+}
diff --git a/factory/src/test/resources/good/MixedDepsImplementingInterfaces.java b/factory/src/test/resources/good/MixedDepsImplementingInterfaces.java
new file mode 100644
index 0000000..c7435ed
--- /dev/null
+++ b/factory/src/test/resources/good/MixedDepsImplementingInterfaces.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+/**
+ * @author Gregory Kick
+ */
+final class MixedDepsImplementingInterfaces {
+  @AutoFactory(implementing = {FromInt.class, MarkerA.class})
+  MixedDepsImplementingInterfaces(@Provided String s, int i) {}
+  
+  @AutoFactory(implementing = {FromObject.class, MarkerB.class})
+  MixedDepsImplementingInterfaces(Object o) {}
+
+  interface FromInt {
+    MixedDepsImplementingInterfaces fromInt(int i);
+  }
+  
+  interface FromObject {
+    MixedDepsImplementingInterfaces fromObject(Object o);
+  }
+  
+  interface MarkerA {}
+
+  interface MarkerB {}
+}
diff --git a/factory/src/test/resources/good/MultipleFactoriesConflictingParameterNames.java b/factory/src/test/resources/good/MultipleFactoriesConflictingParameterNames.java
new file mode 100644
index 0000000..b6a3106
--- /dev/null
+++ b/factory/src/test/resources/good/MultipleFactoriesConflictingParameterNames.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import javax.inject.Provider;
+
+class MultipleFactoriesConflictingParameterNames {
+
+  @AutoFactory
+  MultipleFactoriesConflictingParameterNames(
+      @Provided String string,
+      @Provided Object duplicatedKey_nameDoesntMatter,
+      @Provided Provider<Object> duplicatedKeyProvider_nameDoesntMatter,
+      // used to disambiguate with the second constructor since qualifiers aren't part of the type
+      // system
+      Object unused) {}
+
+  @AutoFactory
+  MultipleFactoriesConflictingParameterNames(
+      @Provided @AQualifier String string,
+      @Provided @AQualifier Object qualifiedDuplicatedKey_nameDoesntMatter,
+      @Provided @AQualifier Provider<Object> qualifiedDuplicatedKeyProvider_nameDoesntMatter) {}
+}
diff --git a/factory/src/test/resources/good/MultipleFactoriesImplementingInterface.java b/factory/src/test/resources/good/MultipleFactoriesImplementingInterface.java
new file mode 100644
index 0000000..2eecf1a
--- /dev/null
+++ b/factory/src/test/resources/good/MultipleFactoriesImplementingInterface.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+class MultipleFactoriesImplementingInterface {  
+  static interface Base {
+    static interface Factory {
+      public abstract Base abstractNonDefaultCreate();
+    }
+  }
+
+  @AutoFactory(implementing = Base.Factory.class)
+  static class ClassA implements Base { }
+
+  @AutoFactory(implementing = Base.Factory.class)
+  static class ClassB implements Base {}
+}  
diff --git a/factory/src/test/resources/good/MultipleProvidedParamsSameKey.java b/factory/src/test/resources/good/MultipleProvidedParamsSameKey.java
new file mode 100644
index 0000000..b338d34
--- /dev/null
+++ b/factory/src/test/resources/good/MultipleProvidedParamsSameKey.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import javax.annotation.Nullable;
+import javax.inject.Provider;
+
+@AutoFactory
+final class MultipleProvidedParamsSameKey {
+  private final String one;
+  private final String two;
+  private final String three;
+  private final Provider<String> providerOne;
+  private final Provider<String> providerTwo;
+
+  public MultipleProvidedParamsSameKey(
+      @Provided String one,
+      @Provided String two,
+      @Nullable @Provided String three,
+      @Provided Provider<String> providerOne,
+      @Provided Provider<String> providerTwo) {
+    this.one = one;
+    this.two = two;
+    this.three = three;
+    this.providerOne = providerOne;
+    this.providerTwo = providerTwo;
+  }
+}
diff --git a/factory/src/test/resources/good/NestedClasses.java b/factory/src/test/resources/good/NestedClasses.java
new file mode 100644
index 0000000..93dbe84
--- /dev/null
+++ b/factory/src/test/resources/good/NestedClasses.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+final class NestedClasses {
+
+  @AutoFactory
+  static final class SimpleNestedClass {}
+
+  @AutoFactory(className = "NestedClassCustomNamedFactory")
+  static final class SimpleNestedClassWithCustomFactory {}
+}
diff --git a/factory/src/test/resources/good/OnlyPrimitives.java b/factory/src/test/resources/good/OnlyPrimitives.java
new file mode 100644
index 0000000..ed39123
--- /dev/null
+++ b/factory/src/test/resources/good/OnlyPrimitives.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+/** @author Ron Shapiro */
+@AutoFactory
+final class OnlyPrimitives {
+  OnlyPrimitives(int i, long l) {}
+}
diff --git a/factory/src/test/resources/good/ProviderArgumentToCreateMethod.java b/factory/src/test/resources/good/ProviderArgumentToCreateMethod.java
new file mode 100644
index 0000000..f1f3735
--- /dev/null
+++ b/factory/src/test/resources/good/ProviderArgumentToCreateMethod.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import javax.inject.Provider;
+
+@AutoFactory(implementing = ProviderArgumentToCreateMethod.CustomCreator.class)
+final class ProviderArgumentToCreateMethod {
+  private final Provider<String> stringProvider;
+
+  ProviderArgumentToCreateMethod(Provider<String> stringProvider) {
+    this.stringProvider = stringProvider;
+  }
+
+  interface CustomCreator {
+    ProviderArgumentToCreateMethod newInstance(Provider<String> stringProvider);
+  }
+}
diff --git a/factory/src/test/resources/good/PublicClass.java b/factory/src/test/resources/good/PublicClass.java
new file mode 100644
index 0000000..78da11d
--- /dev/null
+++ b/factory/src/test/resources/good/PublicClass.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+@AutoFactory
+public final class PublicClass {}
diff --git a/factory/src/test/resources/good/SimpleClass.java b/factory/src/test/resources/good/SimpleClass.java
new file mode 100644
index 0000000..227a4bb
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClass.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+@AutoFactory
+final class SimpleClass {}
diff --git a/factory/src/test/resources/good/SimpleClassCustomName.java b/factory/src/test/resources/good/SimpleClassCustomName.java
new file mode 100644
index 0000000..f842c16
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassCustomName.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+@AutoFactory(className = "CustomNamedFactory")
+final class SimpleClassCustomName {}
diff --git a/factory/src/test/resources/good/SimpleClassImplementingMarker.java b/factory/src/test/resources/good/SimpleClassImplementingMarker.java
new file mode 100644
index 0000000..24e3abc
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassImplementingMarker.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Google LLC
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * 
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import java.util.RandomAccess;
+
+@AutoFactory(implementing = RandomAccess.class)
+class SimpleClassImplementingMarker {
+}
diff --git a/factory/src/test/resources/good/SimpleClassImplementingSimpleInterface.java b/factory/src/test/resources/good/SimpleClassImplementingSimpleInterface.java
new file mode 100644
index 0000000..ddc324c
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassImplementingSimpleInterface.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import tests.SimpleClassImplementingSimpleInterface.SimpleInterface;
+
+@AutoFactory(implementing = SimpleInterface.class)
+final class SimpleClassImplementingSimpleInterface {
+  interface SimpleInterface {
+    SimpleClassImplementingSimpleInterface newInstance();
+  }
+}
diff --git a/factory/src/test/resources/good/SimpleClassMixedDeps.java b/factory/src/test/resources/good/SimpleClassMixedDeps.java
new file mode 100644
index 0000000..05d627c
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassMixedDeps.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+/**
+ * @author Gregory Kick
+ */
+@AutoFactory
+@SuppressWarnings("unused")
+final class SimpleClassMixedDeps {
+  private final String providedDepA;
+  private final String depB;
+
+  SimpleClassMixedDeps(@Provided @AQualifier String providedDepA, String depB) {
+    this.providedDepA = providedDepA;
+    this.depB = depB;
+  }
+}
diff --git a/factory/src/test/resources/good/SimpleClassNonFinal.java b/factory/src/test/resources/good/SimpleClassNonFinal.java
new file mode 100644
index 0000000..a05d61b
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassNonFinal.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+@AutoFactory(allowSubclasses = true)
+final class SimpleClassNonFinal {}
diff --git a/factory/src/test/resources/good/SimpleClassNullableParameters.java b/factory/src/test/resources/good/SimpleClassNullableParameters.java
new file mode 100644
index 0000000..dcaf618
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassNullableParameters.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import javax.annotation.Nullable;
+
+@AutoFactory
+@SuppressWarnings("unused")
+final class SimpleClassNullableParameters {
+  @Nullable private final String nullable;
+  @Nullable private final String qualifiedNullable;
+  @Nullable private final String providedNullable;
+  @Nullable private final String providedQualifiedNullable;
+
+  // TODO(ronshapiro): with Java 8, test Provider<@Nullable String> parameters and provider fields
+  SimpleClassNullableParameters(
+      @Nullable String nullable,
+      @Nullable @AQualifier String qualifiedNullable,
+      @Nullable @Provided String providedNullable,
+      @Nullable @Provided @BQualifier String providedQualifiedNullable) {
+    this.nullable = nullable;
+    this.qualifiedNullable = qualifiedNullable;
+    this.providedNullable = providedNullable;
+    this.providedQualifiedNullable = providedQualifiedNullable;
+  }
+}
diff --git a/factory/src/test/resources/good/SimpleClassPassedDeps.java b/factory/src/test/resources/good/SimpleClassPassedDeps.java
new file mode 100644
index 0000000..b002fbf
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassPassedDeps.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+/**
+ * @author Gregory Kick
+ */
+@AutoFactory
+@SuppressWarnings("unused")
+final class SimpleClassPassedDeps {
+  private final String depA;
+  private final String depB;
+
+  SimpleClassPassedDeps(String depA, String depB) {
+    this.depA = depA;
+    this.depB = depB;
+  }
+}
diff --git a/factory/src/test/resources/good/SimpleClassProvidedDeps.java b/factory/src/test/resources/good/SimpleClassProvidedDeps.java
new file mode 100644
index 0000000..ffcefd2
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassProvidedDeps.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2013 Google LLC
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * 
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+
+/**
+ * @author Gregory Kick
+ */
+@AutoFactory
+@SuppressWarnings("unused")
+final class SimpleClassProvidedDeps {
+  private final int providedPrimitiveA;
+  private final int providedPrimitiveB;
+  private final String providedDepA;
+  private final String providedDepB;
+
+  SimpleClassProvidedDeps(
+      @Provided @AQualifier int providedPrimitiveA,
+      @Provided @BQualifier int providedPrimitiveB,
+      @Provided @AQualifier String providedDepA,
+      @Provided @BQualifier String providedDepB) {
+    this.providedPrimitiveA = providedPrimitiveA;
+    this.providedPrimitiveB = providedPrimitiveB;
+    this.providedDepA = providedDepA;
+    this.providedDepB = providedDepB;
+  }
+}
diff --git a/factory/src/test/resources/good/SimpleClassProvidedProviderDeps.java b/factory/src/test/resources/good/SimpleClassProvidedProviderDeps.java
new file mode 100644
index 0000000..ff01360
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassProvidedProviderDeps.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+import com.google.auto.factory.Provided;
+import javax.inject.Provider;
+
+/**
+ * @author Gregory Kick
+ */
+@AutoFactory
+@SuppressWarnings("unused")
+final class SimpleClassProvidedProviderDeps {
+  private final Provider<String> providedDepA;
+  private final Provider<String> providedDepB;
+
+  SimpleClassProvidedProviderDeps(
+      @Provided @AQualifier Provider<String> providedDepA,
+      @Provided @BQualifier Provider<String> providedDepB) {
+    this.providedDepA = providedDepA;
+    this.providedDepB = providedDepB;
+  }
+}
diff --git a/factory/src/test/resources/good/SimpleClassVarargs.java b/factory/src/test/resources/good/SimpleClassVarargs.java
new file mode 100644
index 0000000..57beb74
--- /dev/null
+++ b/factory/src/test/resources/good/SimpleClassVarargs.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import com.google.auto.factory.AutoFactory;
+
+@AutoFactory(implementing = SimpleClassVarargs.InterfaceWithVarargs.class)
+final class SimpleClassVarargs {
+  private final String[] args;
+
+  SimpleClassVarargs(String... args) {
+    this.args = args;
+  }
+
+  interface InterfaceWithVarargs {
+    SimpleClassVarargs build(String... args);
+  }
+}
diff --git a/factory/src/test/resources/support/AQualifier.java b/factory/src/test/resources/support/AQualifier.java
new file mode 100644
index 0000000..5836941
--- /dev/null
+++ b/factory/src/test/resources/support/AQualifier.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import javax.inject.Qualifier;
+
+/**
+ * @author Gregory Kick
+ */
+@Documented
+@Qualifier
+@Retention(RUNTIME)
+@interface AQualifier {}
diff --git a/factory/src/test/resources/support/BQualifier.java b/factory/src/test/resources/support/BQualifier.java
new file mode 100644
index 0000000..0b7a167
--- /dev/null
+++ b/factory/src/test/resources/support/BQualifier.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import javax.inject.Qualifier;
+
+/**
+ * @author Gregory Kick
+ */
+@Documented
+@Qualifier
+@Retention(RUNTIME)
+@interface BQualifier {}
diff --git a/factory/src/test/resources/support/QualifierWithArgs.java b/factory/src/test/resources/support/QualifierWithArgs.java
new file mode 100644
index 0000000..81e3f84
--- /dev/null
+++ b/factory/src/test/resources/support/QualifierWithArgs.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 tests;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import javax.inject.Qualifier;
+
+/**
+ * @author Justine Tunney
+ */
+@Documented
+@Qualifier
+@Retention(RUNTIME)
+@interface QualifierWithArgs {
+  String name();
+  int count();
+}
diff --git a/service/README.md b/service/README.md
new file mode 100644
index 0000000..5016456
--- /dev/null
+++ b/service/README.md
@@ -0,0 +1,112 @@
+# AutoService
+
+A configuration/metadata generator for java.util.ServiceLoader-style service
+providers
+
+## AutoWhat‽
+
+[Java][java] annotation processors and other systems use
+[java.util.ServiceLoader][sl] to register implementations of well-known types
+using META-INF metadata. However, it is easy for a developer to forget to update
+or correctly specify the service descriptors. \
+AutoService generates this metadata for the developer, for any class annotated
+with `@AutoService`, avoiding typos, providing resistance to errors from
+refactoring, etc.
+
+## Example
+
+Say you have:
+
+```java
+package foo.bar;
+
+import javax.annotation.processing.Processor;
+
+@AutoService(Processor.class)
+final class MyProcessor implements Processor {
+  // …
+}
+```
+
+AutoService will generate the file
+`META-INF/services/javax.annotation.processing.Processor` in the output classes
+folder. The file will contain:
+
+```
+foo.bar.MyProcessor
+```
+
+In the case of javax.annotation.processing.Processor, if this metadata file is
+included in a jar, and that jar is on javac's classpath, then `javac` will
+automatically load it, and include it in its normal annotation processing
+environment. Other users of java.util.ServiceLoader may use the infrastructure
+to different ends, but this metadata will provide auto-loading appropriately.
+
+## Getting Started
+
+You will need `auto-service-annotations-${version}.jar` in your compile-time
+classpath, and you will need `auto-service-${version}.jar` in your
+annotation-processor classpath.
+
+In Maven, you can write:
+
+```xml
+<dependencies>
+  <dependency>
+    <groupId>com.google.auto.service</groupId>
+    <artifactId>auto-service-annotations</artifactId>
+    <version>${auto-service.version}</version>
+  </dependency>
+</dependencies>
+
+...
+
+<plugins>
+  <plugin>
+    <artifactId>maven-compiler-plugin</artifactId>
+    <configuration>
+      <annotationProcessorPaths>
+        <path>
+          <groupId>com.google.auto.service</groupId>
+          <artifactId>auto-service</artifactId>
+          <version>${auto-service.version}</version>
+        </path>
+      </annotationProcessorPaths>
+    </configuration>
+  </plugin>
+</plugins>
+```
+
+Alternatively, you can include the processor itself (which transitively depends
+on the annotation) in your compile-time classpath. (However, note that doing so
+may pull unnecessary classes into your runtime classpath.)
+
+```xml
+<dependencies>
+  <dependency>
+    <groupId>com.google.auto.service</groupId>
+    <artifactId>auto-service</artifactId>
+    <version>${version}</version>
+    <optional>true</optional>
+  </dependency>
+</dependencies>
+```
+
+## License
+
+    Copyright 2013 Google LLC
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       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.
+
+[java]: https://en.wikipedia.org/wiki/Java_(programming_language)
+[sl]: http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
diff --git a/service/annotations/pom.xml b/service/annotations/pom.xml
new file mode 100644
index 0000000..e84147d
--- /dev/null
+++ b/service/annotations/pom.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2013 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.auto.service</groupId>
+    <artifactId>auto-service-aggregator</artifactId>
+    <version>HEAD-SNAPSHOT</version>
+  </parent>
+
+  <groupId>com.google.auto.service</groupId>
+  <artifactId>auto-service-annotations</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>AutoService</name>
+  <description>
+    Provider-configuration files for ServiceLoader.
+  </description>
+  <url>https://github.com/google/auto/tree/master/service</url>
+
+  <scm>
+    <url>http://github.com/google/auto</url>
+    <connection>scm:git:git://github.com/google/auto.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestEntries>
+              <Automatic-Module-Name>com.google.auto.service</Automatic-Module-Name>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <!-- disable processing because the definition in META-INF/services breaks javac -->
+          <compilerArgument>-proc:none</compilerArgument>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/service/annotations/src/main/java/com/google/auto/service/AutoService.java b/service/annotations/src/main/java/com/google/auto/service/AutoService.java
new file mode 100644
index 0000000..260766c
--- /dev/null
+++ b/service/annotations/src/main/java/com/google/auto/service/AutoService.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.service;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation for service providers as described in {@link java.util.ServiceLoader}. The
+ * annotation processor generates the configuration files that allow the annotated class to be
+ * loaded with {@link java.util.ServiceLoader#load(Class)}.
+ *
+ * <p>The annotated class must conform to the service provider specification. Specifically, it must:
+ *
+ * <ul>
+ *   <li>be a non-inner, non-anonymous, concrete class
+ *   <li>have a publicly accessible no-arg constructor
+ *   <li>implement the interface type returned by {@code value()}
+ * </ul>
+ */
+@Documented
+@Retention(CLASS)
+@Target(TYPE)
+public @interface AutoService {
+  /** Returns the interfaces implemented by this service provider. */
+  Class<?>[] value();
+}
diff --git a/service/pom.xml b/service/pom.xml
new file mode 100644
index 0000000..a64ca05
--- /dev/null
+++ b/service/pom.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2013 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.sonatype.oss</groupId>
+    <artifactId>oss-parent</artifactId>
+    <version>7</version>
+  </parent>
+
+  <groupId>com.google.auto.service</groupId>
+  <artifactId>auto-service-aggregator</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>AutoService Aggregator</name>
+  <description>
+    Aggregator POM for @AutoService
+  </description>
+  <packaging>pom</packaging>
+  <url>https://github.com/google/auto/tree/master/service</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <java.version>1.8</java.version>
+    <guava.version>27.0.1-jre</guava.version>
+    <truth.version>1.0.1</truth.version>
+  </properties>
+
+  <scm>
+    <url>http://github.com/google/auto</url>
+    <connection>scm:git:git://github.com/google/auto.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+
+  <issueManagement>
+    <system>GitHub Issues</system>
+    <url>http://github.com/google/auto/issues</url>
+  </issueManagement>
+
+  <licenses>
+    <license>
+      <name>Apache 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+    </license>
+  </licenses>
+
+  <organization>
+    <name>Google LLC</name>
+    <url>http://www.google.com</url>
+  </organization>
+
+  <modules>
+    <module>annotations</module>
+    <module>processor</module>
+  </modules>
+
+  <dependencyManagement>
+    <dependencies>
+      <!-- main dependencies -->
+
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava-gwt</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
+
+      <!-- test dependencies -->
+
+      <dependency>
+        <groupId>com.google.testing.compile</groupId>
+        <artifactId>compile-testing</artifactId>
+        <version>0.18</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.truth</groupId>
+        <artifactId>truth</artifactId>
+        <version>${truth.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.12</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>3.7.0</version>
+          <configuration>
+            <source>${java.version}</source>
+            <target>${java.version}</target>
+            <compilerArgument>-Xlint:all</compilerArgument>
+            <showWarnings>true</showWarnings>
+            <showDeprecation>true</showDeprecation>
+          </configuration>
+          <dependencies>
+            <dependency>
+              <groupId>org.codehaus.plexus</groupId>
+              <artifactId>plexus-java</artifactId>
+              <version>0.9.4</version>
+            </dependency>
+          </dependencies>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jar-plugin</artifactId>
+          <version>3.0.2</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
diff --git a/service/processor/pom.xml b/service/processor/pom.xml
new file mode 100644
index 0000000..22fc20e
--- /dev/null
+++ b/service/processor/pom.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2013 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.auto.service</groupId>
+    <artifactId>auto-service-aggregator</artifactId>
+    <version>HEAD-SNAPSHOT</version>
+  </parent>
+
+  <groupId>com.google.auto.service</groupId>
+  <artifactId>auto-service</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>AutoService Processor</name>
+  <description>
+    Provider-configuration files for ServiceLoader.
+  </description>
+  <url>https://github.com/google/auto/tree/master/service</url>
+
+  <scm>
+    <url>http://github.com/google/auto</url>
+    <connection>scm:git:git://github.com/google/auto.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.auto.service</groupId>
+      <artifactId>auto-service-annotations</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto</groupId>
+      <artifactId>auto-common</artifactId>
+      <version>0.10</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <!-- test dependencies -->
+    <dependency>
+      <groupId>com.google.testing.compile</groupId>
+      <artifactId>compile-testing</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <!-- disable processing because the definition in META-INF/services breaks javac -->
+          <compilerArgument>-proc:none</compilerArgument>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/service/processor/src/main/java/com/google/auto/service/processor/AutoServiceProcessor.java b/service/processor/src/main/java/com/google/auto/service/processor/AutoServiceProcessor.java
new file mode 100644
index 0000000..3bf42d9
--- /dev/null
+++ b/service/processor/src/main/java/com/google/auto/service/processor/AutoServiceProcessor.java
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.service.processor;
+
+import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
+import static com.google.auto.common.MoreElements.getAnnotationMirror;
+import static com.google.common.collect.ImmutableSet.toImmutableSet;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.service.AutoService;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedOptions;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic.Kind;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
+
+/**
+ * Processes {@link AutoService} annotations and generates the service provider
+ * configuration files described in {@link java.util.ServiceLoader}.
+ * <p>
+ * Processor Options:<ul>
+ *   <li>debug - turns on debug statements</li>
+ * </ul>
+ */
+@SupportedOptions({ "debug", "verify" })
+public class AutoServiceProcessor extends AbstractProcessor {
+
+  @VisibleForTesting
+  static final String MISSING_SERVICES_ERROR = "No service interfaces provided for element!";
+
+  /**
+   * Maps the class names of service provider interfaces to the
+   * class names of the concrete classes which implement them.
+   * <p>
+   * For example,
+   *   {@code "com.google.apphosting.LocalRpcService" ->
+   *   "com.google.apphosting.datastore.LocalDatastoreService"}
+   */
+  private Multimap<String, String> providers = HashMultimap.create();
+
+  @Override
+  public ImmutableSet<String> getSupportedAnnotationTypes() {
+    return ImmutableSet.of(AutoService.class.getName());
+  }
+
+  @Override
+  public SourceVersion getSupportedSourceVersion() {
+    return SourceVersion.latestSupported();
+  }
+
+  /**
+   * <ol>
+   *  <li> For each class annotated with {@link AutoService}<ul>
+   *      <li> Verify the {@link AutoService} interface value is correct
+   *      <li> Categorize the class by its service interface
+   *      </ul>
+   *
+   *  <li> For each {@link AutoService} interface <ul>
+   *       <li> Create a file named {@code META-INF/services/<interface>}
+   *       <li> For each {@link AutoService} annotated class for this interface <ul>
+   *           <li> Create an entry in the file
+   *           </ul>
+   *       </ul>
+   * </ol>
+   */
+  @Override
+  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    try {
+      return processImpl(annotations, roundEnv);
+    } catch (Exception e) {
+      // We don't allow exceptions of any kind to propagate to the compiler
+      StringWriter writer = new StringWriter();
+      e.printStackTrace(new PrintWriter(writer));
+      fatalError(writer.toString());
+      return true;
+    }
+  }
+
+  private boolean processImpl(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    if (roundEnv.processingOver()) {
+      generateConfigFiles();
+    } else {
+      processAnnotations(annotations, roundEnv);
+    }
+
+    return true;
+  }
+
+  private void processAnnotations(Set<? extends TypeElement> annotations,
+      RoundEnvironment roundEnv) {
+
+    Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(AutoService.class);
+
+    log(annotations.toString());
+    log(elements.toString());
+
+    for (Element e : elements) {
+      // TODO(gak): check for error trees?
+      TypeElement providerImplementer = (TypeElement) e;
+      AnnotationMirror annotationMirror = getAnnotationMirror(e, AutoService.class).get();
+      Set<DeclaredType> providerInterfaces = getValueFieldOfClasses(annotationMirror);
+      if (providerInterfaces.isEmpty()) {
+        error(MISSING_SERVICES_ERROR, e, annotationMirror);
+        continue;
+      }
+      for (DeclaredType providerInterface : providerInterfaces) {
+        TypeElement providerType = MoreTypes.asTypeElement(providerInterface);
+
+        log("provider interface: " + providerType.getQualifiedName());
+        log("provider implementer: " + providerImplementer.getQualifiedName());
+
+        if (checkImplementer(providerImplementer, providerType)) {
+          providers.put(getBinaryName(providerType), getBinaryName(providerImplementer));
+        } else {
+          String message = "ServiceProviders must implement their service provider interface. "
+              + providerImplementer.getQualifiedName() + " does not implement "
+              + providerType.getQualifiedName();
+          error(message, e, annotationMirror);
+        }
+      }
+    }
+  }
+
+  private void generateConfigFiles() {
+    Filer filer = processingEnv.getFiler();
+
+    for (String providerInterface : providers.keySet()) {
+      String resourceFile = "META-INF/services/" + providerInterface;
+      log("Working on resource file: " + resourceFile);
+      try {
+        SortedSet<String> allServices = Sets.newTreeSet();
+        try {
+          // would like to be able to print the full path
+          // before we attempt to get the resource in case the behavior
+          // of filer.getResource does change to match the spec, but there's
+          // no good way to resolve CLASS_OUTPUT without first getting a resource.
+          FileObject existingFile = filer.getResource(StandardLocation.CLASS_OUTPUT, "",
+              resourceFile);
+          log("Looking for existing resource file at " + existingFile.toUri());
+          Set<String> oldServices = ServicesFiles.readServiceFile(existingFile.openInputStream());
+          log("Existing service entries: " + oldServices);
+          allServices.addAll(oldServices);
+        } catch (IOException e) {
+          // According to the javadoc, Filer.getResource throws an exception
+          // if the file doesn't already exist.  In practice this doesn't
+          // appear to be the case.  Filer.getResource will happily return a
+          // FileObject that refers to a non-existent file but will throw
+          // IOException if you try to open an input stream for it.
+          log("Resource file did not already exist.");
+        }
+
+        Set<String> newServices = new HashSet<String>(providers.get(providerInterface));
+        if (allServices.containsAll(newServices)) {
+          log("No new service entries being added.");
+          return;
+        }
+
+        allServices.addAll(newServices);
+        log("New service file contents: " + allServices);
+        FileObject fileObject = filer.createResource(StandardLocation.CLASS_OUTPUT, "",
+            resourceFile);
+        OutputStream out = fileObject.openOutputStream();
+        ServicesFiles.writeServiceFile(allServices, out);
+        out.close();
+        log("Wrote to: " + fileObject.toUri());
+      } catch (IOException e) {
+        fatalError("Unable to create " + resourceFile + ", " + e);
+        return;
+      }
+    }
+  }
+
+  /**
+   * Verifies {@link ServiceProvider} constraints on the concrete provider class.
+   * Note that these constraints are enforced at runtime via the ServiceLoader,
+   * we're just checking them at compile time to be extra nice to our users.
+   */
+  private boolean checkImplementer(TypeElement providerImplementer, TypeElement providerType) {
+
+    String verify = processingEnv.getOptions().get("verify");
+    if (verify == null || !Boolean.valueOf(verify)) {
+      return true;
+    }
+
+    // TODO: We're currently only enforcing the subtype relationship
+    // constraint. It would be nice to enforce them all.
+
+    Types types = processingEnv.getTypeUtils();
+
+    return types.isSubtype(providerImplementer.asType(), providerType.asType());
+  }
+
+  /**
+   * Returns the binary name of a reference type. For example,
+   * {@code com.google.Foo$Bar}, instead of {@code com.google.Foo.Bar}.
+   *
+   */
+  private String getBinaryName(TypeElement element) {
+    return getBinaryNameImpl(element, element.getSimpleName().toString());
+  }
+
+  private String getBinaryNameImpl(TypeElement element, String className) {
+    Element enclosingElement = element.getEnclosingElement();
+
+    if (enclosingElement instanceof PackageElement) {
+      PackageElement pkg = (PackageElement) enclosingElement;
+      if (pkg.isUnnamed()) {
+        return className;
+      }
+      return pkg.getQualifiedName() + "." + className;
+    }
+
+    TypeElement typeElement = (TypeElement) enclosingElement;
+    return getBinaryNameImpl(typeElement, typeElement.getSimpleName() + "$" + className);
+  }
+
+  /**
+   * Returns the contents of a {@code Class[]}-typed "value" field in a given {@code annotationMirror}.
+   */
+  private ImmutableSet<DeclaredType> getValueFieldOfClasses(AnnotationMirror annotationMirror) {
+    return getAnnotationValue(annotationMirror, "value")
+        .accept(
+            new SimpleAnnotationValueVisitor8<ImmutableSet<DeclaredType>, Void>() {
+              @Override
+              public ImmutableSet<DeclaredType> visitType(TypeMirror typeMirror, Void v) {
+                // TODO(ronshapiro): class literals may not always be declared types, i.e. int.class,
+                // int[].class
+                return ImmutableSet.of(MoreTypes.asDeclared(typeMirror));
+              }
+
+              @Override
+              public ImmutableSet<DeclaredType> visitArray(
+                  List<? extends AnnotationValue> values, Void v) {
+                return values
+                    .stream()
+                    .flatMap(value -> value.accept(this, null).stream())
+                    .collect(toImmutableSet());
+              }
+            },
+            null);
+  }
+
+  private void log(String msg) {
+    if (processingEnv.getOptions().containsKey("debug")) {
+      processingEnv.getMessager().printMessage(Kind.NOTE, msg);
+    }
+  }
+
+  private void error(String msg, Element element, AnnotationMirror annotation) {
+    processingEnv.getMessager().printMessage(Kind.ERROR, msg, element, annotation);
+  }
+
+  private void fatalError(String msg) {
+    processingEnv.getMessager().printMessage(Kind.ERROR, "FATAL ERROR: " + msg);
+  }
+}
diff --git a/service/processor/src/main/java/com/google/auto/service/processor/ServicesFiles.java b/service/processor/src/main/java/com/google/auto/service/processor/ServicesFiles.java
new file mode 100644
index 0000000..c61b3ba
--- /dev/null
+++ b/service/processor/src/main/java/com/google/auto/service/processor/ServicesFiles.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.service.processor;
+
+import static com.google.common.base.Charsets.UTF_8;
+
+import com.google.common.io.Closer;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A helper class for reading and writing Services files.
+ */
+final class ServicesFiles {
+  public static final String SERVICES_PATH = "META-INF/services";
+
+  private ServicesFiles() { }
+
+  /**
+   * Returns an absolute path to a service file given the class
+   * name of the service.
+   *
+   * @param serviceName not {@code null}
+   * @return SERVICES_PATH + serviceName
+   */
+  static String getPath(String serviceName) {
+    return SERVICES_PATH + "/" + serviceName;
+  }
+
+  /**
+   * Reads the set of service classes from a service file.
+   *
+   * @param input not {@code null}. Closed after use.
+   * @return a not {@code null Set} of service class names.
+   * @throws IOException
+   */
+  static Set<String> readServiceFile(InputStream input) throws IOException {
+    HashSet<String> serviceClasses = new HashSet<String>();
+    Closer closer = Closer.create();
+    try {
+      // TODO(gak): use CharStreams
+      BufferedReader r = closer.register(new BufferedReader(new InputStreamReader(input, UTF_8)));
+      String line;
+      while ((line = r.readLine()) != null) {
+        int commentStart = line.indexOf('#');
+        if (commentStart >= 0) {
+          line = line.substring(0, commentStart);
+        }
+        line = line.trim();
+        if (!line.isEmpty()) {
+          serviceClasses.add(line);
+        }
+      }
+      return serviceClasses;
+    } catch (Throwable t) {
+      throw closer.rethrow(t);
+    } finally {
+      closer.close();
+    }
+  }
+
+  /**
+   * Writes the set of service class names to a service file.
+   *
+   * @param output not {@code null}. Not closed after use.
+   * @param services a not {@code null Collection} of service class names.
+   * @throws IOException
+   */
+  static void writeServiceFile(Collection<String> services, OutputStream output)
+      throws IOException {
+    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, UTF_8));
+    for (String service : services) {
+      writer.write(service);
+      writer.newLine();
+    }
+    writer.flush();
+  }
+}
\ No newline at end of file
diff --git a/service/processor/src/main/java/com/google/auto/service/processor/package-info.java b/service/processor/src/main/java/com/google/auto/service/processor/package-info.java
new file mode 100644
index 0000000..a9f0adb
--- /dev/null
+++ b/service/processor/src/main/java/com/google/auto/service/processor/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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.
+ */
+/**
+ * This package contains the annotation processor that implements the
+ * {@link com.google.auto.service.AutoService} API.
+ */
+package com.google.auto.service.processor;
\ No newline at end of file
diff --git a/service/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors b/service/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors
new file mode 100644
index 0000000..dd17374
--- /dev/null
+++ b/service/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors
@@ -0,0 +1 @@
+com.google.auto.service.processor.AutoServiceProcessor,AGGREGATING
diff --git a/service/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/service/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
new file mode 100644
index 0000000..a4406e1
--- /dev/null
+++ b/service/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -0,0 +1 @@
+com.google.auto.service.processor.AutoServiceProcessor
diff --git a/service/processor/src/test/java/com/google/auto/service/processor/AutoServiceProcessorTest.java b/service/processor/src/test/java/com/google/auto/service/processor/AutoServiceProcessorTest.java
new file mode 100644
index 0000000..d3e00a7
--- /dev/null
+++ b/service/processor/src/test/java/com/google/auto/service/processor/AutoServiceProcessorTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.service.processor;
+
+import static com.google.auto.service.processor.AutoServiceProcessor.MISSING_SERVICES_ERROR;
+import static com.google.testing.compile.JavaSourcesSubject.assertThat;
+
+import com.google.testing.compile.JavaFileObjects;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests the {@link AutoServiceProcessor}.
+ */
+@RunWith(JUnit4.class)
+public class AutoServiceProcessorTest {
+  @Test
+  public void autoService() {
+      assertThat(
+            JavaFileObjects.forResource("test/SomeService.java"),
+            JavaFileObjects.forResource("test/SomeServiceProvider1.java"),
+            JavaFileObjects.forResource("test/SomeServiceProvider2.java"),
+            JavaFileObjects.forResource("test/Enclosing.java"),
+            JavaFileObjects.forResource("test/AnotherService.java"),
+            JavaFileObjects.forResource("test/AnotherServiceProvider.java"))
+        .processedWith(new AutoServiceProcessor())
+        .compilesWithoutError()
+        .and().generatesFiles(
+            JavaFileObjects.forResource("META-INF/services/test.SomeService"),
+            JavaFileObjects.forResource("META-INF/services/test.AnotherService"));
+  }
+
+  @Test
+  public void multiService() {
+    assertThat(
+            JavaFileObjects.forResource("test/SomeService.java"),
+            JavaFileObjects.forResource("test/AnotherService.java"),
+            JavaFileObjects.forResource("test/MultiServiceProvider.java"))
+        .processedWith(new AutoServiceProcessor())
+        .compilesWithoutError()
+        .and().generatesFiles(
+            JavaFileObjects.forResource("META-INF/services/test.SomeServiceMulti"),
+            JavaFileObjects.forResource("META-INF/services/test.AnotherServiceMulti"));
+  }
+
+  @Test
+  public void badMultiService() {
+    assertThat(JavaFileObjects.forResource("test/NoServices.java"))
+        .processedWith(new AutoServiceProcessor())
+        .failsToCompile()
+        .withErrorContaining(MISSING_SERVICES_ERROR);
+  }
+}
diff --git a/service/processor/src/test/resources/META-INF/services/test.AnotherService b/service/processor/src/test/resources/META-INF/services/test.AnotherService
new file mode 100644
index 0000000..7453e4d
--- /dev/null
+++ b/service/processor/src/test/resources/META-INF/services/test.AnotherService
@@ -0,0 +1 @@
+test.AnotherServiceProvider
diff --git a/service/processor/src/test/resources/META-INF/services/test.AnotherServiceMulti b/service/processor/src/test/resources/META-INF/services/test.AnotherServiceMulti
new file mode 100644
index 0000000..f6ef36a
--- /dev/null
+++ b/service/processor/src/test/resources/META-INF/services/test.AnotherServiceMulti
@@ -0,0 +1 @@
+test.MultiServiceProvider
diff --git a/service/processor/src/test/resources/META-INF/services/test.SomeService b/service/processor/src/test/resources/META-INF/services/test.SomeService
new file mode 100644
index 0000000..1b71d9d
--- /dev/null
+++ b/service/processor/src/test/resources/META-INF/services/test.SomeService
@@ -0,0 +1,3 @@
+test.Enclosing$NestedSomeServiceProvider
+test.SomeServiceProvider1
+test.SomeServiceProvider2
diff --git a/service/processor/src/test/resources/META-INF/services/test.SomeServiceMulti b/service/processor/src/test/resources/META-INF/services/test.SomeServiceMulti
new file mode 100644
index 0000000..f6ef36a
--- /dev/null
+++ b/service/processor/src/test/resources/META-INF/services/test.SomeServiceMulti
@@ -0,0 +1 @@
+test.MultiServiceProvider
diff --git a/service/processor/src/test/resources/test/AnotherService.java b/service/processor/src/test/resources/test/AnotherService.java
new file mode 100644
index 0000000..c096c22
--- /dev/null
+++ b/service/processor/src/test/resources/test/AnotherService.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 test;
+
+interface AnotherService { }
\ No newline at end of file
diff --git a/service/processor/src/test/resources/test/AnotherServiceProvider.java b/service/processor/src/test/resources/test/AnotherServiceProvider.java
new file mode 100644
index 0000000..c5e5c11
--- /dev/null
+++ b/service/processor/src/test/resources/test/AnotherServiceProvider.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 test;
+
+import com.google.auto.service.AutoService;
+
+@AutoService(AnotherService.class)
+public class AnotherServiceProvider implements AnotherService { }
\ No newline at end of file
diff --git a/service/processor/src/test/resources/test/Enclosing.java b/service/processor/src/test/resources/test/Enclosing.java
new file mode 100644
index 0000000..26dd585
--- /dev/null
+++ b/service/processor/src/test/resources/test/Enclosing.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 test;
+
+import com.google.auto.service.AutoService;
+
+public class Enclosing {
+  @AutoService(SomeService.class)
+  public static class NestedSomeServiceProvider implements SomeService { }
+}
\ No newline at end of file
diff --git a/service/processor/src/test/resources/test/MultiServiceProvider.java b/service/processor/src/test/resources/test/MultiServiceProvider.java
new file mode 100644
index 0000000..478c7e7
--- /dev/null
+++ b/service/processor/src/test/resources/test/MultiServiceProvider.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 test;
+
+import com.google.auto.service.AutoService;
+
+@AutoService({SomeService.class, AnotherService.class})
+public class MultiServiceProvider implements SomeService, AnotherService {}
diff --git a/service/processor/src/test/resources/test/NoServices.java b/service/processor/src/test/resources/test/NoServices.java
new file mode 100644
index 0000000..e9523ca
--- /dev/null
+++ b/service/processor/src/test/resources/test/NoServices.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 test;
+
+import com.google.auto.service.AutoService;
+
+@AutoService({})
+public class NoServices {}
diff --git a/service/processor/src/test/resources/test/SomeService.java b/service/processor/src/test/resources/test/SomeService.java
new file mode 100644
index 0000000..d29c409
--- /dev/null
+++ b/service/processor/src/test/resources/test/SomeService.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 test;
+
+interface SomeService { }
\ No newline at end of file
diff --git a/service/processor/src/test/resources/test/SomeServiceProvider1.java b/service/processor/src/test/resources/test/SomeServiceProvider1.java
new file mode 100644
index 0000000..008136b
--- /dev/null
+++ b/service/processor/src/test/resources/test/SomeServiceProvider1.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 test;
+
+import com.google.auto.service.AutoService;
+
+@AutoService(SomeService.class)
+public class SomeServiceProvider1 implements SomeService { }
\ No newline at end of file
diff --git a/service/processor/src/test/resources/test/SomeServiceProvider2.java b/service/processor/src/test/resources/test/SomeServiceProvider2.java
new file mode 100644
index 0000000..5444996
--- /dev/null
+++ b/service/processor/src/test/resources/test/SomeServiceProvider2.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2008 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 test;
+
+import com.google.auto.service.AutoService;
+
+@AutoService(SomeService.class)
+public class SomeServiceProvider2 implements SomeService { }
\ No newline at end of file
diff --git a/util/generate-latest-docs.sh b/util/generate-latest-docs.sh
new file mode 100755
index 0000000..8617ba4
--- /dev/null
+++ b/util/generate-latest-docs.sh
@@ -0,0 +1,25 @@
+# see http://benlimmer.com/2013/12/26/automatically-publish-javadoc-to-gh-pages-with-travis-ci/ for details
+
+if [ "$TRAVIS_REPO_SLUG" == "google/auto" ] && \
+   [ "$TRAVIS_JDK_VERSION" == "oraclejdk7" ] && \
+   [ "$TRAVIS_PULL_REQUEST" == "false" ] && \
+   [ "$TRAVIS_BRANCH" == "master" ]; then
+  echo -e "Publishing javadoc...\n"
+  
+  mvn -f build-pom.xml javadoc:aggregate
+  TARGET="$(pwd)/target"
+
+  cd $HOME
+  git clone --quiet --branch=gh-pages https://${GH_TOKEN}@github.com/google/auto gh-pages > /dev/null
+  
+  cd gh-pages
+  git config --global user.email "travis@travis-ci.org"
+  git config --global user.name "travis-ci"
+  git rm -rf api/latest 
+  mv ${TARGET}/site/apidocs api/latest
+  git add -A -f api/latest
+  git commit -m "Latest javadoc on successful travis build $TRAVIS_BUILD_NUMBER auto-pushed to gh-pages"
+  git push -fq origin gh-pages > /dev/null
+
+  echo -e "Published Javadoc to gh-pages.\n"
+fi
diff --git a/util/mvn-deploy.sh b/util/mvn-deploy.sh
new file mode 100755
index 0000000..e7160eb
--- /dev/null
+++ b/util/mvn-deploy.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+if [ $# -lt 1 ]; then
+  echo "usage $0 <ssl-key> [<param> ...]"
+  exit 1;
+fi
+key=${1}
+shift
+params=${@}
+
+#validate key
+keystatus=$(gpg --list-keys | grep ${key} | awk '{print $1}')
+if [ "${keystatus}" != "pub" ]; then
+  echo "Could not find public key with label ${key}"
+  echo -n "Available keys from: "
+  gpg --list-keys | grep --invert-match '^sub'
+
+  exit 1
+fi
+
+mvn ${params} clean site:jar -P sonatype-oss-release -Dgpg.keyname=${key} deploy
diff --git a/util/publish-snapshot-on-commit.sh b/util/publish-snapshot-on-commit.sh
new file mode 100755
index 0000000..0b74c6b
--- /dev/null
+++ b/util/publish-snapshot-on-commit.sh
@@ -0,0 +1,12 @@
+# see https://coderwall.com/p/9b_lfq
+
+if [ "$TRAVIS_REPO_SLUG" == "google/auto" ] && \
+   [ "$TRAVIS_JDK_VERSION" == "oraclejdk7" ] && \
+   [ "$TRAVIS_PULL_REQUEST" == "false" ] && \
+   [ "$TRAVIS_BRANCH" == "master" ]; then
+  echo -e "Publishing maven snapshot...\n"
+
+  mvn -f build-pom.xml clean source:jar deploy --settings="util/settings.xml" -DskipTests=true -Dmaven.javadoc.skip=true
+
+  echo -e "Published maven snapshot"
+fi
diff --git a/util/settings.xml b/util/settings.xml
new file mode 100644
index 0000000..91f444b
--- /dev/null
+++ b/util/settings.xml
@@ -0,0 +1,9 @@
+<settings>
+  <servers>
+    <server>
+      <id>sonatype-nexus-snapshots</id>
+      <username>${env.CI_DEPLOY_USERNAME}</username>
+      <password>${env.CI_DEPLOY_PASSWORD}</password>
+    </server>
+  </servers>
+</settings>
diff --git a/value/CHANGES.md b/value/CHANGES.md
new file mode 100644
index 0000000..32b6107
--- /dev/null
+++ b/value/CHANGES.md
@@ -0,0 +1,255 @@
+# AutoValue Changes
+
+**This document is obsolete.** For details of changes in releases since 1.5,
+see the [releases page](https://github.com/google/auto/releases) for the Auto
+project.
+
+## 1.4 → 1.5
+
+### Functional changes
+
+* A workaround for older Eclipse versions has been removed. If you need to use
+  an Eclipse version older than 4.5, you will need to stay on AutoValue 1.4.
+
+* The [retention](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Retention.html)
+  of the `@AutoValue` annotation has changed from `SOURCE` to `CLASS`. This
+  means that it is possible for code-analysis tools to tell whether a class is
+  an `@AutoValue`. AutoValue itself uses this to enforce the check that one
+  `@AutoValue` class cannot extend another, even if the classes are compiled
+  separately.
+
+* It is now an error if `@Memoized` is applied to a method not inside an
+  `@AutoValue` class.
+
+* Type annotations are now handled more consistently. If `@Nullable` is a type
+  annotation, a property of type `@Nullable Integer` will have that type used
+  everywhere in the generated code. Associated bugs with nested type
+  annotations, like `Outer.@Inner`, have been fixed.
+
+### Bugs fixed since 1.4.1
+
+* `@Memoized` methods can now throw checked exceptions. Previously this failed
+  because the exceptions were not copied into the `throws` clause of the
+  generated override, so the call to `super.foo()` did not compile.
+
+* The generated `hashCode()` method uses `h = (int) (h ^ longProperty)` rather
+  than `h ^= longProperty` to avoid warnings about loss of precision.
+
+* Annotations are not copied from an abstract method to its implementation if
+  they are not visible from the latter. This can happen if the `@AutoValue`
+  inherits the abstract method from a class or interface in a different package.
+
+## 1.3 → 1.4
+
+*This is the last AutoValue version that compiles and runs on Java 6.* Future
+versions will require at least Java 8 to run. We will continue to generate code
+that is compatible with Java 7, so AutoValue can be used with `javac -source 7
+-target 7 -bootclasspath <rt.jar-from-jdk7>`, but using the `javac` from jdk8 or
+later.
+
+### Functional changes
+
+* Builder setters now reject a null parameter immediately unless the
+  corresponding property is `@Nullable`. Previously this check happened at
+  `build()` time, and in some cases didn't happen at all. This is the change
+  that is most likely to affect existing code.
+
+* Added `@Memoized`. A `@Memoized` method will be overridden in the generated
+  `AutoValue_Foo` class to save the value returned the first time it was called
+  and reuse that every other time.
+
+* Generalized support for property builders. Now, in addition to being able to
+  say `immutableListBuilder()` for a property of type `ImmutableList<T>`, you
+  can say `fooBuilder()` for a property of an arbitrary type that has a builder
+  following certain conventions. In particular, you can do this if the type of
+  `foo()` is itself an `@AutoValue` class with a builder. The default value of
+  `foo()`, if `fooBuilder()` is never called, is `fooBuilder().build()`.
+
+* If a property `foo()` or `getFoo()` has a builder method `fooBuilder()` then
+  the property can not now be `@Nullable`. An `ImmutableList`, for example,
+  starts off empty, not null, so `@Nullable` was misleading.
+
+* When an `@AutoValue` class `Foo` has a builder, the generated
+  `AutoValue_Foo.Builder` has a constructor `AutoValue_Foo.Builder(Foo)`. That
+  constructor was never documented and is now private. If you want to make a
+  `Foo.Builder` from a `Foo`, `Foo` should have an abstract method `Builder
+  toBuilder()`.
+
+  This change was necessary so that generalized property-builder support could
+  know whether or not the built class needs to be convertible back into its
+  builder. That's only necessary if there is a `toBuilder()`.
+
+* The Extension API is now a committed API, meaning we no longer warn that it is
+  likely to change incompatibly. A
+  [guide](https://github.com/google/auto/blob/master/value/userguide/extensions.md)
+  gives tips on writing extensions.
+
+* Extensions can now return null rather than generated code. In that case the
+  extension does not generate a class in the AutoValue hierarchy, but it can
+  still do other things like error checking or generating side files.
+
+* Access modifiers like `protected` are copied from builder methods to their
+  implementations, instead of the implementations always being public.
+  Change by @torquestomp.
+
+* AutoAnnotation now precomputes parts of the `hashCode` that are constant
+  because they come from defaulted methods. This avoids warnings about integer
+  overflow from tools that check that.
+
+* If a property is called `oAuth()`, its setter can be called
+  `setOAuth(x)`. Previously it had to be `setoAuth(x)`, which is still allowed.
+
+## Bugs fixed
+
+* AutoAnnotation now correctly handles types like `Class<? extends
+  Annotation>[]`. Previously it would try to create a generic array, which Java
+  doesn't allow. Change by @lukesandberg.
+
+* We guard against spurious exceptions due to a JDK bug in reading resources
+  from jars. (#365)
+
+* We don't propagate an exception if a corrupt jar is found in extension
+  loading.
+
+* AutoValue is ready for Java 9, where public classes are not necessarily
+  accessible, and javax.annotation.Generated is not necessarily present.
+
+* AutoValue now works correctly even if the version of AutoValue in the
+  `-classpath` is older than the one in the `-processorpath`.
+
+* Builders now behave correctly when there is a non-optional property called
+  `missing`. Previously a variable-hiding problem meant that we didn't detect
+  when it wasn't set.
+
+* If `@AutoValue class Foo` has a builder, we always generated two constructors,
+  `Builder()` and `Builder(Foo)`, but we only used the second one if `Foo` had a
+  `toBuilder()` method. Now we only generate that constructor if it is
+  needed. That avoids warnings about unused code.
+
+* `@AutoAnnotation` now works when the annotation and the factory method are in
+  the default (unnamed) package.
+
+## 1.2 → 1.3
+
+### Functional changes
+
+* Support for TYPE_USE `@Nullable`.
+  This is https://github.com/google/auto/pull/293 by @brychcy.
+
+* Restructured the code in AutoValueProcessor for handling extensions, to get
+  rid of warnings about abstract methods when those methods are going to be
+  implemented by an extension, and to fix a bug where extensions would not work
+  right if there was a toBuilder() method. Some of the code in this change is
+  based on https://github.com/google/auto/pull/299 by @rharter.
+
+* Added support for "optional getters", where a getter in an AutoValue Builder
+  can have type `Optional<T>` and it will return `Optional.of(x)` where `x` is
+  the value that has been set in the Builder, or `Optional.empty()` if no value
+  has been set.
+
+* In AutoValue builders, added support for setting a property of type
+  `Optional<T>` via a setter with an argument of type `T`.
+
+* Added logic to AutoValue to detect the confusing case where you think you
+  are using JavaBeans conventions (like getFoo()) but you aren't because at
+  least one method isn't.
+
+* Added a README.md describing EscapeVelocity.
+
+### Bugs fixed
+
+* Allow an `@AutoValue.Builder` to extend a parent builder using the `<B extends
+  Builder<B>>` idiom.
+
+* AutoAnnotation now factors in package names when detecting
+  overloads. Previously it treated all annotations with the same SimpleName as
+  being overload attempts.
+
+* Removed an inaccurate javadoc reference, which referred to an
+  artifact from an earlier draft version of the Extensions API. This is
+  https://github.com/google/auto/pull/322 by @lucastsa.
+
+## 1.1 → 1.2
+
+### Functional changes
+
+  * A **provisional** extension API has been introduced. This **will change**
+    in a later release. If you want to use it regardless, see the
+    [AutoValueExtension] class.
+
+  * Properties of primitive array type (e.g. `byte[]`) are no longer cloned
+    when read. If your `@AutoValue` class includes an array property, by default
+    it will get a compiler warning, which can be suppressed with
+    `@SuppressWarnings("mutable")`.
+
+  * An `@AutoValue.Builder` type can now define both the setter and builder
+    methods like so:
+
+    ```
+      ...
+      abstract void setStrings(ImmutableList<String>);
+      abstract ImmutableList.Builder<String> stringsBuilder();
+      ...
+    ```
+    At runtime, if `stringsBuilder()...` is called then it is an error to call
+    `setStrings(...)` afterwards.
+
+  * The classes in the autovalue jar are now shaded with a `$` so they never
+    appear in IDE autocompletion.
+
+  * AutoValue now uses its own implementation of a subset of Apache Velocity,
+    so there will no longer be problems with interference between the Velocity
+    that was bundled with AutoValue and other versions that might be present.
+
+### Bugs fixed
+
+  * Explicit check for nested `@AutoValue` classes being private, or not being
+    static. Otherwise the compiler errors could be hard to understand,
+    especially in IDEs.
+
+  * An Eclipse bug that could occasionally lead to exceptions in the IDE has
+    been fixed (GitHub issue #200).
+
+  * Fixed a bug where AutoValue generated incorrect code if a method with a
+    type parameter was inherited by a class that supplies a concrete type for
+    that parameter. For example `StringIterator implements Iterator<String>`,
+    where the type of `next()` is String, not `T`.
+
+  * In `AutoValueProcessor`, fixed an exception that happened if the same
+    abstract method was inherited from more than one parent (Github Issue #267).
+
+  * AutoValue now works correctly in an environment where
+    `@javax.annotation.Generated` does not exist.
+
+  * Properties marked `@Nullable` now get `@Nullable` on the corresponding
+    constructor parameters in the generated class.
+
+## 1.0 → 1.1
+
+### Functional changes
+
+  * Adds builders to AutoValue. Builders are nested classes annotated with
+    `@AutoValue.Builder`.
+
+  * Annotates constructor parameters with `@Nullable` if the corresponding
+    property methods are `@Nullable`.
+
+  * Changes Maven shading so org.apache.commons is shaded.
+
+  * Copies a `@GwtCompatible` annotation from the `@AutoValue` class to its
+    implementation subclass.
+
+### Bugs fixed
+
+  * Works around a bug in the Eclipse compiler that meant that annotations
+    would be incorrectly copied from `@AutoValue` methods to their
+    implementations.
+
+## 1.0 (Initial Release)
+
+  * Allows automatic generation of value type implementations
+
+    See [the AutoValue User's Guide](userguide/index.md)
+
+
+[AutoValueExtension]: src/main/java/com/google/auto/value/extension/AutoValueExtension.java
diff --git a/value/README.md b/value/README.md
new file mode 100644
index 0000000..f6c00c3
--- /dev/null
+++ b/value/README.md
@@ -0,0 +1,25 @@
+# AutoValue
+
+*Generated immutable value classes for Java 7+* <br />
+***Kevin Bourrillion, Éamonn McManus*** <br />
+**Google, Inc.**
+
+**Value classes** are extremely common in Java projects. These are classes for
+which you want to treat any two instances with suitably equal field values as
+interchangeable. That's right: we're talking about those classes where you wind
+up implementing `equals`, `hashCode` and `toString` in a bloated, repetitive,
+formulaic yet error-prone fashion.
+
+Writing these methods the first time is not too bad, with the aid of a few
+helper methods and IDE templates. But once written they continue to burden
+reviewers, editors and future readers. Their wide expanses of boilerplate
+sharply decrease the signal-to-noise ratio of your code... and they love to
+harbor hard-to-spot bugs.
+
+AutoValue provides an easier way to create immutable value classes, with a lot
+less code and less room for error, while **not restricting your freedom** to
+code almost any aspect of your class exactly the way you want it.
+
+For more information, consult the
+[detailed
+documentation](userguide/index.md)
diff --git a/value/annotations/pom.xml b/value/annotations/pom.xml
new file mode 100644
index 0000000..d0d4a6b
--- /dev/null
+++ b/value/annotations/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2012 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.auto.value</groupId>
+    <artifactId>auto-value-parent</artifactId>
+    <version>HEAD-SNAPSHOT</version>
+  </parent>
+
+  <groupId>com.google.auto.value</groupId>
+  <artifactId>auto-value-annotations</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>AutoValue Annotations</name>
+  <description>
+    Immutable value-type code generation for Java 1.6+.
+  </description>
+  <url>https://github.com/google/auto/tree/master/value</url>
+
+  <properties>
+    <java.version>1.7</java.version>
+  </properties>
+
+  <scm>
+    <url>http://github.com/google/auto</url>
+    <connection>scm:git:git://github.com/google/auto.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+  <build>
+    <sourceDirectory>../src/main/java</sourceDirectory>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <includes>
+            <include>com/google/auto/value/*</include>
+            <include>com/google/auto/value/extension/memoized/*</include>
+            <include>com/google/auto/value/extension/serializable/*</include>
+          </includes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-invoker-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>disable-java8-doclint</id>
+      <activation>
+        <jdk>[1.8,)</jdk>
+      </activation>
+      <properties>
+        <additionalparam>-Xdoclint:none</additionalparam>
+      </properties>
+    </profile>
+  </profiles>
+</project>
diff --git a/value/pom.xml b/value/pom.xml
new file mode 100644
index 0000000..9f8be5a
--- /dev/null
+++ b/value/pom.xml
@@ -0,0 +1,192 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2012 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.sonatype.oss</groupId>
+    <artifactId>oss-parent</artifactId>
+    <version>7</version>
+  </parent>
+
+  <groupId>com.google.auto.value</groupId>
+  <artifactId>auto-value-parent</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>AutoValue Parent</name>
+  <description>
+    Immutable value-type code generation for Java 7+.
+  </description>
+  <packaging>pom</packaging>
+  <url>https://github.com/google/auto/tree/master/value</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <java.version>1.8</java.version>
+    <guava.version>28.1-jre</guava.version>
+    <truth.version>1.0.1</truth.version>
+  </properties>
+
+  <scm>
+    <url>http://github.com/google/auto</url>
+    <connection>scm:git:git://github.com/google/auto.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+
+  <issueManagement>
+    <system>GitHub Issues</system>
+    <url>http://github.com/google/auto/issues</url>
+  </issueManagement>
+
+  <licenses>
+    <license>
+      <name>Apache 2.0</name>
+      <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+    </license>
+  </licenses>
+
+  <organization>
+    <name>Google LLC</name>
+    <url>http://www.google.com</url>
+  </organization>
+
+  <modules>
+    <module>annotations</module>
+    <module>processor</module>
+    <module>src/it/functional</module>
+    <module>src/it/gwtserializer</module>
+  </modules>
+
+  <dependencyManagement>
+    <dependencies>
+      <!-- main dependencies -->
+
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava-gwt</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.squareup</groupId>
+        <artifactId>javapoet</artifactId>
+        <version>1.11.1</version>
+      </dependency>
+
+      <!-- test dependencies -->
+
+      <dependency>
+        <groupId>com.google.code.findbugs</groupId>
+        <artifactId>jsr305</artifactId>
+        <version>3.0.2</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.guava</groupId>
+        <artifactId>guava-testlib</artifactId>
+        <version>${guava.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.testing.compile</groupId>
+        <artifactId>compile-testing</artifactId>
+        <version>0.18</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.truth</groupId>
+        <artifactId>truth</artifactId>
+        <version>${truth.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>com.google.truth.extensions</groupId>
+        <artifactId>truth-java8-extension</artifactId>
+        <version>${truth.version}</version>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.13</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.velocity</groupId>
+        <artifactId>velocity</artifactId>
+        <version>1.7</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>3.7.0</version>
+          <configuration>
+            <source>${java.version}</source>
+            <target>${java.version}</target>
+            <compilerArgument>-Xlint:all</compilerArgument>
+            <showWarnings>true</showWarnings>
+            <showDeprecation>true</showDeprecation>
+          </configuration>
+          <dependencies>
+            <dependency>
+              <groupId>org.codehaus.plexus</groupId>
+              <artifactId>plexus-java</artifactId>
+              <version>0.9.4</version>
+            </dependency>
+          </dependencies>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jar-plugin</artifactId>
+          <version>3.0.2</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-invoker-plugin</artifactId>
+          <version>3.0.1</version>
+          <configuration>
+            <addTestClassPath>true</addTestClassPath>
+            <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
+            <pomIncludes>
+              <pomInclude>*/pom.xml</pomInclude>
+            </pomIncludes>
+            <streamLogs>true</streamLogs>
+          </configuration>
+          <executions>
+            <execution>
+              <id>integration-test</id>
+              <goals>
+                <goal>install</goal>
+                <goal>run</goal>
+              </goals>
+            </execution>
+          </executions>
+        </plugin>
+        <plugin>
+          <groupId>org.immutables.tools</groupId>
+          <artifactId>maven-shade-plugin</artifactId>
+          <version>4</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
diff --git a/value/processor/pom.xml b/value/processor/pom.xml
new file mode 100644
index 0000000..0aa9ec8
--- /dev/null
+++ b/value/processor/pom.xml
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2012 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.auto.value</groupId>
+    <artifactId>auto-value-parent</artifactId>
+    <version>HEAD-SNAPSHOT</version>
+  </parent>
+
+  <groupId>com.google.auto.value</groupId>
+  <artifactId>auto-value</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>AutoValue Processor</name>
+  <description>
+    Immutable value-type code generation for Java 1.6+.
+  </description>
+  <url>https://github.com/google/auto/tree/master/value</url>
+
+  <scm>
+    <url>http://github.com/google/auto</url>
+    <connection>scm:git:git://github.com/google/auto.git</connection>
+    <developerConnection>scm:git:ssh://git@github.com/google/auto.git</developerConnection>
+    <tag>HEAD</tag>
+  </scm>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.auto</groupId>
+      <artifactId>auto-common</artifactId>
+      <version>0.10</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto.service</groupId>
+      <artifactId>auto-service</artifactId>
+      <version>1.0-rc6</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.errorprone</groupId>
+      <artifactId>error_prone_annotations</artifactId>
+      <version>2.3.3</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.escapevelocity</groupId>
+      <artifactId>escapevelocity</artifactId>
+      <version>0.9.1</version>
+    </dependency>
+    <dependency>
+      <groupId>net.ltgt.gradle.incap</groupId>
+      <artifactId>incap</artifactId>
+      <version>0.2</version>
+    </dependency>
+    <dependency>
+      <groupId>net.ltgt.gradle.incap</groupId>
+      <artifactId>incap-processor</artifactId>
+      <version>0.2</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.squareup</groupId>
+      <artifactId>javapoet</artifactId>
+    </dependency>
+    <!-- test dependencies -->
+    <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value-annotations</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.velocity</groupId>
+      <artifactId>velocity</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava-testlib</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth.extensions</groupId>
+      <artifactId>truth-java8-extension</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.testing.compile</groupId>
+      <artifactId>compile-testing</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+       <groupId>org.mockito</groupId>
+       <artifactId>mockito-core</artifactId>
+       <version>3.1.0</version>
+       <scope>test</scope>
+     </dependency>
+  </dependencies>
+
+  <build>
+    <sourceDirectory>../src/main/java</sourceDirectory>
+    <testSourceDirectory>../src/test/java</testSourceDirectory>
+
+    <resources>
+      <resource>
+        <directory>../src/main/java</directory>
+        <includes>
+          <include>**/*.vm</include>
+        </includes>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <includes>
+            <include>com/google/auto/value/processor/**/*.java</include>
+            <include>com/google/auto/value/extension/memoized/processor/**/*.java</include>
+            <include>com/google/auto/value/extension/serializable/processor/**/*.java</include>
+            <include>com/google/auto/value/extension/serializable/serializer/**/*.java</include>
+          </includes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-invoker-plugin</artifactId>
+      </plugin>
+      <plugin>
+        <groupId>org.immutables.tools</groupId>
+        <artifactId>maven-shade-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <minimizeJar>true</minimizeJar>
+              <artifactSet>
+                <excludes>
+                  <exclude>com.google.code.findbugs:jsr305</exclude>
+                </excludes>
+              </artifactSet>
+              <relocations>
+                <relocation>
+                  <pattern>org.objectweb</pattern>
+                  <shadedPattern>autovalue.shaded.org.objectweb$</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>com.google</pattern>
+                  <shadedPattern>autovalue.shaded.com.google$</shadedPattern>
+                  <excludes>
+                    <exclude>com.google.auto.value.**</exclude>
+                  </excludes>
+                </relocation>
+                <relocation>
+                  <pattern>com.squareup.javapoet</pattern>
+                  <shadedPattern>autovalue.shaded.com.squareup.javapoet$</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>net.ltgt.gradle.incap</pattern>
+                  <shadedPattern>autovalue.shaded.net.ltgt.gradle.incap$</shadedPattern>
+                </relocation>
+                <relocation>
+                  <pattern>org.checkerframework</pattern>
+                  <shadedPattern>autovalue.shaded.org.checkerframework$</shadedPattern>
+                </relocation>
+              </relocations>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>disable-java8-doclint</id>
+      <activation>
+        <jdk>[1.8,)</jdk>
+      </activation>
+      <properties>
+        <additionalparam>-Xdoclint:none</additionalparam>
+      </properties>
+    </profile>
+  </profiles>
+</project>
diff --git a/value/src/it/functional/invoker.properties b/value/src/it/functional/invoker.properties
new file mode 100644
index 0000000..018eaf0
--- /dev/null
+++ b/value/src/it/functional/invoker.properties
@@ -0,0 +1,4 @@
+invoker.goals = clean verify
+
+invoker.profiles.1 =
+invoker.profiles.2 = eclipse
\ No newline at end of file
diff --git a/value/src/it/functional/pom.xml b/value/src/it/functional/pom.xml
new file mode 100644
index 0000000..4157da9
--- /dev/null
+++ b/value/src/it/functional/pom.xml
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2013 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<!-- TODO(gak): see if we can manage these dependencies any better -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.auto.value</groupId>
+    <artifactId>auto-value-parent</artifactId>
+    <version>HEAD-SNAPSHOT</version>
+    <relativePath>../../../pom.xml</relativePath>
+  </parent>
+  <url>https://github.com/google/auto/tree/master/value</url>
+
+  <groupId>com.google.auto.value.it.functional</groupId>
+  <artifactId>functional</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>Auto-Value Functional Integration Test</name>
+  <properties>
+    <exclude.tests>this-matches-nothing</exclude.tests>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value-annotations</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto.service</groupId>
+      <artifactId>auto-service</artifactId>
+      <version>1.0-rc6</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.gwt</groupId>
+      <artifactId>gwt-user</artifactId>
+      <version>2.8.2</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava-testlib</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth</groupId>
+      <artifactId>truth</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.truth.extensions</groupId>
+      <artifactId>truth-java8-extension</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.testing.compile</groupId>
+      <artifactId>compile-testing</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>3.1.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.eclipse.jdt</groupId>
+      <artifactId>ecj</artifactId>
+      <version>3.20.0</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.escapevelocity</groupId>
+      <artifactId>escapevelocity</artifactId>
+      <version>0.9.1</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+       <version>3.0.2</version>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.7.0</version>
+        <dependencies>
+          <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-java</artifactId>
+            <version>0.9.4</version>
+          </dependency>
+        </dependencies>
+        <configuration>
+          <source>${java.specification.version}</source>
+          <target>${java.specification.version}</target>
+          <compilerArgs>
+            <arg>-Xlint:all</arg>
+            <arg>-encoding</arg>
+            <arg>utf8</arg>
+          </compilerArgs>
+          <showWarnings>true</showWarnings>
+          <showDeprecation>true</showDeprecation>
+          <testExcludes>
+            <exclude>${exclude.tests}</exclude>
+          </testExcludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <version>2.7</version>
+        <configuration>
+          <!-- Build/test, but don't deploy -->
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>eclipse</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-compiler-plugin</artifactId>
+            <version>3.7.0</version>
+            <dependencies>
+              <dependency>
+                <groupId>org.codehaus.plexus</groupId>
+                <artifactId>plexus-java</artifactId>
+                <version>0.9.4</version>
+              </dependency>
+            </dependencies>
+            <configuration>
+              <source>${java.specification.version}</source>
+              <target>${java.specification.version}</target>
+              <compilerArgs>
+                <arg>-Xlint:all</arg>
+                <arg>-encoding</arg>
+                <arg>utf8</arg>
+              </compilerArgs>
+              <showWarnings>true</showWarnings>
+              <showDeprecation>true</showDeprecation>
+              <testExcludes>
+                <exclude>${exclude.tests}</exclude>
+              </testExcludes>
+            </configuration>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+    <profile>
+      <id>exclude-java8-tests</id>
+      <activation>
+        <jdk>(,1.7]</jdk>
+      </activation>
+      <properties>
+        <exclude.tests>**/AutoValueJava8Test.java</exclude.tests>
+      </properties>
+    </profile>
+  </profiles>
+</project>
diff --git a/value/src/it/functional/src/main/java/PackagelessNestedValueType.java b/value/src/it/functional/src/main/java/PackagelessNestedValueType.java
new file mode 100644
index 0000000..77b1939
--- /dev/null
+++ b/value/src/it/functional/src/main/java/PackagelessNestedValueType.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+import com.google.auto.value.AutoValue;
+import java.util.Map;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+public class PackagelessNestedValueType {
+  @AutoValue
+  public abstract static class Nested {
+    abstract Map<Integer, String> numberNames();
+
+    public static Nested create(Map<Integer, String> numberNames) {
+      return new AutoValue_PackagelessNestedValueType_Nested(numberNames);
+    }
+  }
+}
diff --git a/value/src/it/functional/src/main/java/PackagelessValueType.java b/value/src/it/functional/src/main/java/PackagelessValueType.java
new file mode 100644
index 0000000..62b172e
--- /dev/null
+++ b/value/src/it/functional/src/main/java/PackagelessValueType.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+import com.google.auto.value.AutoValue;
+import java.util.Map;
+import javax.annotation.Nullable;
+
+/**
+ * Simple package-less value type for tests.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@AutoValue
+public abstract class PackagelessValueType {
+  // The getters here are formatted as an illustration of what getters typically look in real
+  // classes. In particular they have doc comments.
+
+  /** @return A string that is a nullable string. */
+  @Nullable
+  public abstract String string();
+
+  /** @return An integer that is an integer. */
+  public abstract int integer();
+
+  /** @return A non-null map where the keys are strings and the values are longs. */
+  public abstract Map<String, Long> map();
+
+  public static PackagelessValueType create(
+      @Nullable String string, int integer, Map<String, Long> map) {
+    // The subclass AutoValue_PackagelessValueType is created by the annotation processor that is
+    // triggered by the presence of the @AutoValue annotation. It has a constructor for each
+    // of the abstract getter methods here, in order. The constructor stashes the values here
+    // in private final fields, and each method is implemented to return the value of the
+    // corresponding field.
+    return new AutoValue_PackagelessValueType(string, integer, map);
+  }
+}
diff --git a/value/src/it/functional/src/main/java/com/google/auto/value/NestedValueType.java b/value/src/it/functional/src/main/java/com/google/auto/value/NestedValueType.java
new file mode 100644
index 0000000..cd8b3b7
--- /dev/null
+++ b/value/src/it/functional/src/main/java/com/google/auto/value/NestedValueType.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import java.util.Map;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+public class NestedValueType {
+  @AutoValue
+  public abstract static class Nested {
+    abstract Map<Integer, String> numberNames();
+
+    public static Nested create(Map<Integer, String> numberNames) {
+      return new AutoValue_NestedValueType_Nested(numberNames);
+    }
+  }
+}
diff --git a/value/src/it/functional/src/main/java/com/google/auto/value/SimpleValueType.java b/value/src/it/functional/src/main/java/com/google/auto/value/SimpleValueType.java
new file mode 100644
index 0000000..9d6c6c7
--- /dev/null
+++ b/value/src/it/functional/src/main/java/com/google/auto/value/SimpleValueType.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import java.util.Map;
+import javax.annotation.Nullable;
+
+/**
+ * Simple value type for tests.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@AutoValue
+public abstract class SimpleValueType {
+  // The getters here are formatted as an illustration of what getters typically look in real
+  // classes. In particular they have doc comments.
+
+  /** Returns a string that is a nullable string. */
+  @Nullable
+  public abstract String string();
+
+  /** Returns an integer that is an integer. */
+  public abstract int integer();
+
+  /** Returns a non-null map where the keys are strings and the values are longs. */
+  public abstract Map<String, Long> map();
+
+  public static SimpleValueType create(
+      @Nullable String string, int integer, Map<String, Long> map) {
+    // The subclass AutoValue_SimpleValueType is created by the annotation processor that is
+    // triggered by the presence of the @AutoValue annotation. It has a constructor for each
+    // of the abstract getter methods here, in order. The constructor stashes the values here
+    // in private final fields, and each method is implemented to return the value of the
+    // corresponding field.
+    return new AutoValue_SimpleValueType(string, integer, map);
+  }
+}
diff --git a/value/src/it/functional/src/test/java/PackagelessValueTypeTest.java b/value/src/it/functional/src/test/java/PackagelessValueTypeTest.java
new file mode 100644
index 0000000..0ed3846
--- /dev/null
+++ b/value/src/it/functional/src/test/java/PackagelessValueTypeTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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.
+ */
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.testing.NullPointerTester;
+import java.util.Map;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class PackagelessValueTypeTest {
+  @Test
+  public void testPackagelessValueType() {
+    final String happy = "happy";
+    final int testInt = 23;
+    final Map<String, Long> testMap = ImmutableMap.of("happy", 23L);
+    PackagelessValueType simple = PackagelessValueType.create(happy, testInt, testMap);
+    assertSame(happy, simple.string());
+    assertEquals(testInt, simple.integer());
+    assertSame(testMap, simple.map());
+    assertEquals(
+        "PackagelessValueType{string=happy, integer=23, map={happy=23}}", simple.toString());
+    int expectedHashCode = 1;
+    expectedHashCode = (expectedHashCode * 1000003) ^ happy.hashCode();
+    expectedHashCode = (expectedHashCode * 1000003) ^ ((Object) testInt).hashCode();
+    expectedHashCode = (expectedHashCode * 1000003) ^ testMap.hashCode();
+    assertEquals(expectedHashCode, simple.hashCode());
+  }
+
+  @Test
+  public void testNestedValueType() {
+    ImmutableMap<Integer, String> numberNames = ImmutableMap.of(1, "un", 2, "deux");
+    PackagelessNestedValueType.Nested nested =
+        PackagelessNestedValueType.Nested.create(numberNames);
+    assertEquals(numberNames, nested.numberNames());
+  }
+
+  @Test
+  public void testNull() {
+    NullPointerTester tester = new NullPointerTester();
+    tester.testAllPublicStaticMethods(PackagelessValueType.class);
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationDefaultsTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationDefaultsTest.java
new file mode 100644
index 0000000..8f00850
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationDefaultsTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import static org.junit.Assert.assertTrue;
+
+import com.google.auto.value.enums.MyEnum;
+import com.google.common.testing.EqualsTester;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class AutoAnnotationDefaultsTest {
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface EverythingWithDefaults {
+    byte aByte() default 1;
+
+    short aShort() default 2;
+
+    int anInt() default 3;
+
+    long aLong() default Long.MAX_VALUE;
+
+    float aFloat() default Float.MAX_VALUE;
+
+    double aDouble() default -Double.MAX_VALUE;
+
+    char aChar() default '#';
+
+    boolean aBoolean() default true;
+
+    String aString() default "maybe\nmaybe not\n";
+
+    String spaces() default "  ( x ) , ( y )"; // ensure the formatter doesn't eat spaces
+
+    MyEnum anEnum() default MyEnum.TWO;
+
+    byte[] bytes() default {-1, 0, 1};
+
+    short[] shorts() default {-2, 0, 2};
+
+    int[] ints() default {};
+
+    long[] longs() default {-Long.MAX_VALUE};
+
+    float[] floats() default {
+      -Float.MIN_VALUE, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN,
+    };
+
+    double[] doubles() default {
+      -Double.MIN_VALUE, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN,
+    };
+
+    char[] chars() default {'f', '\n', '\uffef'};
+
+    boolean[] booleans() default {false, true};
+
+    String[] strings() default {"", "\uffef\n"};
+
+    MyEnum[] enums() default {MyEnum.ONE, MyEnum.TWO};
+  }
+
+  @AutoAnnotation
+  static EverythingWithDefaults newEverythingWithDefaults() {
+    return new AutoAnnotation_AutoAnnotationDefaultsTest_newEverythingWithDefaults();
+  }
+
+  @Test
+  public void testDefaults() throws Exception {
+    @EverythingWithDefaults
+    class Annotated {}
+    EverythingWithDefaults expected = Annotated.class.getAnnotation(EverythingWithDefaults.class);
+    EverythingWithDefaults actual = newEverythingWithDefaults();
+
+    // Iterate over the annotation members to see if any differ. We could just compare expected and
+    // actual but if the comparison failed it could be hard to see exactly what differed.
+    StringBuilder differencesBuilder = new StringBuilder();
+    for (Method member : EverythingWithDefaults.class.getDeclaredMethods()) {
+      String name = member.getName();
+      Object expectedValue = member.invoke(expected);
+      Object actualValue = member.invoke(actual);
+      if (!equal(expectedValue, actualValue)) {
+        differencesBuilder
+            .append("For ")
+            .append(name)
+            .append(" expected <")
+            .append(string(expectedValue))
+            .append("> but was <")
+            .append(string(actualValue))
+            .append(">\n");
+      }
+    }
+    String differences = differencesBuilder.toString();
+    assertTrue(differences, differences.isEmpty());
+
+    // All the members were the same. Check that the equals and hashCode results say so too.
+    new EqualsTester().addEqualityGroup(expected, actual).testEquals();
+  }
+
+  private static boolean equal(Object x, Object y) {
+    return Arrays.deepEquals(new Object[] {x}, new Object[] {y});
+  }
+
+  private static String string(Object x) {
+    String s = Arrays.deepToString(new Object[] {x});
+    return s.substring(1, s.length() - 1);
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationTest.java
new file mode 100644
index 0000000..ca1ef6b
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoAnnotationTest.java
@@ -0,0 +1,614 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.auto.value.annotations.Empty;
+import com.google.auto.value.annotations.GwtArrays;
+import com.google.auto.value.annotations.StringValues;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.primitives.Ints;
+import com.google.common.testing.EqualsTester;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class AutoAnnotationTest {
+  @AutoAnnotation
+  private static StringValues newStringValues(String[] value) {
+    return new AutoAnnotation_AutoAnnotationTest_newStringValues(value);
+  }
+
+  @Empty
+  @StringValues("oops")
+  static class AnnotatedClass {}
+
+  @Test
+  public void testSimple() {
+    StringValues expectedStringValues = AnnotatedClass.class.getAnnotation(StringValues.class);
+    StringValues actualStringValues = newStringValues(new String[] {"oops"});
+    StringValues otherStringValues = newStringValues(new String[] {});
+    new EqualsTester()
+        .addEqualityGroup(expectedStringValues, actualStringValues)
+        .addEqualityGroup(otherStringValues)
+        .testEquals();
+  }
+
+  @Test
+  public void testArraysAreCloned() {
+    String[] array = {"Jekyll"};
+    StringValues stringValues = newStringValues(array);
+    array[0] = "Hyde";
+    assertEquals("Jekyll", stringValues.value()[0]);
+    stringValues.value()[0] = "Hyde";
+    assertEquals("Jekyll", stringValues.value()[0]);
+  }
+
+  @Test
+  public void testGwtArraysAreCloned() {
+    String[] strings = {"Jekyll"};
+    int[] ints = {2, 3, 5};
+    GwtArrays arrays = newGwtArrays(strings, ints);
+    assertEquals(ImmutableList.of("Jekyll"), ImmutableList.copyOf(arrays.strings()));
+    assertEquals(ImmutableList.of(2, 3, 5), Ints.asList(arrays.ints()));
+    strings[0] = "Hyde";
+    ints[0] = -1;
+    assertEquals(ImmutableList.of("Jekyll"), ImmutableList.copyOf(arrays.strings()));
+    assertEquals(ImmutableList.of(2, 3, 5), Ints.asList(arrays.ints()));
+  }
+
+  @AutoAnnotation
+  private static GwtArrays newGwtArrays(String[] strings, int[] ints) {
+    return new AutoAnnotation_AutoAnnotationTest_newGwtArrays(strings, ints);
+  }
+
+  @AutoAnnotation
+  private static StringValues newStringValuesVarArgs(String... value) {
+    return new AutoAnnotation_AutoAnnotationTest_newStringValuesVarArgs(value);
+  }
+
+  @Test
+  public void testSimpleVarArgs() {
+    StringValues expectedStringValues = AnnotatedClass.class.getAnnotation(StringValues.class);
+    StringValues actualStringValues = newStringValuesVarArgs("oops");
+    StringValues otherStringValues = newStringValuesVarArgs(new String[] {});
+    new EqualsTester()
+        .addEqualityGroup(expectedStringValues, actualStringValues)
+        .addEqualityGroup(otherStringValues)
+        .testEquals();
+  }
+
+  @AutoAnnotation
+  private static Empty newEmpty() {
+    return new AutoAnnotation_AutoAnnotationTest_newEmpty();
+  }
+
+  @Test
+  public void testEmpty() {
+    Empty expectedEmpty = AnnotatedClass.class.getAnnotation(Empty.class);
+    Empty actualEmpty = newEmpty();
+    new EqualsTester().addEqualityGroup(expectedEmpty, actualEmpty).testEquals();
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface Everything {
+    byte aByte();
+
+    short aShort();
+
+    int anInt();
+
+    long aLong();
+
+    float aFloat();
+
+    double aDouble();
+
+    char aChar();
+
+    boolean aBoolean();
+
+    String aString();
+
+    RetentionPolicy anEnum();
+
+    StringValues anAnnotation();
+
+    byte[] bytes();
+
+    short[] shorts();
+
+    int[] ints();
+
+    long[] longs();
+
+    float[] floats();
+
+    double[] doubles();
+
+    char[] chars();
+
+    boolean[] booleans();
+
+    String[] strings();
+
+    RetentionPolicy[] enums();
+
+    StringValues[] annotations();
+  }
+
+  @AutoAnnotation
+  static Everything newEverything(
+      byte aByte,
+      short aShort,
+      int anInt,
+      long aLong,
+      float aFloat,
+      double aDouble,
+      char aChar,
+      boolean aBoolean,
+      String aString,
+      RetentionPolicy anEnum,
+      StringValues anAnnotation,
+      byte[] bytes,
+      short[] shorts,
+      int[] ints,
+      long[] longs,
+      float[] floats,
+      double[] doubles,
+      char[] chars,
+      boolean[] booleans,
+      String[] strings,
+      RetentionPolicy[] enums,
+      StringValues[] annotations) {
+    return new AutoAnnotation_AutoAnnotationTest_newEverything(
+        aByte,
+        aShort,
+        anInt,
+        aLong,
+        aFloat,
+        aDouble,
+        aChar,
+        aBoolean,
+        aString,
+        anEnum,
+        anAnnotation,
+        bytes,
+        shorts,
+        ints,
+        longs,
+        floats,
+        doubles,
+        chars,
+        booleans,
+        strings,
+        enums,
+        annotations);
+  }
+
+  @AutoAnnotation
+  static Everything newEverythingCollections(
+      byte aByte,
+      short aShort,
+      int anInt,
+      long aLong,
+      float aFloat,
+      double aDouble,
+      char aChar,
+      boolean aBoolean,
+      String aString,
+      RetentionPolicy anEnum,
+      StringValues anAnnotation,
+      Collection<Byte> bytes,
+      List<Short> shorts,
+      ArrayList<Integer> ints,
+      Set<Long> longs,
+      SortedSet<Float> floats,
+      TreeSet<Double> doubles,
+      LinkedHashSet<Character> chars,
+      ImmutableCollection<Boolean> booleans,
+      ImmutableList<String> strings,
+      ImmutableSet<RetentionPolicy> enums,
+      Set<StringValues> annotations) {
+    return new AutoAnnotation_AutoAnnotationTest_newEverythingCollections(
+        aByte,
+        aShort,
+        anInt,
+        aLong,
+        aFloat,
+        aDouble,
+        aChar,
+        aBoolean,
+        aString,
+        anEnum,
+        anAnnotation,
+        bytes,
+        shorts,
+        ints,
+        longs,
+        floats,
+        doubles,
+        chars,
+        booleans,
+        strings,
+        enums,
+        annotations);
+  }
+
+  @Everything(
+      aByte = 1,
+      aShort = 2,
+      anInt = 3,
+      aLong = -4,
+      aFloat = Float.NaN,
+      aDouble = Double.NaN,
+      aChar = '#',
+      aBoolean = true,
+      aString = "maybe\nmaybe not\n",
+      anEnum = RetentionPolicy.RUNTIME,
+      anAnnotation = @StringValues("whatever"),
+      bytes = {5, 6},
+      shorts = {},
+      ints = {7},
+      longs = {8, 9},
+      floats = {10, 11},
+      doubles = {Double.NEGATIVE_INFINITY, -12.0, Double.POSITIVE_INFINITY},
+      chars = {'?', '!', '\n'},
+      booleans = {false, true, false},
+      strings = {"ver", "vers", "vert", "verre", "vair"},
+      enums = {RetentionPolicy.CLASS, RetentionPolicy.RUNTIME},
+      annotations = {@StringValues({}), @StringValues({"foo", "bar"})})
+  private static class AnnotatedWithEverything {}
+
+  // Get an instance of @Everything via reflection on the class AnnotatedWithEverything,
+  // fabricate an instance using newEverything that is supposed to be equal to it, and
+  // fabricate another instance using newEverything that is supposed to be different.
+  private static final Everything EVERYTHING_FROM_REFLECTION =
+      AnnotatedWithEverything.class.getAnnotation(Everything.class);
+  private static final Everything EVERYTHING_FROM_AUTO =
+      newEverything(
+          (byte) 1,
+          (short) 2,
+          3,
+          -4,
+          Float.NaN,
+          Double.NaN,
+          '#',
+          true,
+          "maybe\nmaybe not\n",
+          RetentionPolicy.RUNTIME,
+          newStringValues(new String[] {"whatever"}),
+          new byte[] {5, 6},
+          new short[] {},
+          new int[] {7},
+          new long[] {8, 9},
+          new float[] {10, 11},
+          new double[] {Double.NEGATIVE_INFINITY, -12.0, Double.POSITIVE_INFINITY},
+          new char[] {'?', '!', '\n'},
+          new boolean[] {false, true, false},
+          new String[] {"ver", "vers", "vert", "verre", "vair"},
+          new RetentionPolicy[] {RetentionPolicy.CLASS, RetentionPolicy.RUNTIME},
+          new StringValues[] {
+            newStringValues(new String[] {}), newStringValues(new String[] {"foo", "bar"}),
+          });
+  private static final Everything EVERYTHING_FROM_AUTO_COLLECTIONS =
+      newEverythingCollections(
+          (byte) 1,
+          (short) 2,
+          3,
+          -4,
+          Float.NaN,
+          Double.NaN,
+          '#',
+          true,
+          "maybe\nmaybe not\n",
+          RetentionPolicy.RUNTIME,
+          newStringValues(new String[] {"whatever"}),
+          Arrays.asList((byte) 5, (byte) 6),
+          Collections.<Short>emptyList(),
+          new ArrayList<Integer>(Collections.singleton(7)),
+          ImmutableSet.of(8L, 9L),
+          ImmutableSortedSet.of(10f, 11f),
+          new TreeSet<Double>(
+              ImmutableList.of(Double.NEGATIVE_INFINITY, -12.0, Double.POSITIVE_INFINITY)),
+          new LinkedHashSet<Character>(ImmutableList.of('?', '!', '\n')),
+          ImmutableList.of(false, true, false),
+          ImmutableList.of("ver", "vers", "vert", "verre", "vair"),
+          ImmutableSet.of(RetentionPolicy.CLASS, RetentionPolicy.RUNTIME),
+          ImmutableSet.of(
+              newStringValues(new String[] {}), newStringValues(new String[] {"foo", "bar"})));
+  private static final Everything EVERYTHING_ELSE_FROM_AUTO =
+      newEverything(
+          (byte) 0,
+          (short) 0,
+          0,
+          0,
+          0,
+          0,
+          '0',
+          false,
+          "",
+          RetentionPolicy.SOURCE,
+          newStringValues(new String[] {""}),
+          new byte[0],
+          new short[0],
+          new int[0],
+          new long[0],
+          new float[0],
+          new double[0],
+          new char[0],
+          new boolean[0],
+          new String[0],
+          new RetentionPolicy[0],
+          new StringValues[0]);
+  private static final Everything EVERYTHING_ELSE_FROM_AUTO_COLLECTIONS =
+      newEverythingCollections(
+          (byte) 0,
+          (short) 0,
+          0,
+          0,
+          0,
+          0,
+          '0',
+          false,
+          "",
+          RetentionPolicy.SOURCE,
+          newStringValues(new String[] {""}),
+          ImmutableList.<Byte>of(),
+          Collections.<Short>emptyList(),
+          new ArrayList<Integer>(),
+          Collections.<Long>emptySet(),
+          ImmutableSortedSet.<Float>of(),
+          new TreeSet<Double>(),
+          new LinkedHashSet<Character>(),
+          ImmutableSet.<Boolean>of(),
+          ImmutableList.<String>of(),
+          ImmutableSet.<RetentionPolicy>of(),
+          Collections.<StringValues>emptySet());
+
+  @Test
+  public void testEqualsAndHashCode() {
+    new EqualsTester()
+        .addEqualityGroup(
+            EVERYTHING_FROM_REFLECTION, EVERYTHING_FROM_AUTO, EVERYTHING_FROM_AUTO_COLLECTIONS)
+        .addEqualityGroup(EVERYTHING_ELSE_FROM_AUTO, EVERYTHING_ELSE_FROM_AUTO_COLLECTIONS)
+        .testEquals();
+  }
+
+  public static class IntList extends ArrayList<Integer> {
+    IntList(Collection<Integer> c) {
+      super(c);
+    }
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface IntArray {
+    int[] ints();
+  }
+
+  @IntArray(ints = {1, 2, 3})
+  private static class AnnotatedWithIntArray {}
+
+  @AutoAnnotation
+  static IntArray newIntArray(IntList ints) {
+    return new AutoAnnotation_AutoAnnotationTest_newIntArray(ints);
+  }
+
+  /**
+   * Test that we can represent a primitive array member with a parameter whose type is a collection
+   * of the corresponding wrapper type, even if the wrapper type is not explicitly a type parameter.
+   * Specifically, if the member is an {@code int[]} then obviously we can represent it as a {@code
+   * List<Integer>}, but here we test that we can also represent it as an {@code IntList}, which is
+   * only a {@code List<Integer>} by virtue of inheritance. This is a separate test rather than just
+   * putting an {@code IntList} parameter into {@link #newEverythingCollections} because we want to
+   * check that we are still able to detect the primitive wrapper type even though it's hidden in
+   * this way. We need to generate a helper method for every primitive wrapper.
+   */
+  @Test
+  public void testDerivedPrimitiveCollection() {
+    IntList intList = new IntList(ImmutableList.of(1, 2, 3));
+    IntArray actual = newIntArray(intList);
+    IntArray expected = AnnotatedWithIntArray.class.getAnnotation(IntArray.class);
+    assertEquals(expected, actual);
+  }
+
+  @Test
+  public void testToString() {
+    String expected =
+        "@com.google.auto.value.AutoAnnotationTest.Everything("
+            + "aByte=1, aShort=2, anInt=3, aLong=-4, aFloat=NaN, aDouble=NaN, aChar='#', "
+            + "aBoolean=true, aString=\"maybe\\nmaybe not\\n\", anEnum=RUNTIME, "
+            + "anAnnotation=@com.google.auto.value.annotations.StringValues([\"whatever\"]), "
+            + "bytes=[5, 6], shorts=[], ints=[7], longs=[8, 9], floats=[10.0, 11.0], "
+            + "doubles=[-Infinity, -12.0, Infinity], "
+            + "chars=['?', '!', '\\n'], "
+            + "booleans=[false, true, false], "
+            + "strings=[\"ver\", \"vers\", \"vert\", \"verre\", \"vair\"], "
+            + "enums=[CLASS, RUNTIME], "
+            + "annotations=["
+            + "@com.google.auto.value.annotations.StringValues([]), "
+            + "@com.google.auto.value.annotations.StringValues([\"foo\", \"bar\"])"
+            + "]"
+            + ")";
+    assertEquals(expected, EVERYTHING_FROM_AUTO.toString());
+    assertEquals(expected, EVERYTHING_FROM_AUTO_COLLECTIONS.toString());
+  }
+
+  @Test
+  public void testStringQuoting() {
+    StringValues instance =
+        newStringValues(
+            new String[] {
+              "", "\r\n", "hello, world", "Éamonn", "\007\uffef",
+            });
+    String expected =
+        "@com.google.auto.value.annotations.StringValues("
+            + "[\"\", \"\\r\\n\", \"hello, world\", \"Éamonn\", \"\\007\\uffef\"])";
+    assertEquals(expected, instance.toString());
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface AnnotationsAnnotation {
+    Class<? extends Annotation>[] value();
+  }
+
+  @AnnotationsAnnotation(AnnotationsAnnotation.class)
+  static class AnnotatedWithAnnotationsAnnotation {}
+
+  @AutoAnnotation
+  static AnnotationsAnnotation newAnnotationsAnnotation(List<Class<? extends Annotation>> value) {
+    return new AutoAnnotation_AutoAnnotationTest_newAnnotationsAnnotation(value);
+  }
+
+  @Test
+  public void testGenericArray() {
+    AnnotationsAnnotation generated =
+        newAnnotationsAnnotation(
+            ImmutableList.<Class<? extends Annotation>>of(AnnotationsAnnotation.class));
+    AnnotationsAnnotation fromReflect =
+        AnnotatedWithAnnotationsAnnotation.class.getAnnotation(AnnotationsAnnotation.class);
+    assertEquals(fromReflect, generated);
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface ClassesAnnotation {
+    Class<?>[] value();
+  }
+
+  @ClassesAnnotation(AnnotationsAnnotation.class)
+  static class AnnotatedWithClassesAnnotation {}
+
+  @AutoAnnotation
+  static ClassesAnnotation newClassesAnnotation(List<Class<?>> value) {
+    return new AutoAnnotation_AutoAnnotationTest_newClassesAnnotation(value);
+  }
+
+  @Test
+  public void testWildcardArray() {
+    ClassesAnnotation generated =
+        newClassesAnnotation(Arrays.<Class<?>>asList(AnnotationsAnnotation.class));
+    ClassesAnnotation fromReflect =
+        AnnotatedWithClassesAnnotation.class.getAnnotation(ClassesAnnotation.class);
+    assertEquals(fromReflect, generated);
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface IntegersAnnotation {
+    int one() default Integer.MAX_VALUE;
+
+    int two() default Integer.MAX_VALUE;
+
+    int three();
+  }
+
+  @IntegersAnnotation(three = 23)
+  static class AnnotatedWithIntegersAnnotation {}
+
+  @AutoAnnotation
+  static IntegersAnnotation newIntegersAnnotation(int three) {
+    return new AutoAnnotation_AutoAnnotationTest_newIntegersAnnotation(three);
+  }
+
+  @Test
+  public void testConstantOverflowInHashCode() {
+    IntegersAnnotation generated = newIntegersAnnotation(23);
+    IntegersAnnotation fromReflect =
+        AnnotatedWithIntegersAnnotation.class.getAnnotation(IntegersAnnotation.class);
+    new EqualsTester().addEqualityGroup(generated, fromReflect).testEquals();
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface EverythingWithDefaults {
+    byte aByte() default 5;
+
+    short aShort() default 17;
+
+    int anInt() default 23;
+
+    long aLong() default 1729;
+
+    float aFloat() default 5;
+
+    double aDouble() default 17;
+
+    char aChar() default 'x';
+
+    boolean aBoolean() default true;
+
+    String aString() default "whatever";
+
+    RetentionPolicy anEnum() default RetentionPolicy.CLASS;
+    // We don't yet support defaulting annotation values.
+    // StringValues anAnnotation() default @StringValues({"foo", "bar"});
+    byte[] bytes() default {1, 2};
+
+    short[] shorts() default {3, 4};
+
+    int[] ints() default {5, 6};
+
+    long[] longs() default {7, 8};
+
+    float[] floats() default {9, 10};
+
+    double[] doubles() default {11, 12};
+
+    char[] chars() default {'D', 'E'};
+
+    boolean[] booleans() default {true, false};
+
+    String[] strings() default {"vrai", "faux"};
+
+    RetentionPolicy[] enums() default {RetentionPolicy.SOURCE, RetentionPolicy.CLASS};
+    // We don't yet support defaulting annotation values.
+    // StringValues[] annotations() default {
+    //   @StringValues({"foo", "bar"}), @StringValues({"baz", "buh"})
+    // };
+  }
+
+  @EverythingWithDefaults
+  static class AnnotatedWithEverythingWithDefaults {}
+
+  @AutoAnnotation
+  static EverythingWithDefaults newEverythingWithDefaults() {
+    return new AutoAnnotation_AutoAnnotationTest_newEverythingWithDefaults();
+  }
+
+  @Test
+  public void testDefaultedValues() {
+    EverythingWithDefaults generated = newEverythingWithDefaults();
+    EverythingWithDefaults fromReflect =
+        AnnotatedWithEverythingWithDefaults.class.getAnnotation(EverythingWithDefaults.class);
+    new EqualsTester().addEqualityGroup(generated, fromReflect).testEquals();
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoOneOfJava8Test.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoOneOfJava8Test.java
new file mode 100644
index 0000000..2695bdf
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoOneOfJava8Test.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.Method;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for Java8-specific {@code @AutoOneOf} behaviour.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class AutoOneOfJava8Test {
+  @AutoOneOf(EqualsNullable.Kind.class)
+  public abstract static class EqualsNullable {
+
+    @Target(ElementType.TYPE_USE)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface Nullable {}
+
+    public enum Kind {
+      THING
+    }
+
+    public abstract Kind kind();
+
+    public abstract String thing();
+
+    public static EqualsNullable ofThing(String thing) {
+      return AutoOneOf_AutoOneOfJava8Test_EqualsNullable.thing(thing);
+    }
+
+    @Override
+    public abstract boolean equals(@Nullable Object x);
+
+    @Override
+    public abstract int hashCode();
+  }
+
+  /**
+   * Tests that a type annotation on the parameter of {@code equals(Object)} is copied into the
+   * implementation class.
+   */
+  @Test
+  public void equalsNullable() throws ReflectiveOperationException {
+    EqualsNullable x = EqualsNullable.ofThing("foo");
+    Class<? extends EqualsNullable> c = x.getClass();
+    Method equals = c.getMethod("equals", Object.class);
+    assertThat(equals.getDeclaringClass()).isNotSameInstanceAs(EqualsNullable.class);
+    AnnotatedType parameterType = equals.getAnnotatedParameterTypes()[0];
+    assertThat(parameterType.isAnnotationPresent(EqualsNullable.Nullable.class)).isTrue();
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoOneOfTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoOneOfTest.java
new file mode 100644
index 0000000..1b58728
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoOneOfTest.java
@@ -0,0 +1,661 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.common.testing.EqualsTester;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class AutoOneOfTest {
+  @AutoValue
+  public abstract static class Dog {
+    public abstract String name();
+
+    public static Dog create(String name) {
+      return new AutoValue_AutoOneOfTest_Dog(name);
+    }
+
+    public void bark() {}
+  }
+
+  @AutoValue
+  public abstract static class Cat {
+    public static Cat create() {
+      return new AutoValue_AutoOneOfTest_Cat();
+    }
+
+    public void meow() {}
+  }
+
+  @AutoValue
+  public abstract static class TigerShark {
+    public static TigerShark create() {
+      return new AutoValue_AutoOneOfTest_TigerShark();
+    }
+
+    public void chomp() {}
+  }
+
+  @AutoOneOf(Pet.Kind.class)
+  public abstract static class Pet {
+
+    public static Pet create(Dog dog) {
+      return AutoOneOf_AutoOneOfTest_Pet.dog(dog);
+    }
+
+    public static Pet create(Cat cat) {
+      return AutoOneOf_AutoOneOfTest_Pet.cat(cat);
+    }
+
+    public static Pet create(TigerShark shark) {
+      return AutoOneOf_AutoOneOfTest_Pet.tigerShark(shark);
+    }
+
+    public abstract Dog dog();
+
+    public abstract Cat cat();
+
+    public abstract TigerShark tigerShark();
+
+    public enum Kind {
+      DOG,
+      CAT,
+      TIGER_SHARK
+    }
+
+    public abstract Kind getKind();
+  }
+
+  @Test
+  public void equality() {
+    Dog marvin1 = Dog.create("Marvin");
+    Pet petMarvin1 = Pet.create(marvin1);
+    Dog marvin2 = Dog.create("Marvin");
+    Pet petMarvin2 = Pet.create(marvin2);
+    Dog isis = Dog.create("Isis");
+    Pet petIsis = Pet.create(isis);
+    Cat cat = Cat.create();
+    new EqualsTester()
+        .addEqualityGroup(marvin1, marvin2)
+        .addEqualityGroup(petMarvin1, petMarvin2)
+        .addEqualityGroup(petIsis)
+        .addEqualityGroup(cat)
+        .addEqualityGroup("foo")
+        .testEquals();
+  }
+
+  @Test
+  public void getCorrectType() {
+    Dog marvin = Dog.create("Marvin");
+    Pet petMarvin = Pet.create(marvin);
+    assertThat(petMarvin.dog()).isSameInstanceAs(marvin);
+  }
+
+  @Test
+  public void getWrongType() {
+    Cat cat = Cat.create();
+    Pet petCat = Pet.create(cat);
+    try {
+      petCat.tigerShark();
+      fail();
+    } catch (UnsupportedOperationException e) {
+      assertThat(e).hasMessageThat().containsMatch("(?i:cat)");
+    }
+  }
+
+  @Test
+  public void string() {
+    Dog marvin = Dog.create("Marvin");
+    Pet petMarvin = Pet.create(marvin);
+    assertThat(petMarvin.toString()).isEqualTo("Pet{dog=Dog{name=Marvin}}");
+  }
+
+  @Test
+  public void getKind() {
+    Dog marvin = Dog.create("Marvin");
+    Pet petMarvin = Pet.create(marvin);
+    Cat cat = Cat.create();
+    Pet petCat = Pet.create(cat);
+    TigerShark shark = TigerShark.create();
+    Pet petShark = Pet.create(shark);
+    assertThat(petMarvin.getKind()).isEqualTo(Pet.Kind.DOG);
+    assertThat(petCat.getKind()).isEqualTo(Pet.Kind.CAT);
+    assertThat(petShark.getKind()).isEqualTo(Pet.Kind.TIGER_SHARK);
+  }
+
+  @Test
+  public void cannotBeNull() {
+    try {
+      Pet.create((Dog) null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  // Package-private case.
+
+  @AutoOneOf(IntegerOrString.Kind.class)
+  abstract static class IntegerOrString {
+    enum Kind {
+      INTEGER,
+      STRING
+    }
+
+    abstract Kind getKind();
+
+    abstract int integer();
+
+    abstract String string();
+
+    static IntegerOrString of(int x) {
+      return AutoOneOf_AutoOneOfTest_IntegerOrString.integer(x);
+    }
+
+    static IntegerOrString of(String x) {
+      return AutoOneOf_AutoOneOfTest_IntegerOrString.string(x);
+    }
+  }
+
+  @Test
+  public void packagePrivate() {
+    IntegerOrString integer = IntegerOrString.of(23);
+    IntegerOrString string = IntegerOrString.of("23");
+    assertThat(integer.getKind()).isEqualTo(IntegerOrString.Kind.INTEGER);
+    assertThat(string.getKind()).isEqualTo(IntegerOrString.Kind.STRING);
+    assertThat(integer.integer()).isEqualTo(23);
+    assertThat(string.string()).isEqualTo("23");
+    assertThat(integer).isNotEqualTo(string);
+    try {
+      integer.string();
+      fail();
+    } catch (UnsupportedOperationException e) {
+      assertThat(e).hasMessageThat().containsMatch("(?i:integer)");
+    }
+  }
+
+  @AutoOneOf(Pet.Kind.class)
+  public abstract static class PetWithGet {
+    public abstract Dog getDog();
+
+    public abstract Cat getCat();
+
+    public abstract TigerShark getTigerShark();
+
+    public static PetWithGet create(Dog dog) {
+      return AutoOneOf_AutoOneOfTest_PetWithGet.dog(dog);
+    }
+
+    public static PetWithGet create(Cat cat) {
+      return AutoOneOf_AutoOneOfTest_PetWithGet.cat(cat);
+    }
+
+    public static PetWithGet create(TigerShark shark) {
+      return AutoOneOf_AutoOneOfTest_PetWithGet.tigerShark(shark);
+    }
+
+    public abstract Pet.Kind getKind();
+  }
+
+  @Test
+  public void getPrefix() {
+    Dog marvin = Dog.create("Marvin");
+    PetWithGet petMarvin = PetWithGet.create(marvin);
+    assertThat(petMarvin.toString()).isEqualTo("PetWithGet{dog=Dog{name=Marvin}}");
+  }
+
+  @AutoOneOf(Primitive.Kind.class)
+  public abstract static class Primitive {
+    public enum Kind {
+      A_BYTE,
+      A_SHORT,
+      AN_INT,
+      A_LONG,
+      A_FLOAT,
+      A_DOUBLE,
+      A_CHAR,
+      A_BOOLEAN
+    }
+
+    public abstract Kind getKind();
+
+    public abstract byte aByte();
+
+    public abstract short aShort();
+
+    public abstract int anInt();
+
+    public abstract long aLong();
+
+    public abstract float aFloat();
+
+    public abstract double aDouble();
+
+    public abstract char aChar();
+
+    public abstract boolean aBoolean();
+
+    public static Primitive of(byte x) {
+      return AutoOneOf_AutoOneOfTest_Primitive.aByte(x);
+    }
+
+    public static Primitive of(short x) {
+      return AutoOneOf_AutoOneOfTest_Primitive.aShort(x);
+    }
+
+    public static Primitive of(int x) {
+      return AutoOneOf_AutoOneOfTest_Primitive.anInt(x);
+    }
+
+    public static Primitive of(long x) {
+      return AutoOneOf_AutoOneOfTest_Primitive.aLong(x);
+    }
+
+    public static Primitive of(float x) {
+      return AutoOneOf_AutoOneOfTest_Primitive.aFloat(x);
+    }
+
+    public static Primitive of(double x) {
+      return AutoOneOf_AutoOneOfTest_Primitive.aDouble(x);
+    }
+
+    public static Primitive of(char x) {
+      return AutoOneOf_AutoOneOfTest_Primitive.aChar(x);
+    }
+
+    public static Primitive of(boolean x) {
+      return AutoOneOf_AutoOneOfTest_Primitive.aBoolean(x);
+    }
+  }
+
+  @Test
+  public void primitive() {
+    Primitive primitive = Primitive.of(17);
+    assertThat(primitive.anInt()).isEqualTo(17);
+    assertThat(primitive.toString()).isEqualTo("Primitive{anInt=17}");
+  }
+
+  @AutoOneOf(OneOfOne.Kind.class)
+  public abstract static class OneOfOne {
+    public enum Kind {
+      DOG
+    }
+
+    public abstract Dog getDog();
+
+    public static OneOfOne create(Dog dog) {
+      return AutoOneOf_AutoOneOfTest_OneOfOne.dog(dog);
+    }
+
+    public abstract Kind getKind();
+  }
+
+  @Test
+  public void oneOfOne() {
+    Dog marvin = Dog.create("Marvin");
+    OneOfOne oneOfMarvin = OneOfOne.create(marvin);
+    assertThat(oneOfMarvin.toString()).isEqualTo("OneOfOne{dog=Dog{name=Marvin}}");
+    assertThat(oneOfMarvin.getKind()).isEqualTo(OneOfOne.Kind.DOG);
+  }
+
+  // We allow this for consistency, even though it's obviously pretty useless.
+  // The generated code might be rubbish, but it compiles. No concrete implementation is generated
+  // so there isn't really anything to test beyond that it compiles.
+  @AutoOneOf(OneOfNone.Kind.class)
+  public abstract static class OneOfNone {
+    public enum Kind {}
+
+    public abstract Kind getKind();
+  }
+
+  // Testing generics. Typically generics will be a bit messy because the @AutoOneOf class must
+  // have type parameters for every property that needs them, even though any given property
+  // might not use all the type parameters.
+  @AutoOneOf(TaskResult.Kind.class)
+  public abstract static class TaskResult<V extends Serializable> {
+    public enum Kind {
+      VALUE,
+      EXCEPTION
+    }
+
+    public abstract Kind getKind();
+
+    public abstract V value();
+
+    public abstract Throwable exception();
+
+    public V get() throws ExecutionException {
+      switch (getKind()) {
+        case VALUE:
+          return value();
+        case EXCEPTION:
+          throw new ExecutionException(exception());
+      }
+      throw new AssertionError(getKind());
+    }
+
+    static <V extends Serializable> TaskResult<V> value(V value) {
+      return AutoOneOf_AutoOneOfTest_TaskResult.value(value);
+    }
+
+    static TaskResult<?> exception(Throwable exception) {
+      return AutoOneOf_AutoOneOfTest_TaskResult.exception(exception);
+    }
+  }
+
+  @Test
+  public void taskResultValue() throws Exception {
+    TaskResult<String> result = TaskResult.value("foo");
+    assertThat(result.get()).isEqualTo("foo");
+  }
+
+  @Test
+  public void taskResultException() {
+    Exception exception = new IllegalArgumentException("oops");
+    TaskResult<?> result = TaskResult.exception(exception);
+    try {
+      result.get();
+      fail();
+    } catch (ExecutionException e) {
+      assertThat(e).hasCauseThat().isEqualTo(exception);
+    }
+  }
+
+  @AutoOneOf(CustomToString.Kind.class)
+  public abstract static class CustomToString {
+    public enum Kind {
+      ACE
+    }
+
+    public abstract Kind getKind();
+
+    public abstract String ace();
+
+    public static CustomToString ace(String ace) {
+      return AutoOneOf_AutoOneOfTest_CustomToString.ace(ace);
+    }
+
+    @Override
+    public String toString() {
+      return "blim";
+    }
+  }
+
+  // If you have an explicit toString() method, we won't override it.
+  @Test
+  public void customToString() {
+    CustomToString x = CustomToString.ace("ceg");
+    assertThat(x.toString()).isEqualTo("blim");
+  }
+
+  @AutoOneOf(AbstractToString.Kind.class)
+  public abstract static class AbstractToString {
+    public enum Kind {
+      ACE
+    }
+
+    public abstract Kind getKind();
+
+    public abstract String ace();
+
+    public static AbstractToString ace(String ace) {
+      return AutoOneOf_AutoOneOfTest_AbstractToString.ace(ace);
+    }
+
+    @Override
+    public abstract String toString();
+  }
+
+  // If you have an explicit abstract toString() method, we will implement it.
+  @Test
+  public void abstractToString() {
+    AbstractToString x = AbstractToString.ace("ceg");
+    assertThat(x.toString()).isEqualTo("AbstractToString{ace=ceg}");
+  }
+
+  // "package" is a reserved word. You probably don't want to have a property with that name,
+  // but if you insist, you can get one by using getFoo()-style methods. We leak our renaming
+  // scheme here (package0) and for users that that bothers they can just avoid having properties
+  // that are reserved words.
+  @AutoOneOf(LetterOrPackage.Kind.class)
+  public abstract static class LetterOrPackage {
+    public enum Kind {
+      LETTER,
+      PACKAGE
+    }
+
+    public abstract Kind getKind();
+
+    public abstract String getLetter();
+
+    public abstract String getPackage();
+
+    public static LetterOrPackage ofLetter(String letter) {
+      return AutoOneOf_AutoOneOfTest_LetterOrPackage.letter(letter);
+    }
+
+    public static LetterOrPackage ofPackage(String pkg) {
+      return AutoOneOf_AutoOneOfTest_LetterOrPackage.package0(pkg);
+    }
+  }
+
+  @Test
+  public void reservedWordProperty() {
+    LetterOrPackage pkg = LetterOrPackage.ofPackage("pacquet");
+    assertThat(pkg.toString()).isEqualTo("LetterOrPackage{package=pacquet}");
+  }
+
+  @AutoOneOf(ArrayValue.Kind.class)
+  public abstract static class ArrayValue {
+    public enum Kind {
+      STRING,
+      INTS
+    }
+
+    public abstract Kind getKind();
+
+    public abstract String string();
+
+    @SuppressWarnings("mutable")
+    public abstract int[] ints();
+
+    public static ArrayValue ofString(String string) {
+      return AutoOneOf_AutoOneOfTest_ArrayValue.string(string);
+    }
+
+    public static ArrayValue ofInts(int[] ints) {
+      return AutoOneOf_AutoOneOfTest_ArrayValue.ints(ints);
+    }
+  }
+
+  @Test
+  public void arrayValues() {
+    ArrayValue string = ArrayValue.ofString("foo");
+    ArrayValue ints1 = ArrayValue.ofInts(new int[] {17, 23});
+    ArrayValue ints2 = ArrayValue.ofInts(new int[] {17, 23});
+    new EqualsTester()
+        .addEqualityGroup(string)
+        .addEqualityGroup(ints1, ints2)
+        .testEquals();
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  public @interface CopyTest {
+    int value();
+  }
+
+  @AutoOneOf(AnnotationNotCopied.Kind.class)
+  @CopyTest(23)
+  public abstract static class AnnotationNotCopied {
+    public enum Kind {
+      ACE
+    }
+
+    public abstract Kind getKind();
+
+    public abstract String ace();
+
+    public static AnnotationNotCopied ace(String ace) {
+      return AutoOneOf_AutoOneOfTest_AnnotationNotCopied.ace(ace);
+    }
+  }
+
+  @Test
+  public void classAnnotationsNotCopiedByDefault() {
+    assertThat(AnnotationNotCopied.class.isAnnotationPresent(CopyTest.class)).isTrue();
+    AnnotationNotCopied ace = AnnotationNotCopied.ace("ace");
+    assertThat(ace.getClass().isAnnotationPresent(CopyTest.class)).isFalse();
+  }
+
+  @AutoOneOf(AnnotationCopied.Kind.class)
+  @CopyTest(23)
+  @AutoValue.CopyAnnotations
+  public abstract static class AnnotationCopied {
+    public enum Kind {
+      ACE
+    }
+
+    public abstract Kind getKind();
+
+    public abstract String ace();
+
+    public static AnnotationCopied ace(String ace) {
+      return AutoOneOf_AutoOneOfTest_AnnotationCopied.ace(ace);
+    }
+  }
+
+  @Test
+  public void classAnnotationsCopiedIfCopyAnnotations() {
+    assertThat(AnnotationCopied.class.isAnnotationPresent(CopyTest.class)).isTrue();
+    AnnotationCopied ace = AnnotationCopied.ace("ace");
+    assertThat(ace.getClass().isAnnotationPresent(CopyTest.class)).isTrue();
+    assertThat(ace.getClass().getAnnotation(CopyTest.class).value()).isEqualTo(23);
+  }
+
+  @AutoOneOf(MaybeEmpty.Kind.class)
+  public abstract static class MaybeEmpty implements Serializable {
+    public enum Kind {
+      EMPTY, STRING,
+    }
+
+    public abstract Kind getKind();
+
+    public abstract void empty();
+
+    public abstract String string();
+
+    public static MaybeEmpty ofEmpty() {
+      return AutoOneOf_AutoOneOfTest_MaybeEmpty.empty();
+    }
+
+    public static MaybeEmpty ofString(String s) {
+      return AutoOneOf_AutoOneOfTest_MaybeEmpty.string(s);
+    }
+  }
+
+  @Test
+  public void voidPropertyIsSingleton() {
+    MaybeEmpty empty1 = MaybeEmpty.ofEmpty();
+    MaybeEmpty empty2 = MaybeEmpty.ofEmpty();
+    assertThat(empty1).isSameInstanceAs(empty2);
+  }
+
+  @Test
+  public void voidPropertyRemainsSingletonWhenDeserialized() throws Exception {
+    MaybeEmpty empty1 = MaybeEmpty.ofEmpty();
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    // We're still compiling this with -source 6, so we can't use try-with-resources.
+    ObjectOutputStream dos = new ObjectOutputStream(baos);
+    dos.writeObject(empty1);
+    dos.close();
+    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+    ObjectInputStream ois = new ObjectInputStream(bais);
+    MaybeEmpty empty2 = (MaybeEmpty) ois.readObject();
+    assertThat(empty2).isSameInstanceAs(empty1);
+  }
+
+  @Test
+  public void voidPropertyToString() {
+    MaybeEmpty empty = MaybeEmpty.ofEmpty();
+    assertThat(empty.toString()).isEqualTo("MaybeEmpty{empty}");
+  }
+
+  @Test
+  public void voidPropertyHashCodeIsIdentity() {
+    MaybeEmpty empty = MaybeEmpty.ofEmpty();
+    assertThat(empty.hashCode()).isEqualTo(System.identityHashCode(empty));
+  }
+
+  @Test
+  public void voidPropertyGetterDoesNothing() {
+    MaybeEmpty empty = MaybeEmpty.ofEmpty();
+    empty.empty();
+  }
+
+  @Test
+  public void voidPropertyNotEqualToNonVoid() {
+    MaybeEmpty empty = MaybeEmpty.ofEmpty();
+    MaybeEmpty notEmpty = MaybeEmpty.ofString("foo");
+    assertThat(empty).isNotEqualTo(notEmpty);
+    assertThat(notEmpty).isNotEqualTo(empty);
+  }
+
+  @Test
+  public void voidPropertyWrongType() {
+    MaybeEmpty notEmpty = MaybeEmpty.ofString("foo");
+    try {
+      notEmpty.empty();
+      fail();
+    } catch (UnsupportedOperationException e) {
+      assertThat(e).hasMessageThat().containsMatch("(?i:string)");
+    }
+  }
+
+  @AutoOneOf(OneOfArray.Kind.class)
+  public abstract static class OneOfArray {
+    public enum Kind {
+      INTS
+    }
+
+    public abstract Kind getKind();
+
+    @SuppressWarnings("mutable")
+    public abstract int[] ints();
+
+    public static OneOfArray ofInts(int[] s) {
+      return AutoOneOf_AutoOneOfTest_OneOfArray.ints(s);
+    }
+  }
+
+  @Test
+  public void arrayToString() {
+    OneOfArray oneOfArray = OneOfArray.ofInts(new int[] {1, 2});
+    assertThat(oneOfArray.toString()).isEqualTo("OneOfArray{ints=[1, 2]}");
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueJava8Test.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueJava8Test.java
new file mode 100644
index 0000000..27356c5
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueJava8Test.java
@@ -0,0 +1,797 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static com.google.common.truth.Truth8.assertThat;
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeTrue;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.testing.EqualsTester;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.Compiler;
+import com.google.testing.compile.JavaFileObjects;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.TypeVariable;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Predicate;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.ElementFilter;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for constructs new in Java 8, such as type annotations.
+ *
+ * @author Till Brychcy
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class AutoValueJava8Test {
+  private static boolean javacHandlesTypeAnnotationsCorrectly;
+
+  // This is appalling. Some versions of javac do not correctly report annotations on type uses in
+  // certain cases, for example on type variables or arrays. Since some of the tests here are for
+  // exactly that, we compile a test program with a test annotation processor to see whether we
+  // might be in the presence of such a javac, and if so we skip the tests that would fail because
+  // of the bug. This isn't completely sound because we can't be entirely sure that the javac that
+  // Compiler.javac() finds is the same as the javac that was used to build this test (and therefore
+  // run AutoValueProcessor), but it's better than just ignoring the tests outright.
+  @BeforeClass
+  public static void setUpClass() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "Test",
+            "import java.lang.annotation.ElementType;",
+            "import java.lang.annotation.Retention;",
+            "import java.lang.annotation.RetentionPolicy;",
+            "import java.lang.annotation.Target;",
+            "public abstract class Test<T> {",
+            "  @Retention(RetentionPolicy.RUNTIME)",
+            "  @Target(ElementType.TYPE_USE)",
+            "  public @interface Nullable {}",
+            "",
+            "  public abstract @Nullable T t();",
+            "}");
+    Compilation compilation =
+        Compiler.javac().withProcessors(new BugTestProcessor()).compile(javaFileObject);
+    if (compilation.errors().isEmpty()) {
+      javacHandlesTypeAnnotationsCorrectly = true;
+    } else {
+      assertThat(compilation).hadErrorCount(1);
+      assertThat(compilation).hadErrorContaining(JAVAC_HAS_BUG_ERROR);
+    }
+  }
+
+  private static final String JAVAC_HAS_BUG_ERROR = "javac has the type-annotation bug";
+
+  @SupportedAnnotationTypes("*")
+  @SupportedSourceVersion(SourceVersion.RELEASE_8)
+  private static class BugTestProcessor extends AbstractProcessor {
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      if (roundEnv.processingOver()) {
+        test();
+      }
+      return false;
+    }
+
+    private void test() {
+      TypeElement test = processingEnv.getElementUtils().getTypeElement("Test");
+      List<ExecutableElement> methods = ElementFilter.methodsIn(test.getEnclosedElements());
+      ExecutableElement t = Iterables.getOnlyElement(methods);
+      assertThat(t.getSimpleName().toString()).isEqualTo("t");
+      List<? extends AnnotationMirror> typeAnnotations = t.getReturnType().getAnnotationMirrors();
+      if (typeAnnotations.isEmpty()) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, JAVAC_HAS_BUG_ERROR);
+        return;
+      }
+      AnnotationMirror typeAnnotation = Iterables.getOnlyElement(typeAnnotations);
+      assertThat(typeAnnotation.getAnnotationType().toString()).contains("Nullable");
+    }
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @Target(ElementType.TYPE_USE)
+  public @interface Nullable {}
+
+  @AutoValue
+  abstract static class NullableProperties {
+    abstract @Nullable String nullableString();
+
+    abstract int randomInt();
+
+    static NullableProperties create(@Nullable String nullableString, int randomInt) {
+      return new AutoValue_AutoValueJava8Test_NullableProperties(nullableString, randomInt);
+    }
+  }
+
+  @Test
+  public void testNullablePropertiesCanBeNull() {
+    NullableProperties instance = NullableProperties.create(null, 23);
+    assertThat(instance.nullableString()).isNull();
+    assertThat(instance.randomInt()).isEqualTo(23);
+    assertThat(instance.toString())
+        .isEqualTo("NullableProperties{nullableString=null, randomInt=23}");
+  }
+
+  @AutoAnnotation
+  static Nullable nullable() {
+    return new AutoAnnotation_AutoValueJava8Test_nullable();
+  }
+
+  @Test
+  public void testNullablePropertyImplementationIsNullable() throws NoSuchMethodException {
+    Method method =
+        AutoValue_AutoValueJava8Test_NullableProperties.class.getDeclaredMethod("nullableString");
+    assertThat(method.getAnnotatedReturnType().getAnnotations())
+        .asList()
+        .contains(nullable());
+  }
+
+  @Test
+  public void testNullablePropertyConstructorParameterIsNullable() throws NoSuchMethodException {
+    Constructor<?> constructor =
+        AutoValue_AutoValueJava8Test_NullableProperties.class.getDeclaredConstructor(
+            String.class, int.class);
+    try {
+      assertThat(constructor.getAnnotatedParameterTypes()[0].getAnnotations())
+          .asList()
+          .contains(nullable());
+    } catch (AssertionError e) {
+      if (javacHandlesTypeAnnotationsCorrectly) {
+        throw e;
+      }
+    }
+  }
+
+  @AutoValue
+  abstract static class NullablePropertiesNotCopied {
+    @AutoValue.CopyAnnotations(exclude = Nullable.class)
+    abstract @Nullable String nullableString();
+
+    abstract int randomInt();
+
+    NullablePropertiesNotCopied create(String notNullableAfterAll, int randomInt) {
+      return new AutoValue_AutoValueJava8Test_NullablePropertiesNotCopied(
+          notNullableAfterAll, randomInt);
+    }
+  }
+
+  @Test
+  public void testExcludedNullablePropertyImplementation() throws NoSuchMethodException {
+    Method method = AutoValue_AutoValueJava8Test_NullablePropertiesNotCopied.class
+        .getDeclaredMethod("nullableString");
+    assertThat(method.getAnnotatedReturnType().getAnnotations())
+        .asList()
+        .doesNotContain(nullable());
+  }
+
+  @Test
+  public void testExcludedNullablePropertyConstructorParameter() throws NoSuchMethodException {
+    Constructor<?> constructor =
+        AutoValue_AutoValueJava8Test_NullablePropertiesNotCopied.class.getDeclaredConstructor(
+            String.class, int.class);
+    try {
+      assertThat(constructor.getAnnotatedParameterTypes()[0].getAnnotations())
+          .asList()
+          .doesNotContain(nullable());
+    } catch (AssertionError e) {
+      if (javacHandlesTypeAnnotationsCorrectly) {
+        throw e;
+      }
+    }
+  }
+
+  @AutoValue
+  abstract static class NullableNonNullable {
+    abstract @Nullable String nullableString();
+
+    abstract @Nullable String otherNullableString();
+
+    abstract String nonNullableString();
+
+    static NullableNonNullable create(
+        String nullableString, String otherNullableString, String nonNullableString) {
+      return new AutoValue_AutoValueJava8Test_NullableNonNullable(
+          nullableString, otherNullableString, nonNullableString);
+    }
+  }
+
+  @Test
+  public void testEqualsWithNullable() throws Exception {
+    NullableNonNullable everythingNull =
+        NullableNonNullable.create(null, null, "nonNullableString");
+    NullableNonNullable somethingNull =
+        NullableNonNullable.create(null, "otherNullableString", "nonNullableString");
+    NullableNonNullable nothingNull =
+        NullableNonNullable.create("nullableString", "otherNullableString", "nonNullableString");
+    NullableNonNullable nothingNullAgain =
+        NullableNonNullable.create("nullableString", "otherNullableString", "nonNullableString");
+    new EqualsTester()
+        .addEqualityGroup(everythingNull)
+        .addEqualityGroup(somethingNull)
+        .addEqualityGroup(nothingNull, nothingNullAgain)
+        .testEquals();
+  }
+
+  public static class Nested {}
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @Target(ElementType.TYPE_USE)
+  public @interface OtherTypeAnnotation {}
+
+  @AutoAnnotation
+  public static OtherTypeAnnotation otherTypeAnnotation() {
+    return new AutoAnnotation_AutoValueJava8Test_otherTypeAnnotation();
+  }
+
+  @AutoValue
+  abstract static class NestedNullableProperties {
+    abstract @Nullable @OtherTypeAnnotation Nested nullableThing();
+
+    abstract int randomInt();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueJava8Test_NestedNullableProperties.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder setNullableThing(@Nullable @OtherTypeAnnotation Nested thing);
+
+      abstract Builder setRandomInt(int x);
+
+      abstract NestedNullableProperties build();
+    }
+  }
+
+  @Test
+  public void testNestedNullablePropertiesCanBeNull() {
+    NestedNullableProperties instance = NestedNullableProperties.builder().setRandomInt(23).build();
+    assertThat(instance.nullableThing()).isNull();
+    assertThat(instance.randomInt()).isEqualTo(23);
+    assertThat(instance.toString())
+        .isEqualTo("NestedNullableProperties{nullableThing=null, randomInt=23}");
+  }
+
+  @Test
+  public void testNestedNullablePropertiesAreCopied() throws Exception {
+    try {
+      Method generatedGetter =
+          AutoValue_AutoValueJava8Test_NestedNullableProperties.class.getDeclaredMethod(
+              "nullableThing");
+      Annotation[] getterAnnotations = generatedGetter.getAnnotatedReturnType().getAnnotations();
+      assertThat(getterAnnotations).asList().containsAtLeast(nullable(), otherTypeAnnotation());
+
+      Method generatedSetter =
+          AutoValue_AutoValueJava8Test_NestedNullableProperties.Builder.class.getDeclaredMethod(
+              "setNullableThing", Nested.class);
+      Annotation[] setterAnnotations =
+          generatedSetter.getAnnotatedParameterTypes()[0].getAnnotations();
+      assertThat(setterAnnotations).asList().containsAtLeast(nullable(), otherTypeAnnotation());
+    } catch (AssertionError e) {
+      if (javacHandlesTypeAnnotationsCorrectly) {
+        throw e;
+      }
+    }
+  }
+
+  @AutoValue
+  @SuppressWarnings("AutoValueImmutableFields")
+  abstract static class PrimitiveArrays {
+    @SuppressWarnings("mutable")
+    abstract boolean[] booleans();
+
+    @SuppressWarnings("mutable")
+    abstract int @Nullable [] ints();
+
+    static PrimitiveArrays create(boolean[] booleans, int[] ints) {
+      // Real code would likely clone these parameters, but here we want to check that the
+      // generated constructor rejects a null value for booleans.
+      return new AutoValue_AutoValueJava8Test_PrimitiveArrays(booleans, ints);
+    }
+  }
+
+  @Test
+  public void testPrimitiveArrays() {
+    PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], new int[0]);
+    boolean[] booleans = {false, true, true, false};
+    int[] ints = {6, 28, 496, 8128, 33550336};
+    PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), ints.clone());
+    PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), ints.clone());
+    new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();
+    // EqualsTester also exercises hashCode(). We clone the arrays above to ensure that using the
+    // default Object.hashCode() will fail.
+
+    String expectedString =
+        "PrimitiveArrays{booleans="
+            + Arrays.toString(booleans)
+            + ", "
+            + "ints="
+            + Arrays.toString(ints)
+            + "}";
+    assertThat(object1.toString()).isEqualTo(expectedString);
+
+    assertThat(object1.ints()).isSameInstanceAs(object1.ints());
+  }
+
+  @Test
+  public void testNullablePrimitiveArrays() {
+    assumeTrue(javacHandlesTypeAnnotationsCorrectly);
+    PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], null);
+    boolean[] booleans = {false, true, true, false};
+    PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), null);
+    PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), null);
+    new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();
+
+    String expectedString =
+        "PrimitiveArrays{booleans=" + Arrays.toString(booleans) + ", " + "ints=null}";
+    assertThat(object1.toString()).isEqualTo(expectedString);
+
+    assertThat(object1.booleans()).isSameInstanceAs(object1.booleans());
+    assertThat(object1.booleans()).isEqualTo(booleans);
+    object1.booleans()[0] ^= true;
+    assertThat(object1.booleans()).isNotEqualTo(booleans);
+  }
+
+  @Test
+  public void testNotNullablePrimitiveArrays() {
+    try {
+      PrimitiveArrays.create(null, new int[0]);
+      fail("Construction with null value for non-@Nullable array should have failed");
+    } catch (NullPointerException e) {
+      assertThat(e.getMessage()).contains("booleans");
+    }
+  }
+
+  @AutoValue
+  public abstract static class NullablePropertyWithBuilder {
+    public abstract String notNullable();
+
+    public abstract @Nullable String nullable();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueJava8Test_NullablePropertyWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder notNullable(String s);
+
+      Builder nullable(@Nullable String s);
+
+      NullablePropertyWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testOmitNullableWithBuilder() {
+    NullablePropertyWithBuilder instance1 =
+        NullablePropertyWithBuilder.builder().notNullable("hello").build();
+    assertThat(instance1.notNullable()).isEqualTo("hello");
+    assertThat(instance1.nullable()).isNull();
+
+    NullablePropertyWithBuilder instance2 =
+        NullablePropertyWithBuilder.builder().notNullable("hello").nullable(null).build();
+    assertThat(instance2.notNullable()).isEqualTo("hello");
+    assertThat(instance2.nullable()).isNull();
+    assertThat(instance1).isEqualTo(instance2);
+
+    NullablePropertyWithBuilder instance3 =
+        NullablePropertyWithBuilder.builder().notNullable("hello").nullable("world").build();
+    assertThat(instance3.notNullable()).isEqualTo("hello");
+    assertThat(instance3.nullable()).isEqualTo("world");
+
+    try {
+      NullablePropertyWithBuilder.builder().build();
+      fail("Expected IllegalStateException for unset non-@Nullable property");
+    } catch (IllegalStateException e) {
+      assertThat(e.getMessage()).contains("notNullable");
+    }
+  }
+
+  @AutoValue
+  public abstract static class OptionalPropertyWithNullableBuilder {
+    public abstract String notOptional();
+
+    public abstract Optional<String> optional();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueJava8Test_OptionalPropertyWithNullableBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder notOptional(String s);
+
+      Builder optional(@Nullable String s);
+
+      OptionalPropertyWithNullableBuilder build();
+    }
+  }
+
+  @Test
+  public void testOmitOptionalWithNullableBuilder() {
+    OptionalPropertyWithNullableBuilder instance1 =
+        OptionalPropertyWithNullableBuilder.builder().notOptional("hello").build();
+    assertThat(instance1.notOptional()).isEqualTo("hello");
+    assertThat(instance1.optional()).isEmpty();
+
+    OptionalPropertyWithNullableBuilder instance2 =
+        OptionalPropertyWithNullableBuilder.builder().notOptional("hello").optional(null).build();
+    assertThat(instance2.notOptional()).isEqualTo("hello");
+    assertThat(instance2.optional()).isEmpty();
+    assertThat(instance1).isEqualTo(instance2);
+
+    OptionalPropertyWithNullableBuilder instance3 =
+        OptionalPropertyWithNullableBuilder.builder()
+            .notOptional("hello")
+            .optional("world")
+            .build();
+    assertThat(instance3.notOptional()).isEqualTo("hello");
+    assertThat(instance3.optional()).hasValue("world");
+
+    try {
+      OptionalPropertyWithNullableBuilder.builder().build();
+      fail("Expected IllegalStateException for unset non-Optional property");
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @AutoValue
+  @SuppressWarnings("AutoValueImmutableFields")
+  public abstract static class BuilderWithUnprefixedGetters<T extends Comparable<T>> {
+    public abstract ImmutableList<T> list();
+
+    public abstract @Nullable T t();
+
+    @SuppressWarnings("mutable")
+    public abstract int[] ints();
+
+    public abstract int noGetter();
+
+    public static <T extends Comparable<T>> Builder<T> builder() {
+      return new AutoValue_AutoValueJava8Test_BuilderWithUnprefixedGetters.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    public interface Builder<T extends Comparable<T>> {
+      Builder<T> setList(ImmutableList<T> list);
+
+      Builder<T> setT(T t);
+
+      Builder<T> setInts(int[] ints);
+
+      Builder<T> setNoGetter(int x);
+
+      ImmutableList<T> list();
+
+      T t();
+
+      int[] ints();
+
+      BuilderWithUnprefixedGetters<T> build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithUnprefixedGetter() {
+    assumeTrue(javacHandlesTypeAnnotationsCorrectly);
+    ImmutableList<String> names = ImmutableList.of("fred", "jim");
+    int[] ints = {6, 28, 496, 8128, 33550336};
+    int noGetter = -1;
+
+    BuilderWithUnprefixedGetters.Builder<String> builder = BuilderWithUnprefixedGetters.builder();
+    assertThat(builder.t()).isNull();
+    try {
+      builder.list();
+      fail("Attempt to retrieve unset list property should have failed");
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set");
+    }
+    try {
+      builder.ints();
+      fail("Attempt to retrieve unset ints property should have failed");
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessageThat().isEqualTo("Property \"ints\" has not been set");
+    }
+
+    builder.setList(names);
+    assertThat(builder.list()).isSameInstanceAs(names);
+    builder.setInts(ints);
+    assertThat(builder.ints()).isEqualTo(ints);
+    // The array is not cloned by the getter, so the client can modify it (but shouldn't).
+    ints[0] = 0;
+    assertThat(builder.ints()[0]).isEqualTo(0);
+    ints[0] = 6;
+
+    BuilderWithUnprefixedGetters<String> instance = builder.setNoGetter(noGetter).build();
+    assertThat(instance.list()).isSameInstanceAs(names);
+    assertThat(instance.t()).isNull();
+    assertThat(instance.ints()).isEqualTo(ints);
+    assertThat(instance.noGetter()).isEqualTo(noGetter);
+  }
+
+  @AutoValue
+  @SuppressWarnings("AutoValueImmutableFields")
+  public abstract static class BuilderWithPrefixedGetters<T extends Comparable<T>> {
+    public abstract ImmutableList<T> getList();
+
+    public abstract T getT();
+
+    @SuppressWarnings("mutable")
+    public abstract int @Nullable [] getInts();
+
+    public abstract int getNoGetter();
+
+    public static <T extends Comparable<T>> Builder<T> builder() {
+      return new AutoValue_AutoValueJava8Test_BuilderWithPrefixedGetters.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder<T extends Comparable<T>> {
+      public abstract Builder<T> setList(ImmutableList<T> list);
+
+      public abstract Builder<T> setT(T t);
+
+      public abstract Builder<T> setInts(int[] ints);
+
+      public abstract Builder<T> setNoGetter(int x);
+
+      abstract ImmutableList<T> getList();
+
+      abstract T getT();
+
+      abstract int[] getInts();
+
+      public abstract BuilderWithPrefixedGetters<T> build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithPrefixedGetter() {
+    assumeTrue(javacHandlesTypeAnnotationsCorrectly);
+    ImmutableList<String> names = ImmutableList.of("fred", "jim");
+    String name = "sheila";
+    int noGetter = -1;
+
+    BuilderWithPrefixedGetters.Builder<String> builder = BuilderWithPrefixedGetters.builder();
+    assertThat(builder.getInts()).isNull();
+    try {
+      builder.getList();
+      fail("Attempt to retrieve unset list property should have failed");
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set");
+    }
+
+    builder.setList(names);
+    assertThat(builder.getList()).isSameInstanceAs(names);
+    builder.setT(name);
+    assertThat(builder.getInts()).isNull();
+
+    BuilderWithPrefixedGetters<String> instance = builder.setNoGetter(noGetter).build();
+    assertThat(instance.getList()).isSameInstanceAs(names);
+    assertThat(instance.getT()).isEqualTo(name);
+    assertThat(instance.getInts()).isNull();
+    assertThat(instance.getNoGetter()).isEqualTo(noGetter);
+  }
+
+  // This class tests the case where an annotation is both a method annotation and a type
+  // annotation. If we weren't careful, we might emit it twice in the generated code.
+  @AutoValue
+  abstract static class FunkyNullable {
+    @Target({ElementType.METHOD, ElementType.TYPE_USE})
+    @interface Nullable {}
+
+    abstract @Nullable String foo();
+
+    abstract Optional<String> bar();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueJava8Test_FunkyNullable.Builder();
+    }
+
+    @AutoValue.Builder
+    interface Builder {
+      Builder setFoo(@Nullable String foo);
+
+      Builder setBar(@Nullable String bar);
+
+      FunkyNullable build();
+    }
+  }
+
+  @Test
+  public void testFunkyNullable() {
+    FunkyNullable explicitNull = FunkyNullable.builder().setFoo(null).setBar(null).build();
+    FunkyNullable implicitNull = FunkyNullable.builder().build();
+    assertThat(explicitNull).isEqualTo(implicitNull);
+  }
+
+  @AutoValue
+  abstract static class EqualsNullable {
+    @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Nullable {}
+
+    abstract String foo();
+
+    static EqualsNullable create(String foo) {
+      return new AutoValue_AutoValueJava8Test_EqualsNullable(foo);
+    }
+
+    @Override
+    public abstract boolean equals(@Nullable Object x);
+
+    @Override
+    public abstract int hashCode();
+  }
+
+  /**
+   * Tests that a type annotation on the parameter of {@code equals(Object)} is copied into the
+   * implementation class.
+   */
+  @Test
+  public void testEqualsNullable() throws ReflectiveOperationException {
+    EqualsNullable x = EqualsNullable.create("foo");
+    Class<? extends EqualsNullable> implClass = x.getClass();
+    Method equals = implClass.getDeclaredMethod("equals", Object.class);
+    AnnotatedType[] parameterTypes = equals.getAnnotatedParameterTypes();
+    assertThat(parameterTypes[0].isAnnotationPresent(EqualsNullable.Nullable.class)).isTrue();
+  }
+
+  @AutoValue
+  abstract static class AnnotatedTypeParameter<@Nullable T> {
+    abstract @Nullable T thing();
+
+    static <@Nullable T> AnnotatedTypeParameter<T> create(T thing) {
+      return new AutoValue_AutoValueJava8Test_AnnotatedTypeParameter<T>(thing);
+    }
+  }
+
+  /**
+   * Tests that an annotation on a type parameter of an {@code @AutoValue} class is copied to the
+   * implementation class.
+   */
+  @Test
+  public void testTypeAnnotationCopiedToImplementation() {
+    @Nullable String nullableString = "blibby";
+    AnnotatedTypeParameter<@Nullable String> x = AnnotatedTypeParameter.create(nullableString);
+    Class<?> c = x.getClass();
+    assertThat(c.getTypeParameters()).hasLength(1);
+    TypeVariable<?> typeParameter = c.getTypeParameters()[0];
+    assertWithMessage(typeParameter.toString())
+        .that(typeParameter.getAnnotations())
+        .asList()
+        .contains(nullable());
+  }
+
+  @AutoValue
+  abstract static class AnnotatedTypeParameterWithBuilder<@Nullable T> {
+    abstract @Nullable T thing();
+
+    static <@Nullable T> Builder<T> builder() {
+      return new AutoValue_AutoValueJava8Test_AnnotatedTypeParameterWithBuilder.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder<@Nullable T> {
+      abstract Builder<T> setThing(T thing);
+
+      abstract AnnotatedTypeParameterWithBuilder<T> build();
+    }
+  }
+
+  /**
+   * Tests that an annotation on a type parameter of an {@code @AutoValue} builder is copied to the
+   * implementation class.
+   */
+  @Test
+  public void testTypeAnnotationOnBuilderCopiedToImplementation() {
+    AnnotatedTypeParameterWithBuilder.Builder<@Nullable String> builder =
+        AnnotatedTypeParameterWithBuilder.builder();
+    Class<?> c = builder.getClass();
+    assertThat(c.getTypeParameters()).hasLength(1);
+    TypeVariable<?> typeParameter = c.getTypeParameters()[0];
+    assertWithMessage(typeParameter.toString())
+        .that(typeParameter.getAnnotations())
+        .asList()
+        .contains(nullable());
+  }
+
+  // b/127701294
+  @AutoValue
+  abstract static class OptionalOptional {
+    abstract Optional<Optional<String>> maybeJustMaybe();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueJava8Test_OptionalOptional.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder maybeJustMaybe(Optional<String> maybe);
+      abstract OptionalOptional build();
+    }
+  }
+
+  @Test
+  public void testOptionalOptional_empty() {
+    OptionalOptional empty = OptionalOptional.builder().build();
+    assertThat(empty.maybeJustMaybe()).isEmpty();
+  }
+
+  @Test
+  public void testOptionalOptional_ofEmpty() {
+    OptionalOptional ofEmpty = OptionalOptional.builder().maybeJustMaybe(Optional.empty()).build();
+    assertThat(ofEmpty.maybeJustMaybe()).hasValue(Optional.empty());
+  }
+
+  @Test
+  public void testOptionalOptional_ofSomething() {
+    OptionalOptional ofSomething =
+        OptionalOptional.builder().maybeJustMaybe(Optional.of("foo")).build();
+    assertThat(ofSomething.maybeJustMaybe()).hasValue(Optional.of("foo"));
+  }
+
+  @AutoValue
+  abstract static class OptionalExtends {
+    abstract Optional<? extends Predicate<? super Integer>> predicate();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueJava8Test_OptionalExtends.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder setPredicate(Predicate<? super Integer> predicate);
+      abstract OptionalExtends build();
+    }
+  }
+
+  @Test
+  public void testOptionalExtends() {
+    Predicate<Number> predicate = n -> n.toString().equals("0");
+    OptionalExtends t = OptionalExtends.builder().setPredicate(predicate).build();
+    assertThat(t.predicate()).hasValue(predicate);
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueNotEclipseTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueNotEclipseTest.java
new file mode 100644
index 0000000..4d008c7
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueNotEclipseTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import static com.google.common.truth.Truth8.assertThat;
+
+import java.util.Optional;
+import javax.annotation.Nullable;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Like {@link AutoValueTest}, but with code that doesn't build with at least some versions of
+ * Eclipse, and should therefore not be included in {@link CompileWithEclipseTest}. (The latter is
+ * not currently present in the open-source build.)
+ */
+@RunWith(JUnit4.class)
+public class AutoValueNotEclipseTest {
+  // This produced the following error with JDT 4.6:
+  // Internal compiler error: java.lang.Exception: java.lang.IllegalArgumentException: element
+  // public abstract B setOptional(T)  is not a member of the containing type
+  // com.google.auto.value.AutoValueTest.ConcreteOptional.Builder nor any of its superclasses at
+  // org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:169)
+  interface AbstractOptional<T> {
+    Optional<T> optional();
+
+    interface Builder<T, B extends Builder<T, B>> {
+      B setOptional(@Nullable T t);
+    }
+  }
+
+  @AutoValue
+  abstract static class ConcreteOptional implements AbstractOptional<String> {
+    static Builder builder() {
+      return new AutoValue_AutoValueNotEclipseTest_ConcreteOptional.Builder();
+    }
+
+    @AutoValue.Builder
+    interface Builder extends AbstractOptional.Builder<String, Builder> {
+      ConcreteOptional build();
+    }
+  }
+
+  @Test
+  public void genericOptionalOfNullable() {
+    ConcreteOptional empty = ConcreteOptional.builder().build();
+    assertThat(empty.optional()).isEmpty();
+    ConcreteOptional notEmpty = ConcreteOptional.builder().setOptional("foo").build();
+    assertThat(notEmpty.optional()).hasValue("foo");
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueTest.java
new file mode 100644
index 0000000..346bc53
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/AutoValueTest.java
@@ -0,0 +1,3420 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ComparisonChain;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedMap;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.ImmutableTable;
+import com.google.common.testing.EqualsTester;
+import com.google.common.testing.SerializableTester;
+import java.io.ObjectStreamClass;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.math.BigInteger;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import javax.annotation.Nullable;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class AutoValueTest {
+  private static boolean omitIdentifiers;
+
+  @BeforeClass
+  public static void initOmitIdentifiers() {
+    omitIdentifiers = System.getProperty("OmitIdentifiers") != null;
+  }
+
+  @AutoValue
+  abstract static class Simple {
+    public abstract String publicString();
+
+    protected abstract int protectedInt();
+
+    abstract Map<String, Long> packageMap();
+
+    public static Simple create(String s, int i, Map<String, Long> m) {
+      return new AutoValue_AutoValueTest_Simple(s, i, m);
+    }
+  }
+
+  @Test
+  public void testSimple() throws Exception {
+    Simple instance1a = Simple.create("example", 23, ImmutableMap.of("twenty-three", 23L));
+    Simple instance1b = Simple.create("example", 23, ImmutableMap.of("twenty-three", 23L));
+    Simple instance2 = Simple.create("", 0, ImmutableMap.<String, Long>of());
+    assertEquals("example", instance1a.publicString());
+    assertEquals(23, instance1a.protectedInt());
+    assertEquals(ImmutableMap.of("twenty-three", 23L), instance1a.packageMap());
+    MoreObjects.ToStringHelper toStringHelper = MoreObjects.toStringHelper(Simple.class);
+    toStringHelper.add("publicString", "example");
+    toStringHelper.add("protectedInt", 23);
+    toStringHelper.add("packageMap", ImmutableMap.of("twenty-three", 23L));
+    String expectedString =
+        omitIdentifiers ? "{example, 23, {twenty-three=23}}" : toStringHelper.toString();
+    assertThat(instance1a.toString()).isEqualTo(expectedString);
+    new EqualsTester()
+        .addEqualityGroup(instance1a, instance1b)
+        .addEqualityGroup(instance2)
+        .testEquals();
+  }
+
+  @AutoValue
+  abstract static class Empty {
+    public static Empty create() {
+      return new AutoValue_AutoValueTest_Empty();
+    }
+  }
+
+  @Test
+  public void testEmpty() throws Exception {
+    Empty instance = Empty.create();
+    String expectedString = omitIdentifiers ? "{}" : "Empty{}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+    assertEquals(instance, instance);
+    assertEquals(instance, Empty.create());
+  }
+
+  @AutoValue
+  abstract static class SimpleWithGetters {
+    abstract int getFoo();
+
+    abstract boolean isBar();
+
+    abstract boolean getOtherBar();
+
+    abstract String getPackage(); // package is a reserved word
+
+    abstract String getPackage0();
+
+    abstract String getHTMLPage();
+
+    static SimpleWithGetters create(
+        int foo, boolean bar, boolean otherBar, String pkg, String pkg0, String htmlPage) {
+      return new AutoValue_AutoValueTest_SimpleWithGetters(foo, bar, otherBar, pkg, pkg0, htmlPage);
+    }
+  }
+
+  @Test
+  public void testGetters() {
+    SimpleWithGetters instance = SimpleWithGetters.create(23, true, false, "foo", "bar", "<html>");
+    String expectedString =
+        omitIdentifiers
+            ? "{23, true, false, foo, bar, <html>}"
+            : "SimpleWithGetters{"
+                + "foo=23, bar=true, otherBar=false, package=foo, package0=bar, HTMLPage=<html>}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+  }
+
+  @AutoValue
+  abstract static class NotAllGetters {
+    abstract int getFoo();
+
+    abstract boolean bar();
+
+    static NotAllGetters create(int foo, boolean bar) {
+      return new AutoValue_AutoValueTest_NotAllGetters(foo, bar);
+    }
+  }
+
+  @Test
+  public void testNotGetters() {
+    NotAllGetters instance = NotAllGetters.create(23, true);
+    String expectedString = omitIdentifiers ? "{23, true}" : "NotAllGetters{getFoo=23, bar=true}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+  }
+
+  @AutoValue
+  abstract static class StrangeGetters {
+    abstract int get1st();
+    abstract int get_1st(); // by default we'll use _1st where identifiers are needed, so foil that.
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder set1st(int x);
+      abstract Builder set_1st(int x);
+      abstract StrangeGetters build();
+    }
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_StrangeGetters.Builder();
+    }
+  }
+
+  @Test
+  public void testStrangeGetters() {
+    StrangeGetters instance = StrangeGetters.builder().set1st(17).set_1st(23).build();
+    String expectedString = omitIdentifiers ? "{17, 23}" : "StrangeGetters{1st=17, _1st=23}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+  }
+
+  @AutoValue
+  abstract static class GettersAndConcreteNonGetters {
+    abstract int getFoo();
+
+    @SuppressWarnings("mutable")
+    abstract byte[] getBytes();
+
+    boolean hasNoBytes() {
+      return getBytes().length == 0;
+    }
+
+    static GettersAndConcreteNonGetters create(int foo, byte[] bytes) {
+      return new AutoValue_AutoValueTest_GettersAndConcreteNonGetters(foo, bytes);
+    }
+  }
+
+  @Test
+  public void testGettersAndConcreteNonGetters() {
+    GettersAndConcreteNonGetters instance = GettersAndConcreteNonGetters.create(23, new byte[] {1});
+    assertFalse(instance.hasNoBytes());
+    String expectedString =
+        omitIdentifiers ? "{23, [1]}" : "GettersAndConcreteNonGetters{foo=23, bytes=[1]}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+  }
+
+  @AutoValue
+  abstract static class ClassProperty {
+    abstract Class<?> theClass();
+
+    static ClassProperty create(Class<?> theClass) {
+      return new AutoValue_AutoValueTest_ClassProperty(theClass);
+    }
+  }
+
+  @Test
+  public void testClassProperty() {
+    ClassProperty instance = ClassProperty.create(Thread.class);
+    assertThat(instance.theClass()).isEqualTo(Thread.class);
+
+    try {
+      ClassProperty.create(null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @AutoValue
+  abstract static class ClassPropertyWithBuilder {
+    abstract Class<? extends Number> numberClass();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_ClassPropertyWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder setNumberClass(Class<? extends Number> x);
+
+      abstract ClassPropertyWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testClassPropertyWithBuilder() {
+    ClassPropertyWithBuilder instance =
+        ClassPropertyWithBuilder.builder().setNumberClass(Integer.class).build();
+    assertThat(instance.numberClass()).isEqualTo(Integer.class);
+
+    try {
+      ClassPropertyWithBuilder.builder().build();
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+
+    try {
+      ClassPropertyWithBuilder.builder().setNumberClass(null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @AutoValue
+  public abstract static class Serialize implements Serializable {
+    public abstract int integer();
+
+    public abstract String string();
+
+    public abstract BigInteger bigInteger();
+
+    public static Serialize create(int integer, String string, BigInteger bigInteger) {
+      return new AutoValue_AutoValueTest_Serialize(integer, string, bigInteger);
+    }
+  }
+
+  @Test
+  public void testSerialize() throws Exception {
+    Serialize instance = Serialize.create(23, "23", BigInteger.valueOf(23));
+    assertEquals(instance, SerializableTester.reserialize(instance));
+  }
+
+  @AutoValue
+  public abstract static class SerializeWithVersionUID implements Serializable {
+    private static final long serialVersionUID = 4294967297L;
+
+    public abstract int integer();
+
+    public abstract String string();
+
+    public static SerializeWithVersionUID create(int integer, String string) {
+      return new AutoValue_AutoValueTest_SerializeWithVersionUID(integer, string);
+    }
+  }
+
+  @Test
+  public void testSerializeWithVersionUID() throws Exception {
+    SerializeWithVersionUID instance = SerializeWithVersionUID.create(23, "23");
+    assertEquals(instance, SerializableTester.reserialize(instance));
+
+    long serialVersionUID =
+        ObjectStreamClass.lookup(AutoValue_AutoValueTest_SerializeWithVersionUID.class)
+            .getSerialVersionUID();
+    assertEquals(4294967297L, serialVersionUID);
+  }
+
+  @AutoValue
+  abstract static class LongProperty {
+    public abstract long longProperty();
+
+    public static LongProperty create(long longProperty) {
+      return new AutoValue_AutoValueTest_LongProperty(longProperty);
+    }
+  }
+
+  @Test
+  public void testLongHashCode() {
+    long longValue = 0x1234567887654321L;
+    LongProperty longProperty = LongProperty.create(longValue);
+    assertEquals(singlePropertyHash(longValue), longProperty.hashCode());
+  }
+
+  @AutoValue
+  abstract static class IntProperty {
+    public abstract int intProperty();
+
+    public static IntProperty create(int intProperty) {
+      return new AutoValue_AutoValueTest_IntProperty(intProperty);
+    }
+  }
+
+  @Test
+  public void testIntHashCode() {
+    int intValue = 0x12345678;
+    IntProperty intProperty = IntProperty.create(intValue);
+    assertEquals(singlePropertyHash(intValue), intProperty.hashCode());
+  }
+
+  @AutoValue
+  abstract static class ShortProperty {
+    public abstract short shortProperty();
+
+    public static ShortProperty create(short shortProperty) {
+      return new AutoValue_AutoValueTest_ShortProperty(shortProperty);
+    }
+  }
+
+  @Test
+  public void testShortHashCode() {
+    short shortValue = 0x1234;
+    ShortProperty shortProperty = ShortProperty.create(shortValue);
+    assertEquals(singlePropertyHash(shortValue), shortProperty.hashCode());
+  }
+
+  @AutoValue
+  abstract static class ByteProperty {
+    public abstract byte byteProperty();
+
+    public static ByteProperty create(byte byteProperty) {
+      return new AutoValue_AutoValueTest_ByteProperty(byteProperty);
+    }
+  }
+
+  @Test
+  public void testByteHashCode() {
+    byte byteValue = 123;
+    ByteProperty byteProperty = ByteProperty.create(byteValue);
+    assertEquals(singlePropertyHash(byteValue), byteProperty.hashCode());
+  }
+
+  @AutoValue
+  abstract static class CharProperty {
+    public abstract char charProperty();
+
+    public static CharProperty create(char charProperty) {
+      return new AutoValue_AutoValueTest_CharProperty(charProperty);
+    }
+  }
+
+  @Test
+  public void testCharHashCode() {
+    char charValue = 123;
+    CharProperty charProperty = CharProperty.create(charValue);
+    assertEquals(singlePropertyHash(charValue), charProperty.hashCode());
+  }
+
+  @AutoValue
+  abstract static class BooleanProperty {
+    public abstract boolean booleanProperty();
+
+    public static BooleanProperty create(boolean booleanProperty) {
+      return new AutoValue_AutoValueTest_BooleanProperty(booleanProperty);
+    }
+  }
+
+  @Test
+  public void testBooleanHashCode() {
+    for (boolean booleanValue : new boolean[] {false, true}) {
+      BooleanProperty booleanProperty = BooleanProperty.create(booleanValue);
+      assertEquals(singlePropertyHash(booleanValue), booleanProperty.hashCode());
+    }
+  }
+
+  @AutoValue
+  abstract static class FloatProperty {
+    public abstract float floatProperty();
+
+    public static FloatProperty create(float floatProperty) {
+      return new AutoValue_AutoValueTest_FloatProperty(floatProperty);
+    }
+  }
+
+  @Test
+  public void testFloatHashCode() {
+    float floatValue = 123456f;
+    FloatProperty floatProperty = FloatProperty.create(floatValue);
+    assertEquals(singlePropertyHash(floatValue), floatProperty.hashCode());
+  }
+
+  @AutoValue
+  abstract static class DoubleProperty {
+    public abstract double doubleProperty();
+
+    public static DoubleProperty create(double doubleProperty) {
+      return new AutoValue_AutoValueTest_DoubleProperty(doubleProperty);
+    }
+  }
+
+  @Test
+  public void testDoubleHashCode() {
+    double doubleValue = 1234567890123456d;
+    DoubleProperty doubleProperty = DoubleProperty.create(doubleValue);
+    assertEquals(singlePropertyHash(doubleValue), doubleProperty.hashCode());
+  }
+
+  @Test
+  public void testFloatingEquality() {
+    FloatProperty floatZero = FloatProperty.create(0.0f);
+    FloatProperty floatMinusZero = FloatProperty.create(-0.0f);
+    FloatProperty floatNaN = FloatProperty.create(Float.NaN);
+    DoubleProperty doubleZero = DoubleProperty.create(0.0);
+    DoubleProperty doubleMinusZero = DoubleProperty.create(-0.0);
+    DoubleProperty doubleNaN = DoubleProperty.create(Double.NaN);
+    new EqualsTester()
+        .addEqualityGroup(floatZero)
+        .addEqualityGroup(floatMinusZero)
+        .addEqualityGroup(floatNaN)
+        .addEqualityGroup(doubleZero)
+        .addEqualityGroup(doubleMinusZero)
+        .addEqualityGroup(doubleNaN)
+        .testEquals();
+  }
+
+  private static int singlePropertyHash(Object property) {
+    return 1000003 ^ property.hashCode();
+  }
+
+  abstract static class Super {
+    public abstract Object superObject();
+
+    public abstract boolean superBoolean();
+    // The above two are out of alphabetical order to test EclipseHack.
+  }
+
+  @AutoValue
+  public abstract static class Sub extends Super {
+    public abstract int subInt();
+
+    public static Sub create(Object superObject, boolean superBoolean, int subInt) {
+      return new AutoValue_AutoValueTest_Sub(superObject, superBoolean, subInt);
+    }
+  }
+
+  // The @AutoValue class can inherit abstract methods from its superclass.
+  @Test
+  public void testSuperclass() throws Exception {
+    Sub instance = Sub.create("blim", true, 1729);
+    assertEquals("blim", instance.superObject());
+    assertTrue(instance.superBoolean());
+    assertEquals(1729, instance.subInt());
+    assertEquals(instance, instance);
+    assertEqualsNullIsFalse(instance);
+  }
+
+  abstract static class NonPublicSuper {
+    abstract Object superObject();
+  }
+
+  // The properties in this subclass are not in alphabetical order, which enables us to test that
+  // everything works correctly when Eclipse sorts them into the order
+  // [superObject, subInt, subString], since it sorts per class.
+  @AutoValue
+  abstract static class NonPublicSub extends NonPublicSuper {
+    abstract String subString();
+
+    abstract int subInt();
+
+    static NonPublicSub create(Object superObject, String subString, int subInt) {
+      return new AutoValue_AutoValueTest_NonPublicSub(superObject, subString, subInt);
+    }
+  }
+
+  @Test
+  public void testNonPublicInheritedGetters() throws Exception {
+    NonPublicSub instance = NonPublicSub.create("blim", "blam", 1729);
+    assertEquals("blim", instance.superObject());
+    assertEquals("blam", instance.subString());
+    assertEquals(1729, instance.subInt());
+    assertEquals(instance, instance);
+    assertEqualsNullIsFalse(instance);
+  }
+
+  @SuppressWarnings("ObjectEqualsNull")
+  private void assertEqualsNullIsFalse(Object instance) {
+    assertFalse(instance.equals(null));
+  }
+
+  @AutoValue
+  abstract static class NullableProperties {
+    @Nullable
+    abstract String nullableString();
+
+    abstract int randomInt();
+
+    static NullableProperties create(@Nullable String nullableString, int randomInt) {
+      return new AutoValue_AutoValueTest_NullableProperties(nullableString, randomInt);
+    }
+  }
+
+  @Test
+  public void testNullablePropertiesCanBeNull() {
+    NullableProperties instance = NullableProperties.create(null, 23);
+    assertNull(instance.nullableString());
+    assertThat(instance.randomInt()).isEqualTo(23);
+    String expectedString =
+        omitIdentifiers ? "{null, 23}" : "NullableProperties{nullableString=null, randomInt=23}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+  }
+
+  @AutoAnnotation
+  static Nullable nullable() {
+    return new AutoAnnotation_AutoValueTest_nullable();
+  }
+
+  @Test
+  public void testNullablePropertyConstructorParameterIsNullable() throws NoSuchMethodException {
+    Constructor<?> constructor =
+        AutoValue_AutoValueTest_NullableProperties.class.getDeclaredConstructor(
+            String.class, int.class);
+    assertThat(constructor.getParameterAnnotations()[0]).asList().contains(nullable());
+  }
+
+  @AutoValue
+  abstract static class AlternativeNullableProperties {
+    @interface Nullable {}
+
+    @AlternativeNullableProperties.Nullable
+    abstract String nullableString();
+
+    abstract int randomInt();
+
+    static AlternativeNullableProperties create(@Nullable String nullableString, int randomInt) {
+      return new AutoValue_AutoValueTest_AlternativeNullableProperties(nullableString, randomInt);
+    }
+  }
+
+  @Test
+  public void testNullableCanBeFromElsewhere() throws Exception {
+    AlternativeNullableProperties instance = AlternativeNullableProperties.create(null, 23);
+    assertNull(instance.nullableString());
+    assertThat(instance.randomInt()).isEqualTo(23);
+    String expectedString =
+        omitIdentifiers
+            ? "{null, 23}"
+            : "AlternativeNullableProperties{nullableString=null, randomInt=23}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+  }
+
+  @AutoValue
+  abstract static class NonNullableProperties {
+    abstract String nonNullableString();
+
+    abstract int randomInt();
+
+    static NonNullableProperties create(String nonNullableString, int randomInt) {
+      return new AutoValue_AutoValueTest_NonNullableProperties(nonNullableString, randomInt);
+    }
+  }
+
+  @Test
+  public void testNonNullablePropertiesCannotBeNull() throws Exception {
+    try {
+      NonNullableProperties.create(null, 23);
+      fail("Object creation succeeded but should not have");
+    } catch (NullPointerException expected) {
+    }
+    NonNullableProperties instance = NonNullableProperties.create("nonnull", 23);
+    assertEquals("nonnull", instance.nonNullableString());
+    assertEquals(23, instance.randomInt());
+  }
+
+  @AutoValue
+  abstract static class NullableListProperties {
+    @Nullable
+    abstract ImmutableList<String> nullableStringList();
+
+    static NullableListProperties create(@Nullable ImmutableList<String> nullableStringList) {
+      return new AutoValue_AutoValueTest_NullableListProperties(nullableStringList);
+    }
+  }
+
+  @Test
+  public void testNullableListPropertiesCanBeNonNull() {
+    NullableListProperties instance = NullableListProperties.create(ImmutableList.of("foo", "bar"));
+    assertEquals(ImmutableList.of("foo", "bar"), instance.nullableStringList());
+  }
+
+  @Test
+  public void testNullableListPropertiesCanBeNull() {
+    NullableListProperties instance = NullableListProperties.create(null);
+    assertNull(instance.nullableStringList());
+  }
+
+  @AutoValue
+  abstract static class NullableListPropertiesWithBuilder {
+    @Nullable
+    abstract ImmutableList<String> nullableStringList();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_NullableListPropertiesWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    interface Builder {
+      Builder nullableStringList(List<String> nullableStringList);
+
+      NullableListPropertiesWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testNullableListPropertiesWithBuilderCanBeNonNull() {
+    NullableListPropertiesWithBuilder instance =
+        NullableListPropertiesWithBuilder.builder()
+            .nullableStringList(ImmutableList.of("foo", "bar"))
+            .build();
+    assertEquals(ImmutableList.of("foo", "bar"), instance.nullableStringList());
+  }
+
+  @Test
+  public void testNullableListPropertiesWithBuilderCanBeUnset() {
+    NullableListPropertiesWithBuilder instance =
+        NullableListPropertiesWithBuilder.builder().build();
+    assertNull(instance.nullableStringList());
+  }
+
+  @Test
+  public void testNullableListPropertiesWithBuilderCanBeNull() {
+    NullableListPropertiesWithBuilder instance =
+        NullableListPropertiesWithBuilder.builder().nullableStringList(null).build();
+    assertNull(instance.nullableStringList());
+  }
+
+  static class Nested {
+    @AutoValue
+    abstract static class Doubly {
+      @Nullable
+      abstract String nullableString();
+
+      abstract int randomInt();
+
+      static Doubly create(String nullableString, int randomInt) {
+        return new AutoValue_AutoValueTest_Nested_Doubly(nullableString, randomInt);
+      }
+    }
+  }
+
+  @Test
+  public void testDoublyNestedClass() throws Exception {
+    Nested.Doubly instance = Nested.Doubly.create(null, 23);
+    assertNull(instance.nullableString());
+    assertThat(instance.randomInt()).isEqualTo(23);
+    String expectedString =
+        omitIdentifiers ? "{null, 23}" : "Doubly{nullableString=null, randomInt=23}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+  }
+
+  static interface NestedInInterface {
+    @AutoValue
+    abstract class Doubly {
+      abstract String string();
+
+      abstract Map<String, Integer> map();
+
+      static Doubly create(String string, Map<String, Integer> map) {
+        return new AutoValue_AutoValueTest_NestedInInterface_Doubly(string, map);
+      }
+    }
+  }
+
+  @Test
+  public void testClassNestedInInterface() throws Exception {
+    Map<String, Integer> map = ImmutableMap.of("vingt-et-un", 21);
+    NestedInInterface.Doubly instance = NestedInInterface.Doubly.create("foo", map);
+    assertEquals("foo", instance.string());
+    assertEquals(map, instance.map());
+  }
+
+  @AutoValue
+  abstract static class NullableNonNullable {
+    @Nullable
+    abstract String nullableString();
+
+    @Nullable
+    abstract String otherNullableString();
+
+    abstract String nonNullableString();
+
+    static NullableNonNullable create(
+        String nullableString, String otherNullableString, String nonNullableString) {
+      return new AutoValue_AutoValueTest_NullableNonNullable(
+          nullableString, otherNullableString, nonNullableString);
+    }
+  }
+
+  @Test
+  public void testEqualsWithNullable() throws Exception {
+    NullableNonNullable everythingNull =
+        NullableNonNullable.create(null, null, "nonNullableString");
+    NullableNonNullable somethingNull =
+        NullableNonNullable.create(null, "otherNullableString", "nonNullableString");
+    NullableNonNullable nothingNull =
+        NullableNonNullable.create("nullableString", "otherNullableString", "nonNullableString");
+    NullableNonNullable nothingNullAgain =
+        NullableNonNullable.create("nullableString", "otherNullableString", "nonNullableString");
+    new EqualsTester()
+        .addEqualityGroup(everythingNull)
+        .addEqualityGroup(somethingNull)
+        .addEqualityGroup(nothingNull, nothingNullAgain)
+        .testEquals();
+  }
+
+  @AutoValue
+  abstract static class GenericProperties {
+    abstract Map<String, Integer> simpleMap();
+
+    abstract Map<String, Map<String, Integer>> hairyMap();
+
+    static GenericProperties create(
+        Map<String, Integer> simpleMap, Map<String, Map<String, Integer>> hairyMap) {
+      return new AutoValue_AutoValueTest_GenericProperties(simpleMap, hairyMap);
+    }
+  }
+
+  @Test
+  public void testGenericProperties() throws Exception {
+    GenericProperties instance1 =
+        GenericProperties.create(
+            ImmutableMap.of("twenty-three", 23),
+            ImmutableMap.of("very", (Map<String, Integer>) ImmutableMap.of("hairy", 17)));
+    GenericProperties instance2 =
+        GenericProperties.create(
+            ImmutableMap.of("seventeen", 17),
+            ImmutableMap.of("very", (Map<String, Integer>) ImmutableMap.of("hairy", 23)));
+    new EqualsTester().addEqualityGroup(instance1).addEqualityGroup(instance2).testEquals();
+    assertEquals(
+        ImmutableMap.of("very", (Map<String, Integer>) ImmutableMap.of("hairy", 23)),
+        instance2.hairyMap());
+  }
+
+  @AutoValue
+  abstract static class GenericClass<K, V> {
+    abstract K key();
+
+    abstract Map<K, V> map();
+
+    static <K, V> GenericClass<K, V> create(K key, Map<K, V> map) {
+      return new AutoValue_AutoValueTest_GenericClass<K, V>(key, map);
+    }
+  }
+
+  @Test
+  public void testGenericClass() throws Exception {
+    GenericClass<String, Boolean> instance =
+        GenericClass.create("whatever", ImmutableMap.of("no", false));
+    assertEquals(instance, instance);
+    assertEquals("whatever", instance.key());
+    assertEquals(ImmutableMap.of("no", false), instance.map());
+  }
+
+  @AutoValue
+  abstract static class GenericClassSimpleBounds<K extends Number, V extends K> {
+    abstract K key();
+
+    abstract Map<K, V> map();
+
+    static <K extends Number, V extends K> GenericClassSimpleBounds<K, V> create(
+        K key, Map<K, V> map) {
+      return new AutoValue_AutoValueTest_GenericClassSimpleBounds<K, V>(key, map);
+    }
+  }
+
+  @Test
+  public void testGenericClassWithSimpleBounds() throws Exception {
+    GenericClassSimpleBounds<Integer, Integer> instance =
+        GenericClassSimpleBounds.create(23, ImmutableMap.of(17, 23));
+    assertEquals(instance, instance);
+    assertEquals(23, (int) instance.key());
+    assertEquals(ImmutableMap.of(17, 23), instance.map());
+  }
+
+  @AutoValue
+  abstract static class GenericClassHairyBounds<K extends List<V> & Comparable<K>, V> {
+    abstract K key();
+
+    abstract Map<K, V> map();
+
+    static <K extends List<V> & Comparable<K>, V> GenericClassHairyBounds<K, V> create(
+        K key, Map<K, V> map) {
+      return new AutoValue_AutoValueTest_GenericClassHairyBounds<K, V>(key, map);
+    }
+  }
+
+  @Test
+  public void testGenericClassWithHairyBounds() throws Exception {
+    class ComparableList<E> extends ArrayList<E> implements Comparable<ComparableList<E>> {
+      @Override
+      public int compareTo(ComparableList<E> list) {
+        throw new UnsupportedOperationException();
+      }
+    }
+    ComparableList<String> emptyList = new ComparableList<String>();
+    GenericClassHairyBounds<ComparableList<String>, String> instance =
+        GenericClassHairyBounds.create(emptyList, ImmutableMap.of(emptyList, "23"));
+    assertEquals(instance, instance);
+    assertEquals(emptyList, instance.key());
+    assertEquals(ImmutableMap.of(emptyList, "23"), instance.map());
+  }
+
+  interface Mergeable<M extends Mergeable<M>> {
+    M merge(M other);
+  }
+
+  @AutoValue
+  abstract static class Delta<M extends Mergeable<M>> {
+    abstract M meta();
+
+    static <M extends Mergeable<M>> Delta<M> create(M meta) {
+      return new AutoValue_AutoValueTest_Delta<M>(meta);
+    }
+  }
+
+  @Test
+  public void testRecursiveGeneric() {
+    class MergeableImpl implements Mergeable<MergeableImpl> {
+      @Override
+      public MergeableImpl merge(MergeableImpl other) {
+        return this;
+      }
+    }
+    MergeableImpl mergeable = new MergeableImpl();
+    Delta<MergeableImpl> instance = Delta.create(mergeable);
+    assertSame(mergeable, instance.meta());
+  }
+
+  static class NodeType<O> {}
+
+  abstract static class NodeExpressionClass<O> {
+    abstract NodeType<O> getType();
+  }
+
+  @AutoValue
+  abstract static class NotNodeExpression extends NodeExpressionClass<Boolean> {
+    static NotNodeExpression create() {
+      return new AutoValue_AutoValueTest_NotNodeExpression(new NodeType<Boolean>());
+    }
+  }
+
+  interface NodeExpressionInterface<O> {
+    NodeType<O> getType();
+  }
+
+  @AutoValue
+  abstract static class NotNodeExpression2 implements NodeExpressionInterface<Boolean> {
+    static NotNodeExpression2 create() {
+      return new AutoValue_AutoValueTest_NotNodeExpression2(new NodeType<Boolean>());
+    }
+  }
+
+  @Test
+  public void testConcreteWithGenericParent() {
+    NotNodeExpression instance = NotNodeExpression.create();
+    assertThat(instance.getType()).isInstanceOf(NodeType.class);
+    NotNodeExpression2 instance2 = NotNodeExpression2.create();
+    assertThat(instance2.getType()).isInstanceOf(NodeType.class);
+  }
+
+  @AutoValue
+  abstract static class ExplicitToString {
+    abstract String string();
+
+    static ExplicitToString create(String string) {
+      return new AutoValue_AutoValueTest_ExplicitToString(string);
+    }
+
+    @Override
+    public String toString() {
+      return "Bazinga{" + string() + "}";
+    }
+  }
+
+  // We should not generate a toString() method if there already is a non-default one.
+  @Test
+  public void testExplicitToString() throws Exception {
+    ExplicitToString instance = ExplicitToString.create("foo");
+    assertEquals("Bazinga{foo}", instance.toString());
+  }
+
+  abstract static class NonAutoExplicitToString {
+    abstract String string();
+
+    @Override
+    public String toString() {
+      return "Bazinga{" + string() + "}";
+    }
+  }
+
+  @AutoValue
+  abstract static class InheritedExplicitToString extends NonAutoExplicitToString {
+    static InheritedExplicitToString create(String string) {
+      return new AutoValue_AutoValueTest_InheritedExplicitToString(string);
+    }
+  }
+
+  // We should not generate a toString() method if we already inherit a non-default one.
+  @Test
+  public void testInheritedExplicitToString() throws Exception {
+    InheritedExplicitToString instance = InheritedExplicitToString.create("foo");
+    assertEquals("Bazinga{foo}", instance.toString());
+  }
+
+  @AutoValue
+  abstract static class AbstractToString {
+    abstract String string();
+
+    static AbstractToString create(String string) {
+      return new AutoValue_AutoValueTest_AbstractToString(string);
+    }
+
+    @Override
+    public abstract String toString();
+  }
+
+  // We should generate a toString() method if the parent class has an abstract one.
+  // That allows users to cancel a toString() from a parent class if they want.
+  @Test
+  public void testAbstractToString() throws Exception {
+    AbstractToString instance = AbstractToString.create("foo");
+    String expectedString = omitIdentifiers ? "{foo}" : "AbstractToString{string=foo}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+  }
+
+  abstract static class NonAutoAbstractToString {
+    abstract String string();
+
+    @Override
+    public abstract String toString();
+  }
+
+  @AutoValue
+  abstract static class SubAbstractToString extends NonAutoAbstractToString {
+    static SubAbstractToString create(String string) {
+      return new AutoValue_AutoValueTest_SubAbstractToString(string);
+    }
+  }
+
+  // We should generate a toString() method if the parent class inherits an abstract one.
+  @Test
+  public void testInheritedAbstractToString() throws Exception {
+    SubAbstractToString instance = SubAbstractToString.create("foo");
+    String expectedString = omitIdentifiers ? "{foo}" : "SubAbstractToString{string=foo}";
+    assertThat(instance.toString()).isEqualTo(expectedString);
+  }
+
+  @AutoValue
+  abstract static class ExplicitHashCode {
+    abstract String string();
+
+    static ExplicitHashCode create(String string) {
+      return new AutoValue_AutoValueTest_ExplicitHashCode(string);
+    }
+
+    @Override
+    public int hashCode() {
+      return 1234;
+    }
+  }
+
+  @Test
+  public void testExplicitHashCode() throws Exception {
+    ExplicitHashCode instance = ExplicitHashCode.create("foo");
+    assertEquals(1234, instance.hashCode());
+  }
+
+  @AutoValue
+  @SuppressWarnings("EqualsHashCode")
+  abstract static class ExplicitEquals {
+    int equalsCount;
+
+    static ExplicitEquals create() {
+      return new AutoValue_AutoValueTest_ExplicitEquals();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      equalsCount++;
+      return super.equals(o);
+    }
+  }
+
+  @SuppressWarnings("SelfEquals")
+  @Test
+  public void testExplicitEquals() throws Exception {
+    ExplicitEquals instance = ExplicitEquals.create();
+    assertEquals(0, instance.equalsCount);
+    assertTrue(instance.equals(instance));
+    assertEquals(1, instance.equalsCount);
+    Method equals = instance.getClass().getMethod("equals", Object.class);
+    assertNotSame(ExplicitEquals.class, instance.getClass());
+    assertSame(ExplicitEquals.class, equals.getDeclaringClass());
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface MyAnnotation {
+    String value();
+  }
+
+  @AutoAnnotation
+  private static MyAnnotation myAnnotation(String value) {
+    return new AutoAnnotation_AutoValueTest_myAnnotation(value);
+  }
+
+  @AutoValue
+  abstract static class PrimitiveArrays {
+    @SuppressWarnings("mutable")
+    abstract boolean[] booleans();
+
+    @SuppressWarnings("mutable")
+    @Nullable
+    abstract int[] ints();
+
+    static PrimitiveArrays create(boolean[] booleans, int[] ints) {
+      // Real code would likely clone these parameters, but here we want to check that the
+      // generated constructor rejects a null value for booleans.
+      return new AutoValue_AutoValueTest_PrimitiveArrays(booleans, ints);
+    }
+  }
+
+  @Test
+  public void testPrimitiveArrays() {
+    PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], new int[0]);
+    boolean[] booleans = {false, true, true, false};
+    int[] ints = {6, 28, 496, 8128, 33550336};
+    PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), ints.clone());
+    PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), ints.clone());
+    new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();
+    // EqualsTester also exercises hashCode(). We clone the arrays above to ensure that using the
+    // default Object.hashCode() will fail.
+
+    String expectedString =
+        omitIdentifiers
+            ? ("{" + Arrays.toString(booleans) + ", " + Arrays.toString(ints) + "}")
+            : ("PrimitiveArrays{booleans="
+                + Arrays.toString(booleans)
+                + ", "
+                + "ints="
+                + Arrays.toString(ints)
+                + "}");
+    assertThat(object1.toString()).isEqualTo(expectedString);
+    assertThat(object1.ints()).isSameInstanceAs(object1.ints());
+  }
+
+  @Test
+  public void testNullablePrimitiveArrays() {
+    PrimitiveArrays object0 = PrimitiveArrays.create(new boolean[0], null);
+    boolean[] booleans = {false, true, true, false};
+    PrimitiveArrays object1 = PrimitiveArrays.create(booleans.clone(), null);
+    PrimitiveArrays object2 = PrimitiveArrays.create(booleans.clone(), null);
+    new EqualsTester().addEqualityGroup(object1, object2).addEqualityGroup(object0).testEquals();
+
+    String expectedString =
+        omitIdentifiers
+            ? ("{" + Arrays.toString(booleans) + ", null}")
+            : ("PrimitiveArrays{booleans=" + Arrays.toString(booleans) + ", " + "ints=null}");
+    assertThat(object1.toString()).isEqualTo(expectedString);
+
+    assertThat(object1.booleans()).isSameInstanceAs(object1.booleans());
+    assertThat(object1.booleans()).isEqualTo(booleans);
+    object1.booleans()[0] ^= true;
+    assertThat(object1.booleans()).isNotEqualTo(booleans);
+  }
+
+  @Test
+  public void testNotNullablePrimitiveArrays() {
+    try {
+      PrimitiveArrays.create(null, new int[0]);
+      fail("Construction with null value for non-@Nullable array should have failed");
+    } catch (NullPointerException e) {
+      if (omitIdentifiers) {
+        assertThat(e).hasMessageThat().isNull();
+      } else {
+        assertThat(e).hasMessageThat().contains("booleans");
+      }
+    }
+  }
+
+  // If users are mad enough to define their own Arrays class and have some properties of that
+  // class and others of primitive array type, then we can't import java.util.Arrays.
+  // This is unlikely.
+  @AutoValue
+  abstract static class AmbiguousArrays {
+    static class Arrays {}
+
+    abstract Arrays arrays();
+
+    @SuppressWarnings("mutable")
+    abstract int[] ints();
+
+    static AmbiguousArrays create(Arrays arrays, int[] ints) {
+      return new AutoValue_AutoValueTest_AmbiguousArrays(arrays, ints);
+    }
+  }
+
+  @Test
+  public void testAmbiguousArrays() {
+    // If this test compiles at all then we presumably don't have the import problem above.
+    AmbiguousArrays object1 = AmbiguousArrays.create(new AmbiguousArrays.Arrays(), new int[0]);
+    assertNotNull(object1.arrays());
+    assertEquals(0, object1.ints().length);
+  }
+
+  static final class HashCodeObserver {
+    int hashCodeCount;
+
+    @Override
+    public boolean equals(Object obj) {
+      return obj instanceof HashCodeObserver;
+    }
+
+    @Override
+    public int hashCode() {
+      hashCodeCount++;
+      return 23;
+    }
+  }
+
+  @AutoValue
+  abstract static class MaybeCachedHashCode {
+    abstract HashCodeObserver hashCodeObserver();
+
+    abstract int randomInt();
+
+    static MaybeCachedHashCode create(HashCodeObserver hashCodeObserver, int randomInt) {
+      return new AutoValue_AutoValueTest_MaybeCachedHashCode(hashCodeObserver, randomInt);
+    }
+  }
+
+  @Test
+  public void testHashCodeNotCached() {
+    HashCodeObserver observer = new HashCodeObserver();
+    MaybeCachedHashCode maybeCached = MaybeCachedHashCode.create(observer, 17);
+    int hash1 = maybeCached.hashCode();
+    int hash2 = maybeCached.hashCode();
+    assertEquals(hash1, hash2);
+    assertEquals(2, observer.hashCodeCount);
+  }
+
+  @AutoValue
+  abstract static class Version implements Comparable<Version> {
+    abstract int major();
+
+    abstract int minor();
+
+    static Version create(int major, int minor) {
+      return new AutoValue_AutoValueTest_Version(major, minor);
+    }
+
+    @Override
+    public int compareTo(Version that) {
+      return ComparisonChain.start()
+          .compare(this.major(), that.major())
+          .compare(this.minor(), that.minor())
+          .result();
+    }
+  }
+
+  @Test
+  public void testComparisonChain() {
+    assertEquals(Version.create(1, 2), Version.create(1, 2));
+    Version[] versions = {Version.create(1, 2), Version.create(1, 3), Version.create(2, 1)};
+    for (int i = 0; i < versions.length; i++) {
+      for (int j = 0; j < versions.length; j++) {
+        int actual = Integer.signum(versions[i].compareTo(versions[j]));
+        int expected = Integer.signum(i - j);
+        assertEquals(expected, actual);
+      }
+    }
+  }
+
+  abstract static class LukesBase {
+    interface LukesVisitor<T> {
+      T visit(LukesSub s);
+    }
+
+    abstract <T> T accept(LukesVisitor<T> visitor);
+
+    @AutoValue
+    abstract static class LukesSub extends LukesBase {
+      static LukesSub create() {
+        return new AutoValue_AutoValueTest_LukesBase_LukesSub();
+      }
+
+      @Override
+      <T> T accept(LukesVisitor<T> visitor) {
+        return visitor.visit(this);
+      }
+    }
+  }
+
+  @Test
+  public void testVisitor() {
+    LukesBase.LukesVisitor<String> visitor =
+        new LukesBase.LukesVisitor<String>() {
+          @Override
+          public String visit(LukesBase.LukesSub s) {
+            return s.toString();
+          }
+        };
+    LukesBase.LukesSub sub = LukesBase.LukesSub.create();
+    assertEquals(sub.toString(), sub.accept(visitor));
+  }
+
+  @AutoValue
+  public abstract static class ComplexInheritance extends AbstractBase implements A, B {
+    public static ComplexInheritance create(String name) {
+      return new AutoValue_AutoValueTest_ComplexInheritance(name);
+    }
+
+    abstract String name();
+  }
+
+  static class AbstractBase implements Base {
+    @Override
+    public int answer() {
+      return 42;
+    }
+  }
+
+  interface A extends Base {}
+
+  interface B extends Base {}
+
+  interface Base {
+    int answer();
+  }
+
+  @Test
+  public void testComplexInheritance() {
+    ComplexInheritance complex = ComplexInheritance.create("fred");
+    assertEquals("fred", complex.name());
+    assertEquals(42, complex.answer());
+  }
+
+  // This tests the case where we inherit abstract methods on more than one path. AbstractList
+  // extends AbstractCollection, which implements Collection; and AbstractList also implements List,
+  // which extends Collection. So the class here inherits the methods of Collection on more than
+  // one path. In an earlier version of the logic for handling inheritance, this confused us into
+  // thinking that the methods from Collection were still abstract and therefore candidates for
+  // implementation, even though we inherit concrete implementations of them from AbstractList.
+  @AutoValue
+  public static class MoreComplexInheritance extends AbstractList<String> {
+    @Override
+    public String get(int index) {
+      throw new NoSuchElementException(String.valueOf(index));
+    }
+
+    @Override
+    public int size() {
+      return 0;
+    }
+
+    public static MoreComplexInheritance create() {
+      return new AutoValue_AutoValueTest_MoreComplexInheritance();
+    }
+  }
+
+  @Test
+  public void testMoreComplexInheritance() {
+    MoreComplexInheritance instance1 = MoreComplexInheritance.create();
+    MoreComplexInheritance instance2 = MoreComplexInheritance.create();
+    assertThat(instance1).isEqualTo(instance2);
+    assertThat(instance1).isNotSameInstanceAs(instance2);
+  }
+
+  // Test that we are not misled by the privateness of an ancestor into thinking that its methods
+  // are invisible to descendants.
+  public abstract static class PublicGrandparent {
+    public abstract String foo();
+  }
+
+  private static class PrivateParent extends PublicGrandparent {
+    @Override
+    public String foo() {
+      return "foo";
+    }
+  }
+
+  @AutoValue
+  static class EffectiveVisibility extends PrivateParent {
+    static EffectiveVisibility create() {
+      return new AutoValue_AutoValueTest_EffectiveVisibility();
+    }
+  }
+
+  @Test
+  public void testEffectiveVisibility() {
+    EffectiveVisibility instance1 = EffectiveVisibility.create();
+    EffectiveVisibility instance2 = EffectiveVisibility.create();
+    assertThat(instance1).isEqualTo(instance2);
+    assertThat(instance1).isNotSameInstanceAs(instance2);
+  }
+
+  @AutoValue
+  public abstract static class InheritTwice implements A, B {
+    public static InheritTwice create(int answer) {
+      return new AutoValue_AutoValueTest_InheritTwice(answer);
+    }
+  }
+
+  @Test
+  public void testInheritTwice() {
+    InheritTwice inheritTwice = InheritTwice.create(42);
+    assertEquals(42, inheritTwice.answer());
+  }
+
+  @AutoValue
+  public abstract static class Optional {
+    public abstract com.google.common.base.Optional<Object> getOptional();
+
+    public static Optional create(com.google.common.base.Optional<Object> opt) {
+      return new AutoValue_AutoValueTest_Optional(opt);
+    }
+  }
+
+  @Test
+  public void testAmbiguityFromAutoValueType() {
+    Optional autoOptional = Optional.create(com.google.common.base.Optional.absent());
+    assertEquals(com.google.common.base.Optional.absent(), autoOptional.getOptional());
+  }
+
+  static class BaseWithNestedType {
+    static class Optional {}
+  }
+
+  @AutoValue
+  public abstract static class InheritsNestedType extends BaseWithNestedType {
+    public abstract com.google.common.base.Optional<Object> getOptional();
+
+    public static InheritsNestedType create(com.google.common.base.Optional<Object> opt) {
+      return new AutoValue_AutoValueTest_InheritsNestedType(opt);
+    }
+  }
+
+  @Test
+  public void testAmbiguityFromInheritedType() {
+    InheritsNestedType inheritsNestedType =
+        InheritsNestedType.create(com.google.common.base.Optional.absent());
+    assertEquals(com.google.common.base.Optional.absent(), inheritsNestedType.getOptional());
+  }
+
+  abstract static class AbstractParent {
+    abstract int foo();
+  }
+
+  @AutoValue
+  abstract static class AbstractChild extends AbstractParent {
+    // The main point of this test is to ensure that we don't try to copy this @Override into the
+    // generated implementation alongside the @Override that we put on all implementation methods.
+    @Override
+    abstract int foo();
+
+    static AbstractChild create(int foo) {
+      return new AutoValue_AutoValueTest_AbstractChild(foo);
+    }
+  }
+
+  @Test
+  public void testOverrideNotDuplicated() {
+    AbstractChild instance = AbstractChild.create(23);
+    assertEquals(23, instance.foo());
+  }
+
+  @AutoValue
+  public abstract static class BasicWithBuilder {
+    public abstract int foo();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_BasicWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder foo(int foo);
+
+      BasicWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testBasicWithBuilder() {
+    BasicWithBuilder x = BasicWithBuilder.builder().foo(23).build();
+    assertEquals(23, x.foo());
+    try {
+      BasicWithBuilder.builder().build();
+      fail("Expected exception for missing property");
+    } catch (IllegalStateException e) {
+      if (omitIdentifiers) {
+        assertThat(e).hasMessageThat().isNull();
+      } else {
+        assertThat(e).hasMessageThat().contains("foo");
+      }
+    }
+  }
+
+  @Test
+  public void testBasicWithBuilderHasOnlyOneConstructor() throws Exception {
+    Class<?> builderClass = AutoValue_AutoValueTest_BasicWithBuilder.Builder.class;
+    Constructor<?>[] constructors = builderClass.getDeclaredConstructors();
+    assertThat(constructors).hasLength(1);
+    Constructor<?> constructor = constructors[0];
+    assertThat(constructor.getParameterTypes()).isEmpty();
+  }
+
+  @AutoValue
+  public abstract static class EmptyWithBuilder {
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_EmptyWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      EmptyWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testEmptyWithBuilder() {
+    EmptyWithBuilder x = EmptyWithBuilder.builder().build();
+    EmptyWithBuilder y = EmptyWithBuilder.builder().build();
+    assertEquals(x, y);
+  }
+
+  @AutoValue
+  public abstract static class TwoPropertiesWithBuilderClass {
+    public abstract String string();
+
+    public abstract int integer();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder();
+    }
+
+    public static Builder builder(String string) {
+      return new AutoValue_AutoValueTest_TwoPropertiesWithBuilderClass.Builder().string(string);
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder {
+      public abstract Builder string(String x);
+
+      public abstract Builder integer(int x);
+
+      public abstract TwoPropertiesWithBuilderClass build();
+    }
+  }
+
+  @Test
+  public void testTwoPropertiesWithBuilderClass() {
+    TwoPropertiesWithBuilderClass a1 =
+        TwoPropertiesWithBuilderClass.builder().string("23").integer(17).build();
+    TwoPropertiesWithBuilderClass a2 =
+        TwoPropertiesWithBuilderClass.builder("23").integer(17).build();
+    TwoPropertiesWithBuilderClass a3 =
+        TwoPropertiesWithBuilderClass.builder().integer(17).string("23").build();
+    TwoPropertiesWithBuilderClass b =
+        TwoPropertiesWithBuilderClass.builder().string("17").integer(17).build();
+    new EqualsTester().addEqualityGroup(a1, a2, a3).addEqualityGroup(b).testEquals();
+
+    try {
+      TwoPropertiesWithBuilderClass.builder().string(null);
+      fail("Did not get expected exception");
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @AutoValue
+  public abstract static class NullablePropertyWithBuilder {
+    public abstract String notNullable();
+
+    @Nullable
+    public abstract String nullable();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_NullablePropertyWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder notNullable(String s);
+
+      Builder nullable(@Nullable String s);
+
+      NullablePropertyWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testOmitNullableWithBuilder() {
+    NullablePropertyWithBuilder instance1 =
+        NullablePropertyWithBuilder.builder().notNullable("hello").build();
+    assertThat(instance1.notNullable()).isEqualTo("hello");
+    assertThat(instance1.nullable()).isNull();
+
+    NullablePropertyWithBuilder instance2 =
+        NullablePropertyWithBuilder.builder().notNullable("hello").nullable(null).build();
+    assertThat(instance2.notNullable()).isEqualTo("hello");
+    assertThat(instance2.nullable()).isNull();
+    assertThat(instance1).isEqualTo(instance2);
+
+    NullablePropertyWithBuilder instance3 =
+        NullablePropertyWithBuilder.builder().notNullable("hello").nullable("world").build();
+    assertThat(instance3.notNullable()).isEqualTo("hello");
+    assertThat(instance3.nullable()).isEqualTo("world");
+
+    try {
+      NullablePropertyWithBuilder.builder().build();
+      fail("Expected IllegalStateException for unset non-@Nullable property");
+    } catch (IllegalStateException e) {
+      if (omitIdentifiers) {
+        assertThat(e).hasMessageThat().isNull();
+      } else {
+        assertThat(e).hasMessageThat().contains("notNullable");
+      }
+    }
+  }
+
+  @AutoValue
+  public abstract static class PrimitiveAndBoxed {
+    public abstract int anInt();
+
+    @Nullable
+    public abstract Integer aNullableInteger();
+
+    public abstract Integer aNonNullableInteger();
+
+    public abstract Builder toBuilder();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_PrimitiveAndBoxed.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder setAnInt(Integer x);
+
+      Builder setANullableInteger(int x);
+
+      Builder setANonNullableInteger(int x);
+
+      PrimitiveAndBoxed build();
+    }
+  }
+
+  @Test
+  public void testPrimitiveAndBoxed() {
+    PrimitiveAndBoxed instance1 =
+        PrimitiveAndBoxed.builder().setAnInt(17).setANonNullableInteger(23).build();
+    assertThat(instance1.anInt()).isEqualTo(17);
+    assertThat(instance1.aNullableInteger()).isNull();
+    assertThat(instance1.aNonNullableInteger()).isEqualTo(23);
+
+    PrimitiveAndBoxed instance2 = instance1.toBuilder().setANullableInteger(5).build();
+    assertThat(instance2.aNullableInteger()).isEqualTo(5);
+
+    try {
+      instance1.toBuilder().setAnInt(null);
+      fail();
+    } catch (NullPointerException expected) {
+    }
+  }
+
+  @AutoValue
+  public abstract static class OptionalPropertiesWithBuilder {
+    public abstract com.google.common.base.Optional<String> optionalString();
+
+    public abstract com.google.common.base.Optional<Integer> optionalInteger();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder setOptionalString(com.google.common.base.Optional<String> s);
+
+      Builder setOptionalString(String s);
+
+      Builder setOptionalInteger(com.google.common.base.Optional<Integer> i);
+
+      Builder setOptionalInteger(int i);
+
+      OptionalPropertiesWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testOmitOptionalWithBuilder() {
+    OptionalPropertiesWithBuilder omitted = OptionalPropertiesWithBuilder.builder().build();
+    assertThat(omitted.optionalString()).isAbsent();
+    assertThat(omitted.optionalInteger()).isAbsent();
+
+    OptionalPropertiesWithBuilder supplied =
+        OptionalPropertiesWithBuilder.builder()
+            .setOptionalString(com.google.common.base.Optional.of("foo"))
+            .build();
+    assertThat(supplied.optionalString()).hasValue("foo");
+    assertThat(omitted.optionalInteger()).isAbsent();
+
+    OptionalPropertiesWithBuilder suppliedDirectly =
+        OptionalPropertiesWithBuilder.builder()
+            .setOptionalString("foo")
+            .setOptionalInteger(23)
+            .build();
+    assertThat(suppliedDirectly.optionalString()).hasValue("foo");
+    assertThat(suppliedDirectly.optionalInteger()).hasValue(23);
+  }
+
+  @AutoValue
+  public abstract static class OptionalPropertyWithNullableBuilder {
+    public abstract String notOptional();
+
+    public abstract com.google.common.base.Optional<String> optional();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_OptionalPropertyWithNullableBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder notOptional(String s);
+
+      Builder optional(@Nullable String s);
+
+      OptionalPropertyWithNullableBuilder build();
+    }
+  }
+
+  @Test
+  public void testOmitOptionalWithNullableBuilder() {
+    OptionalPropertyWithNullableBuilder instance1 =
+        OptionalPropertyWithNullableBuilder.builder().notOptional("hello").build();
+    assertThat(instance1.notOptional()).isEqualTo("hello");
+    assertThat(instance1.optional()).isAbsent();
+
+    OptionalPropertyWithNullableBuilder instance2 =
+        OptionalPropertyWithNullableBuilder.builder().notOptional("hello").optional(null).build();
+    assertThat(instance2.notOptional()).isEqualTo("hello");
+    assertThat(instance2.optional()).isAbsent();
+    assertThat(instance1).isEqualTo(instance2);
+
+    OptionalPropertyWithNullableBuilder instance3 =
+        OptionalPropertyWithNullableBuilder.builder()
+            .notOptional("hello")
+            .optional("world")
+            .build();
+    assertThat(instance3.notOptional()).isEqualTo("hello");
+    assertThat(instance3.optional()).hasValue("world");
+
+    try {
+      OptionalPropertyWithNullableBuilder.builder().build();
+      fail("Expected IllegalStateException for unset non-Optional property");
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @AutoValue
+  public abstract static class NullableOptionalPropertiesWithBuilder {
+    @Nullable
+    public abstract com.google.common.base.Optional<String> optionalString();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_NullableOptionalPropertiesWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder setOptionalString(com.google.common.base.Optional<String> s);
+
+      NullableOptionalPropertiesWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testOmitNullableOptionalWithBuilder() {
+    NullableOptionalPropertiesWithBuilder omitted =
+        NullableOptionalPropertiesWithBuilder.builder().build();
+    assertThat(omitted.optionalString()).isNull();
+
+    NullableOptionalPropertiesWithBuilder supplied =
+        NullableOptionalPropertiesWithBuilder.builder()
+            .setOptionalString(com.google.common.base.Optional.of("foo"))
+            .build();
+    assertThat(supplied.optionalString()).hasValue("foo");
+  }
+
+  @AutoValue
+  public abstract static class OptionalPropertiesWithBuilderSimpleSetter {
+    public abstract com.google.common.base.Optional<String> optionalString();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_OptionalPropertiesWithBuilderSimpleSetter.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder setOptionalString(String s);
+
+      OptionalPropertiesWithBuilderSimpleSetter build();
+    }
+  }
+
+  @Test
+  public void testOptionalPropertySimpleSetter() {
+    OptionalPropertiesWithBuilderSimpleSetter omitted =
+        OptionalPropertiesWithBuilderSimpleSetter.builder().build();
+    assertThat(omitted.optionalString()).isAbsent();
+
+    OptionalPropertiesWithBuilderSimpleSetter supplied =
+        OptionalPropertiesWithBuilderSimpleSetter.builder().setOptionalString("foo").build();
+    assertThat(supplied.optionalString()).hasValue("foo");
+  }
+
+  @AutoValue
+  public abstract static class PropertyWithOptionalGetter {
+    public abstract String getString();
+
+    public abstract int getInt();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_PropertyWithOptionalGetter.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder setString(String s);
+
+      com.google.common.base.Optional<String> getString();
+
+      Builder setInt(int x);
+
+      com.google.common.base.Optional<Integer> getInt();
+
+      PropertyWithOptionalGetter build();
+    }
+  }
+
+  @Test
+  public void testOptionalGetter() {
+    PropertyWithOptionalGetter.Builder omitted = PropertyWithOptionalGetter.builder();
+    assertThat(omitted.getString()).isAbsent();
+    assertThat(omitted.getInt()).isAbsent();
+
+    PropertyWithOptionalGetter.Builder supplied =
+        PropertyWithOptionalGetter.builder().setString("foo").setInt(23);
+    assertThat(supplied.getString()).hasValue("foo");
+    assertThat(supplied.getInt()).hasValue(23);
+  }
+
+  @AutoValue
+  public abstract static class PropertyNamedMissing {
+    public abstract String missing();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_PropertyNamedMissing.Builder();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder {
+      public abstract Builder setMissing(String x);
+
+      public abstract PropertyNamedMissing build();
+    }
+  }
+
+  // https://github.com/google/auto/issues/412
+  @Test
+  public void testPropertyNamedMissing() {
+    try {
+      PropertyNamedMissing.builder().build();
+      fail();
+    } catch (IllegalStateException expected) {
+    }
+    PropertyNamedMissing x = PropertyNamedMissing.builder().setMissing("foo").build();
+    assertThat(x.missing()).isEqualTo("foo");
+  }
+
+  @AutoValue
+  public abstract static class GenericsWithBuilder<T extends Number & Comparable<T>, U extends T> {
+    public abstract List<T> list();
+
+    public abstract U u();
+
+    public static <T extends Number & Comparable<T>, U extends T> Builder<T, U> builder() {
+      return new AutoValue_AutoValueTest_GenericsWithBuilder.Builder<T, U>();
+    }
+
+    public abstract Builder<T, U> toBuilderGenerated();
+
+    @AutoValue.Builder
+    public interface Builder<T extends Number & Comparable<T>, U extends T> {
+      Builder<T, U> list(List<T> list);
+
+      Builder<T, U> u(U u);
+
+      GenericsWithBuilder<T, U> build();
+    }
+  }
+
+  @Test
+  public void testBuilderGenerics() {
+    List<Integer> integers = ImmutableList.of(1, 2, 3);
+    GenericsWithBuilder<Integer, Integer> instance =
+        GenericsWithBuilder.<Integer, Integer>builder().list(integers).u(23).build();
+    assertEquals(integers, instance.list());
+    assertEquals((Integer) 23, instance.u());
+
+    GenericsWithBuilder<Integer, Integer> instance2 = instance.toBuilderGenerated().build();
+    assertEquals(instance, instance2);
+    assertNotSame(instance, instance2);
+
+    GenericsWithBuilder<Integer, Integer> instance3 = instance.toBuilderGenerated().u(17).build();
+    assertEquals(integers, instance3.list());
+    assertEquals((Integer) 17, instance3.u());
+  }
+
+  @AutoValue
+  public abstract static class BuilderWithSet<T extends Comparable<T>> {
+    public abstract List<T> list();
+
+    public abstract T t();
+
+    public static <T extends Comparable<T>> Builder<T> builder() {
+      return new AutoValue_AutoValueTest_BuilderWithSet.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    public interface Builder<T extends Comparable<T>> {
+      Builder<T> setList(List<T> list);
+
+      Builder<T> setT(T t);
+
+      BuilderWithSet<T> build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithSet() {
+    List<Integer> integers = ImmutableList.of(1, 2, 3);
+    BuilderWithSet<Integer> instance =
+        BuilderWithSet.<Integer>builder().setList(integers).setT(23).build();
+    assertEquals(integers, instance.list());
+    assertEquals((Integer) 23, instance.t());
+  }
+
+  @AutoValue
+  public abstract static class BuilderWithSetAndGet {
+    public abstract List<Integer> getAList();
+
+    public abstract int getAnInt();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_BuilderWithSetAndGet.Builder();
+    }
+
+    public abstract Builder toBuilder();
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder setAList(List<Integer> list);
+
+      Builder setAnInt(int i);
+
+      BuilderWithSetAndGet build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithSetAndGet() {
+    List<Integer> integers = ImmutableList.of(1, 2, 3);
+    BuilderWithSetAndGet instance =
+        BuilderWithSetAndGet.builder().setAList(integers).setAnInt(23).build();
+    assertEquals(integers, instance.getAList());
+    assertEquals(23, instance.getAnInt());
+
+    BuilderWithSetAndGet instance2 = instance.toBuilder().build();
+    assertEquals(instance, instance2);
+    assertNotSame(instance, instance2);
+
+    BuilderWithSetAndGet instance3 = instance.toBuilder().setAnInt(17).build();
+    assertEquals(integers, instance3.getAList());
+    assertEquals(17, instance3.getAnInt());
+  }
+
+  @AutoValue
+  public abstract static class BuilderWithUnprefixedGetters<T extends Comparable<T>> {
+    public abstract ImmutableList<T> list();
+
+    @Nullable
+    public abstract T t();
+
+    @SuppressWarnings("mutable")
+    public abstract int[] ints();
+
+    public abstract int noGetter();
+
+    public abstract String oAuth();
+
+    public abstract String oBrien();
+
+    public static <T extends Comparable<T>> Builder<T> builder() {
+      return new AutoValue_AutoValueTest_BuilderWithUnprefixedGetters.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    public interface Builder<T extends Comparable<T>> {
+      Builder<T> setList(ImmutableList<T> list);
+
+      Builder<T> setT(T t);
+
+      Builder<T> setInts(int[] ints);
+
+      Builder<T> setNoGetter(int x);
+
+      Builder<T> setoAuth(String x); // this ugly spelling is for compatibility
+
+      Builder<T> setOBrien(String x);
+
+      ImmutableList<T> list();
+
+      T t();
+
+      int[] ints();
+
+      String oAuth();
+
+      String oBrien();
+
+      BuilderWithUnprefixedGetters<T> build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithUnprefixedGetter() {
+    ImmutableList<String> names = ImmutableList.of("fred", "jim");
+    int[] ints = {6, 28, 496, 8128, 33550336};
+    int noGetter = -1;
+
+    BuilderWithUnprefixedGetters.Builder<String> builder = BuilderWithUnprefixedGetters.builder();
+    assertNull(builder.t());
+    try {
+      builder.list();
+      fail("Attempt to retrieve unset list property should have failed");
+    } catch (IllegalStateException e) {
+      if (omitIdentifiers) {
+        assertThat(e).hasMessageThat().isNull();
+      } else {
+        assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set");
+      }
+    }
+    try {
+      builder.ints();
+      fail("Attempt to retrieve unset ints property should have failed");
+    } catch (IllegalStateException e) {
+      if (omitIdentifiers) {
+        assertThat(e).hasMessageThat().isNull();
+      } else {
+        assertThat(e).hasMessageThat().isEqualTo("Property \"ints\" has not been set");
+      }
+    }
+
+    builder.setList(names);
+    assertThat(builder.list()).isSameInstanceAs(names);
+    builder.setInts(ints);
+    assertThat(builder.ints()).isEqualTo(ints);
+    builder.setoAuth("OAuth");
+    assertThat(builder.oAuth()).isEqualTo("OAuth");
+    builder.setOBrien("Flann");
+    assertThat(builder.oBrien()).isEqualTo("Flann");
+    // The array is not cloned by the getter, so the client can modify it (but shouldn't).
+    ints[0] = 0;
+    assertThat(builder.ints()[0]).isEqualTo(0);
+    ints[0] = 6;
+
+    BuilderWithUnprefixedGetters<String> instance = builder.setNoGetter(noGetter).build();
+    assertThat(instance.list()).isSameInstanceAs(names);
+    assertThat(instance.t()).isNull();
+    assertThat(instance.ints()).isEqualTo(ints);
+    assertThat(instance.noGetter()).isEqualTo(noGetter);
+    assertThat(instance.oAuth()).isEqualTo("OAuth");
+    assertThat(instance.oBrien()).isEqualTo("Flann");
+  }
+
+  @AutoValue
+  public abstract static class BuilderWithPrefixedGetters<T extends Comparable<T>> {
+    public abstract ImmutableList<T> getList();
+
+    public abstract T getT();
+
+    @SuppressWarnings("mutable")
+    @Nullable
+    public abstract int[] getInts();
+
+    public abstract String getOAuth();
+
+    public abstract int getNoGetter();
+
+    public static <T extends Comparable<T>> Builder<T> builder() {
+      return new AutoValue_AutoValueTest_BuilderWithPrefixedGetters.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder<T extends Comparable<T>> {
+      public abstract Builder<T> setList(ImmutableList<T> list);
+
+      public abstract Builder<T> setT(T t);
+
+      public abstract Builder<T> setInts(int[] ints);
+
+      public abstract Builder<T> setNoGetter(int x);
+
+      public abstract Builder<T> setOAuth(String x);
+
+      abstract ImmutableList<T> getList();
+
+      abstract T getT();
+
+      abstract int[] getInts();
+
+      public abstract BuilderWithPrefixedGetters<T> build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithPrefixedGetter() {
+    ImmutableList<String> names = ImmutableList.of("fred", "jim");
+    String name = "sheila";
+    int noGetter = -1;
+
+    BuilderWithPrefixedGetters.Builder<String> builder = BuilderWithPrefixedGetters.builder();
+    assertThat(builder.getInts()).isNull();
+    try {
+      builder.getList();
+      fail("Attempt to retrieve unset list property should have failed");
+    } catch (IllegalStateException e) {
+      if (omitIdentifiers) {
+        assertThat(e).hasMessageThat().isNull();
+      } else {
+        assertThat(e).hasMessageThat().isEqualTo("Property \"list\" has not been set");
+      }
+    }
+
+    builder.setList(names);
+    assertThat(builder.getList()).isSameInstanceAs(names);
+    builder.setT(name);
+    assertThat(builder.getInts()).isNull();
+    builder.setOAuth("OAuth");
+
+    BuilderWithPrefixedGetters<String> instance = builder.setNoGetter(noGetter).build();
+    assertThat(instance.getList()).isSameInstanceAs(names);
+    assertThat(instance.getT()).isEqualTo(name);
+    assertThat(instance.getInts()).isNull();
+    assertThat(instance.getNoGetter()).isEqualTo(noGetter);
+    assertThat(instance.getOAuth()).isEqualTo("OAuth");
+  }
+
+  @AutoValue
+  public abstract static class BuilderWithPropertyBuilders<FooT extends Comparable<FooT>> {
+    public abstract ImmutableList<FooT> getFoos();
+
+    public abstract ImmutableSet<String> getStrings();
+
+    public abstract BuilderWithPropertyBuilders.Builder<FooT> toBuilder();
+
+    public static <FooT extends Comparable<FooT>> Builder<FooT> builder() {
+      return new AutoValue_AutoValueTest_BuilderWithPropertyBuilders.Builder<FooT>();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder<FooT extends Comparable<FooT>> {
+      public abstract ImmutableList<FooT> getFoos();
+
+      public Builder<FooT> addFoos(Iterable<FooT> foos) {
+        foosBuilder().addAll(foos);
+        return this;
+      }
+
+      abstract ImmutableList.Builder<FooT> foosBuilder();
+
+      public Builder<FooT> addToTs(FooT element) {
+        foosBuilder().add(element);
+        return this;
+      }
+
+      abstract Builder<FooT> setStrings(ImmutableList<String> strings);
+
+      abstract ImmutableSet.Builder<String> stringsBuilder();
+
+      public Builder<FooT> addToStrings(String element) {
+        stringsBuilder().add(element);
+        return this;
+      }
+
+      public abstract BuilderWithPropertyBuilders<FooT> build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithPropertyBuilders() {
+    ImmutableList<Integer> numbers = ImmutableList.of(1, 1, 2, 6, 24);
+    ImmutableSet<String> names = ImmutableSet.of("one", "two", "six", "twenty-four");
+
+    BuilderWithPropertyBuilders<Integer> a =
+        BuilderWithPropertyBuilders.<Integer>builder()
+            .addFoos(numbers)
+            .addToStrings("one")
+            .addToStrings("two")
+            .addToStrings("six")
+            .addToStrings("twenty-four")
+            .build();
+
+    assertEquals(numbers, a.getFoos());
+    assertEquals(names, a.getStrings());
+
+    BuilderWithPropertyBuilders.Builder<Integer> bBuilder = BuilderWithPropertyBuilders.builder();
+    bBuilder.stringsBuilder().addAll(names);
+    bBuilder.foosBuilder().addAll(numbers);
+
+    assertEquals(numbers, bBuilder.getFoos());
+
+    BuilderWithPropertyBuilders<Integer> b = bBuilder.build();
+    assertEquals(a, b);
+
+    BuilderWithPropertyBuilders.Builder<Integer> cBuilder = a.toBuilder();
+    cBuilder.addToStrings("one hundred and twenty");
+    cBuilder.addToTs(120);
+    BuilderWithPropertyBuilders<Integer> c = cBuilder.build();
+    assertEquals(
+        ImmutableSet.of("one", "two", "six", "twenty-four", "one hundred and twenty"),
+        c.getStrings());
+    assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120), c.getFoos());
+
+    BuilderWithPropertyBuilders.Builder<Integer> dBuilder = a.toBuilder();
+    dBuilder.addFoos(ImmutableList.of(120, 720));
+    BuilderWithPropertyBuilders<Integer> d = dBuilder.build();
+    assertEquals(ImmutableList.of(1, 1, 2, 6, 24, 120, 720), d.getFoos());
+    assertEquals(names, d.getStrings());
+
+    BuilderWithPropertyBuilders<Integer> empty =
+        BuilderWithPropertyBuilders.<Integer>builder().build();
+    assertEquals(ImmutableList.of(), empty.getFoos());
+    assertEquals(ImmutableSet.of(), empty.getStrings());
+
+    try {
+      BuilderWithPropertyBuilders.<Integer>builder().setStrings(null).build();
+      fail("Did not get expected exception");
+    } catch (RuntimeException expected) {
+      // We don't specify whether you get the exception on setStrings(null) or on build(), nor
+      // which exception it is exactly.
+    }
+  }
+
+  interface ImmutableListOf<T> {
+    ImmutableList<T> list();
+  }
+
+  @AutoValue
+  abstract static class PropertyBuilderInheritsType implements ImmutableListOf<String> {
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_PropertyBuilderInheritsType.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract ImmutableList.Builder<String> listBuilder();
+      abstract PropertyBuilderInheritsType build();
+    }
+  }
+
+  @Test
+  public void propertyBuilderInheritsType() {
+    PropertyBuilderInheritsType.Builder builder = PropertyBuilderInheritsType.builder();
+    builder.listBuilder().add("foo", "bar");
+    PropertyBuilderInheritsType x = builder.build();
+    assertThat(x.list()).containsExactly("foo", "bar").inOrder();
+  }
+
+  @AutoValue
+  public abstract static class BuilderWithExoticPropertyBuilders<
+      K extends Number, V extends Comparable<K>> {
+    public abstract ImmutableMap<String, V> map();
+
+    public abstract ImmutableTable<String, K, V> table();
+
+    public static <K extends Number, V extends Comparable<K>> Builder<K, V> builder() {
+      return new AutoValue_AutoValueTest_BuilderWithExoticPropertyBuilders.Builder<K, V>();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder<K extends Number, V extends Comparable<K>> {
+      public Builder<K, V> putAll(Map<String, V> map) {
+        mapBuilder().putAll(map);
+        return this;
+      }
+
+      public abstract ImmutableMap.Builder<String, V> mapBuilder();
+
+      public Builder<K, V> putAll(ImmutableTable<String, K, V> table) {
+        tableBuilder().putAll(table);
+        return this;
+      }
+
+      public abstract ImmutableTable.Builder<String, K, V> tableBuilder();
+
+      public abstract BuilderWithExoticPropertyBuilders<K, V> build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithExoticPropertyBuilders() {
+    ImmutableMap<String, Integer> map = ImmutableMap.of("one", 1);
+    ImmutableTable<String, Integer, Integer> table = ImmutableTable.of("one", 1, -1);
+
+    BuilderWithExoticPropertyBuilders<Integer, Integer> a =
+        BuilderWithExoticPropertyBuilders.<Integer, Integer>builder()
+            .putAll(map)
+            .putAll(table)
+            .build();
+    assertEquals(map, a.map());
+    assertEquals(table, a.table());
+
+    BuilderWithExoticPropertyBuilders.Builder<Integer, Integer> bBuilder =
+        BuilderWithExoticPropertyBuilders.builder();
+    bBuilder.mapBuilder().putAll(map);
+    bBuilder.tableBuilder().putAll(table);
+    BuilderWithExoticPropertyBuilders<Integer, Integer> b = bBuilder.build();
+    assertEquals(a, b);
+
+    BuilderWithExoticPropertyBuilders<Integer, Integer> empty =
+        BuilderWithExoticPropertyBuilders.<Integer, Integer>builder().build();
+    assertEquals(ImmutableMap.of(), empty.map());
+    assertEquals(ImmutableTable.of(), empty.table());
+  }
+
+  @AutoValue
+  public abstract static class BuilderWithCopyingSetters<T extends Number> {
+    public abstract ImmutableSet<? extends T> things();
+
+    public abstract ImmutableList<Number> numbers();
+
+    public abstract ImmutableMap<String, T> map();
+
+    public static <T extends Number> Builder<T> builder(T value) {
+      return new AutoValue_AutoValueTest_BuilderWithCopyingSetters.Builder<T>()
+          .setNumbers(ImmutableSet.of(17, 23.0))
+          .setMap(Collections.singletonMap("foo", value));
+    }
+
+    @AutoValue.Builder
+    public interface Builder<T extends Number> {
+      Builder<T> setThings(ImmutableSet<T> things);
+
+      Builder<T> setThings(Iterable<? extends T> things);
+
+      Builder<T> setThings(T... things);
+
+      Builder<T> setNumbers(Collection<? extends Number> strings);
+
+      Builder<T> setMap(Map<String, T> map);
+
+      BuilderWithCopyingSetters<T> build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithCopyingSetters() {
+    BuilderWithCopyingSetters.Builder<Integer> builder = BuilderWithCopyingSetters.builder(23);
+
+    BuilderWithCopyingSetters<Integer> a = builder.setThings(ImmutableSet.of(1, 2)).build();
+    assertThat(a.things()).containsExactly(1, 2);
+    assertThat(a.numbers()).containsExactly(17, 23.0).inOrder();
+    assertThat(a.map()).containsExactly("foo", 23);
+
+    BuilderWithCopyingSetters<Integer> b = builder.setThings(Arrays.asList(1, 2)).build();
+    assertThat(b).isEqualTo(a);
+
+    BuilderWithCopyingSetters<Integer> c = builder.setThings(1, 2).build();
+    assertThat(c).isEqualTo(a);
+  }
+
+  @AutoValue
+  public abstract static class BuilderWithImmutableSorted<T extends Comparable<T>> {
+    public abstract ImmutableSortedSet<T> sortedSet();
+
+    public abstract ImmutableSortedMap<T, Integer> sortedMap();
+
+    public static <T extends Comparable<T>> Builder<T> builder() {
+      return new AutoValue_AutoValueTest_BuilderWithImmutableSorted.Builder<T>()
+          .setSortedSet(new TreeSet<T>())
+          .setSortedMap(new TreeMap<T, Integer>());
+    }
+
+    @AutoValue.Builder
+    public interface Builder<T extends Comparable<T>> {
+      @SuppressWarnings("unchecked")
+      Builder<T> setSortedSet(T... x);
+
+      Builder<T> setSortedSet(NavigableSet<T> x);
+
+      ImmutableSortedSet.Builder<T> sortedSetBuilder();
+
+      Builder<T> setSortedMap(SortedMap<T, Integer> x);
+
+      Builder<T> setSortedMap(NavigableMap<T, Integer> x);
+
+      ImmutableSortedMap.Builder<T, Integer> sortedMapBuilder();
+
+      BuilderWithImmutableSorted<T> build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithImmutableSorted_Varargs() {
+    BuilderWithImmutableSorted<String> x =
+        BuilderWithImmutableSorted.<String>builder().setSortedSet("foo", "bar", "baz").build();
+    assertThat(x.sortedSet()).containsExactly("bar", "baz", "foo").inOrder();
+  }
+
+  @Test
+  public void testBuilderWithImmutableSorted_SetSet() {
+    BuilderWithImmutableSorted<String> x =
+        BuilderWithImmutableSorted.<String>builder()
+            .setSortedSet(new TreeSet<String>(String.CASE_INSENSITIVE_ORDER))
+            .build();
+    assertThat(x.sortedSet().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER);
+  }
+
+  @Test
+  public void testBuilderWithImmutableSorted_SetMap() {
+    BuilderWithImmutableSorted<String> x =
+        BuilderWithImmutableSorted.<String>builder()
+            .setSortedMap(new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER))
+            .build();
+    assertThat(x.sortedMap().comparator()).isEqualTo(String.CASE_INSENSITIVE_ORDER);
+  }
+
+  @Test
+  public void testBuilderWithImmutableSorted_SetCollectionBuilder() {
+    BuilderWithImmutableSorted.Builder<String> builder =
+        BuilderWithImmutableSorted.<String>builder();
+    builder.sortedSetBuilder().add("is", "ea", "id");
+    BuilderWithImmutableSorted<String> x = builder.build();
+    assertThat(x.sortedSet()).containsExactly("ea", "id", "is").inOrder();
+  }
+
+  @Test
+  public void testBuilderWithImmutableSorted_MapCollectionBuilder() {
+    BuilderWithImmutableSorted.Builder<String> builder =
+        BuilderWithImmutableSorted.<String>builder();
+    builder.sortedMapBuilder().put("two", 2).put("one", 1);
+    BuilderWithImmutableSorted<String> x = builder.build();
+    assertThat(x.sortedMap()).containsExactly("one", 1, "two", 2).inOrder();
+  }
+
+  @AutoValue
+  public abstract static class BuilderWithCollectionBuilderAndSetter<T extends Number> {
+    public abstract ImmutableList<T> things();
+
+    public static <T extends Number> Builder<T> builder() {
+      return new AutoValue_AutoValueTest_BuilderWithCollectionBuilderAndSetter.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    public interface Builder<T extends Number> {
+      Builder<T> setThings(List<T> things);
+
+      ImmutableList<T> things();
+
+      ImmutableList.Builder<T> thingsBuilder();
+
+      BuilderWithCollectionBuilderAndSetter<T> build();
+    }
+  }
+
+  @Test
+  public void testBuilderAndSetterDefaultsEmpty() {
+    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
+        BuilderWithCollectionBuilderAndSetter.<Integer>builder();
+    assertThat(builder.things()).isEmpty();
+    assertThat(builder.build().things()).isEmpty();
+  }
+
+  @Test
+  public void testBuilderAndSetterUsingBuilder() {
+    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
+        BuilderWithCollectionBuilderAndSetter.builder();
+    builder.thingsBuilder().add(17, 23);
+    BuilderWithCollectionBuilderAndSetter<Integer> x = builder.build();
+    assertThat(x.things()).isEqualTo(ImmutableList.of(17, 23));
+  }
+
+  @Test
+  public void testBuilderAndSetterUsingSetter() {
+    ImmutableList<Integer> things = ImmutableList.of(17, 23);
+    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
+        BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(things);
+    assertThat(builder.things()).isSameInstanceAs(things);
+    assertThat(builder.build().things()).isSameInstanceAs(things);
+
+    List<Integer> moreThings = Arrays.asList(5, 17, 23);
+    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder2 =
+        BuilderWithCollectionBuilderAndSetter.<Integer>builder().setThings(moreThings);
+    assertThat(builder2.things()).isEqualTo(moreThings);
+    assertThat(builder2.build().things()).isEqualTo(moreThings);
+  }
+
+  @Test
+  public void testBuilderAndSetterUsingSetterThenBuilder() {
+    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
+        BuilderWithCollectionBuilderAndSetter.builder();
+    builder.setThings(ImmutableList.of(5));
+    builder.thingsBuilder().add(17, 23);
+    List<Integer> expectedThings = ImmutableList.of(5, 17, 23);
+    assertThat(builder.things()).isEqualTo(expectedThings);
+    assertThat(builder.build().things()).isEqualTo(expectedThings);
+  }
+
+  @Test
+  public void testBuilderAndSetterCannotSetAfterBuilder() {
+    BuilderWithCollectionBuilderAndSetter.Builder<Integer> builder =
+        BuilderWithCollectionBuilderAndSetter.builder();
+    builder.setThings(ImmutableList.of(5));
+    builder.thingsBuilder().add(17, 23);
+    try {
+      builder.setThings(ImmutableList.of(1729));
+      fail("Setting list after retrieving builder should provoke an exception");
+    } catch (IllegalStateException e) {
+      if (omitIdentifiers) {
+        assertThat(e).hasMessageThat().isNull();
+      } else {
+        assertThat(e).hasMessageThat().isEqualTo("Cannot set things after calling thingsBuilder()");
+      }
+    }
+  }
+
+  abstract static class AbstractParentWithBuilder {
+    abstract String foo();
+
+    abstract static class Builder<B extends Builder<B>> {
+      abstract B foo(String s);
+    }
+  }
+
+  @AutoValue
+  abstract static class ChildWithBuilder extends AbstractParentWithBuilder {
+    abstract String bar();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_ChildWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder extends AbstractParentWithBuilder.Builder<Builder> {
+      abstract Builder bar(String s);
+
+      abstract ChildWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testInheritedBuilder() {
+    ChildWithBuilder x = ChildWithBuilder.builder().foo("foo").bar("bar").build();
+    assertThat(x.foo()).isEqualTo("foo");
+    assertThat(x.bar()).isEqualTo("bar");
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface GwtCompatible {
+    boolean funky() default false;
+  }
+
+  @AutoValue
+  @GwtCompatible(funky = true)
+  abstract static class GwtCompatibleTest {
+    abstract int foo();
+
+    static GwtCompatibleTest create(int foo) {
+      return new AutoValue_AutoValueTest_GwtCompatibleTest(foo);
+    }
+  }
+
+  @AutoValue
+  @GwtCompatible
+  abstract static class GwtCompatibleTestNoArgs {
+    abstract String bar();
+
+    static GwtCompatibleTestNoArgs create(String bar) {
+      return new AutoValue_AutoValueTest_GwtCompatibleTestNoArgs(bar);
+    }
+  }
+
+  @Test
+  public void testGwtCompatibleInherited() {
+    GwtCompatibleTest test = GwtCompatibleTest.create(23);
+    GwtCompatible gwtCompatible = test.getClass().getAnnotation(GwtCompatible.class);
+    assertNotNull(gwtCompatible);
+    assertTrue(gwtCompatible.funky());
+
+    GwtCompatibleTestNoArgs testNoArgs = GwtCompatibleTestNoArgs.create("23");
+    GwtCompatible gwtCompatibleNoArgs = testNoArgs.getClass().getAnnotation(GwtCompatible.class);
+    assertNotNull(gwtCompatibleNoArgs);
+    assertFalse(gwtCompatibleNoArgs.funky());
+  }
+
+  @interface NestedAnnotation {
+    int anInt();
+
+    Class<?>[] aClassArray();
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface HairyAnnotation {
+    String aString();
+
+    Class<? extends Number> aClass();
+
+    RetentionPolicy anEnum();
+
+    NestedAnnotation anAnnotation();
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface CopiedAnnotation {}
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @interface ExcludedAnnotation {}
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @Inherited
+  @interface InheritedAnnotation {}
+
+  @CopiedAnnotation
+  @ExcludedAnnotation
+  @InheritedAnnotation
+  @AutoValue
+  @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class})
+  abstract static class CopyAnnotation {
+    @HairyAnnotation(
+        aString = "hello",
+        aClass = Integer.class,
+        anEnum = RetentionPolicy.RUNTIME,
+        anAnnotation =
+            @NestedAnnotation(
+                anInt = 73,
+                aClassArray = {String.class, Object.class}))
+    abstract String field1();
+
+    @CopiedAnnotation
+    @ExcludedAnnotation
+    @InheritedAnnotation
+    @AutoValue.CopyAnnotations(exclude = {ExcludedAnnotation.class})
+    abstract String field2();
+
+    static CopyAnnotation create() {
+      return new AutoValue_AutoValueTest_CopyAnnotation("field1", "field2");
+    }
+  }
+
+  @Test
+  public void testCopyClassAnnotations() throws Exception {
+    CopyAnnotation x = CopyAnnotation.create();
+    Class<?> c = x.getClass();
+    assertNotSame(CopyAnnotation.class, c);
+
+    // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they
+    // don't appear on the AutoValue_ subclass.
+    {
+      List<Class<? extends Annotation>> annotationsOnSuperclass =
+          new ArrayList<Class<? extends Annotation>>();
+      for (Annotation annotation : CopyAnnotation.class.getDeclaredAnnotations()) {
+        annotationsOnSuperclass.add(annotation.annotationType());
+      }
+      assertThat(annotationsOnSuperclass)
+          .containsAtLeast(
+              CopiedAnnotation.class, ExcludedAnnotation.class, InheritedAnnotation.class);
+    }
+
+    {
+      List<Class<? extends Annotation>> annotationsOnSubclass =
+          new ArrayList<Class<? extends Annotation>>();
+      for (Annotation annotation : c.getDeclaredAnnotations()) {
+        annotationsOnSubclass.add(annotation.annotationType());
+      }
+      assertThat(annotationsOnSubclass).containsExactly(CopiedAnnotation.class);
+    }
+  }
+
+  @Test
+  public void testCopyMethodAnnotations() throws Exception {
+    CopyAnnotation x = CopyAnnotation.create();
+    Class<?> c = x.getClass();
+    assertNotSame(CopyAnnotation.class, c);
+
+    Method methodInSubclass = c.getDeclaredMethod("field2");
+    Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod("field2");
+
+    // Sanity check: if these don't appear on CopyAnnotation, it makes no sense to assert that they
+    // don't appear on the AutoValue_ subclass.
+    assertThat(methodInSuperclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue();
+    assertThat(methodInSuperclass.isAnnotationPresent(ExcludedAnnotation.class)).isTrue();
+    assertThat(methodInSuperclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue();
+
+    assertThat(methodInSubclass.isAnnotationPresent(CopiedAnnotation.class)).isTrue();
+    assertThat(methodInSubclass.isAnnotationPresent(ExcludedAnnotation.class)).isFalse();
+    assertThat(methodInSubclass.isAnnotationPresent(InheritedAnnotation.class)).isTrue();
+  }
+
+  @Test
+  public void testCopyMethodAnnotationsByDefault() throws Exception {
+    CopyAnnotation x = CopyAnnotation.create();
+    Class<?> c = x.getClass();
+    assertNotSame(CopyAnnotation.class, c);
+    Method methodInSubclass = c.getDeclaredMethod("field1");
+    Method methodInSuperclass = CopyAnnotation.class.getDeclaredMethod("field1");
+    assertNotSame(methodInSuperclass, methodInSubclass);
+    HairyAnnotation annotationInSubclass = methodInSubclass.getAnnotation(HairyAnnotation.class);
+    HairyAnnotation annotationInSuperclass =
+        methodInSuperclass.getAnnotation(HairyAnnotation.class);
+    assertEquals(annotationInSuperclass, annotationInSubclass);
+  }
+
+  @AutoValue
+  abstract static class HProperty {
+    public abstract Object h();
+
+    public static HProperty create(Object h) {
+      return new AutoValue_AutoValueTest_HProperty(h);
+    }
+  }
+
+  @Test
+  public void testHProperty() throws Exception {
+    // Checks that we can have a property called `h`. The generated hashCode() method has
+    // a local variable of that name and can cause the error `int cannot be dereferenced`
+    HProperty.create(new Object());
+  }
+
+  interface Parent1 {
+    int something();
+  }
+
+  interface Parent2 {
+    int something();
+  }
+
+  @AutoValue
+  abstract static class InheritSameMethodTwice implements Parent1, Parent2 {
+    static InheritSameMethodTwice create(int something) {
+      return new AutoValue_AutoValueTest_InheritSameMethodTwice(something);
+    }
+  }
+
+  @Test
+  public void testInheritSameMethodTwice() {
+    InheritSameMethodTwice x = InheritSameMethodTwice.create(23);
+    assertThat(x.something()).isEqualTo(23);
+  }
+
+  // Make sure we behave correctly when we inherit the same method definition from more than
+  // one parent interface. We expect methods to appear in the order they are seen, with parents
+  // preceding children, the superclass of a class preceding interfaces that class implements,
+  // and an interface mentioned earlier in the "implements" clause preceding one mentioned later.
+  // https://github.com/google/auto/issues/372
+  interface OneTwoThreeFour {
+    String one();
+
+    String two();
+
+    boolean three();
+
+    long four();
+  }
+
+  interface TwoFour {
+    String two();
+
+    long four();
+  }
+
+  @AutoValue
+  abstract static class OneTwoThreeFourImpl implements OneTwoThreeFour, TwoFour {
+    static OneTwoThreeFourImpl create(String one, String two, boolean three, long four) {
+      return new AutoValue_AutoValueTest_OneTwoThreeFourImpl(one, two, three, four);
+    }
+  }
+
+  @Test
+  public void testOneTwoThreeFour() {
+    OneTwoThreeFour x = OneTwoThreeFourImpl.create("one", "two", false, 4);
+    String expectedString =
+        omitIdentifiers
+            ? "{one, two, false, 4}"
+            : "OneTwoThreeFourImpl{one=one, two=two, three=false, four=4}";
+    assertThat(x.toString()).isEqualTo(expectedString);
+  }
+
+  @AutoValue
+  abstract static class OuterWithBuilder {
+    abstract String foo();
+
+    abstract InnerWithBuilder inner();
+
+    abstract Builder toBuilder();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_OuterWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder foo(String x);
+
+      abstract Builder inner(InnerWithBuilder x);
+
+      abstract InnerWithBuilder.Builder innerBuilder();
+
+      abstract OuterWithBuilder build();
+    }
+  }
+
+  @AutoValue
+  abstract static class InnerWithBuilder {
+    abstract int bar();
+
+    abstract Builder toBuilder();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_InnerWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder setBar(int x);
+
+      abstract InnerWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testBuilderWithinBuilder() {
+    OuterWithBuilder x =
+        OuterWithBuilder.builder()
+            .inner(InnerWithBuilder.builder().setBar(23).build())
+            .foo("yes")
+            .build();
+    String expectedStringX =
+        omitIdentifiers
+            ? "{yes, {23}}"
+            : "OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=23}}";
+    assertThat(x.toString()).isEqualTo(expectedStringX);
+
+    OuterWithBuilder.Builder xBuilder = x.toBuilder();
+    xBuilder.innerBuilder().setBar(17);
+    OuterWithBuilder y = xBuilder.build();
+    String expectedStringY =
+        omitIdentifiers
+            ? "{yes, {17}}"
+            : "OuterWithBuilder{foo=yes, inner=InnerWithBuilder{bar=17}}";
+    assertThat(y.toString()).isEqualTo(expectedStringY);
+  }
+
+  public static class MyMap<K, V> extends HashMap<K, V> {
+    public MyMap() {}
+
+    public MyMap(Map<K, V> map) {
+      super(map);
+    }
+  }
+
+  public static class MyMapBuilder<K, V> extends LinkedHashMap<K, V> {
+    public MyMapBuilder() {}
+
+    public MyMapBuilder(Map<K, V> map) {
+      super(map);
+    }
+
+    public MyMap<K, V> build() {
+      return new MyMap<K, V>(this);
+    }
+  }
+
+  @AutoValue
+  abstract static class BuildMyMap<K, V> {
+    abstract MyMap<K, V> map();
+
+    abstract Builder<K, V> toBuilder();
+
+    static <K, V> Builder<K, V> builder() {
+      return new AutoValue_AutoValueTest_BuildMyMap.Builder<K, V>();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder<K, V> {
+      abstract MyMapBuilder<K, V> mapBuilder();
+
+      abstract BuildMyMap<K, V> build();
+    }
+  }
+
+  @Test
+  public void testMyMapBuilder() {
+    BuildMyMap.Builder<String, Integer> builder = BuildMyMap.builder();
+    MyMapBuilder<String, Integer> mapBuilder = builder.mapBuilder();
+    mapBuilder.put("23", 23);
+    BuildMyMap<String, Integer> built = builder.build();
+    assertThat(built.map()).containsExactly("23", 23);
+
+    BuildMyMap.Builder<String, Integer> builder2 = built.toBuilder();
+    MyMapBuilder<String, Integer> mapBuilder2 = builder2.mapBuilder();
+    mapBuilder2.put("17", 17);
+    BuildMyMap<String, Integer> built2 = builder2.build();
+    assertThat(built2.map()).containsExactly("23", 23, "17", 17);
+  }
+
+  public static class MyStringMap<V> extends MyMap<String, V> {
+    public MyStringMap() {}
+
+    public MyStringMap(Map<String, V> map) {
+      super(map);
+    }
+
+    public MyStringMapBuilder<V> toBuilder() {
+      return new MyStringMapBuilder<V>(this);
+    }
+  }
+
+  public static class MyStringMapBuilder<V> extends MyMapBuilder<String, V> {
+    public MyStringMapBuilder() {}
+
+    public MyStringMapBuilder(Map<String, V> map) {
+      super(map);
+    }
+
+    @Override
+    public MyStringMap<V> build() {
+      return new MyStringMap<V>(this);
+    }
+  }
+
+  @AutoValue
+  abstract static class BuildMyStringMap<V> {
+    abstract MyStringMap<V> map();
+
+    abstract Builder<V> toBuilder();
+
+    static <V> Builder<V> builder() {
+      return new AutoValue_AutoValueTest_BuildMyStringMap.Builder<V>();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder<V> {
+      abstract MyStringMapBuilder<V> mapBuilder();
+
+      abstract BuildMyStringMap<V> build();
+    }
+  }
+
+  @Test
+  public void testMyStringMapBuilder() {
+    BuildMyStringMap.Builder<Integer> builder = BuildMyStringMap.builder();
+    MyStringMapBuilder<Integer> mapBuilder = builder.mapBuilder();
+    mapBuilder.put("23", 23);
+    BuildMyStringMap<Integer> built = builder.build();
+    assertThat(built.map()).containsExactly("23", 23);
+
+    BuildMyStringMap.Builder<Integer> builder2 = built.toBuilder();
+    MyStringMapBuilder<Integer> mapBuilder2 = builder2.mapBuilder();
+    mapBuilder2.put("17", 17);
+    BuildMyStringMap<Integer> built2 = builder2.build();
+    assertThat(built2.map()).containsExactly("17", 17, "23", 23);
+  }
+
+  @AutoValue
+  abstract static class BuilderOfManyAccessLevels {
+    public abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt();
+
+    protected abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt();
+
+    abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt();
+
+    @AutoValue.Builder
+    public abstract static class Builder {
+      protected abstract int publicGetterProtectedBuilderGetterPackageProtectedSetterInt();
+
+      abstract int protectedGetterPackageProtectedBuilderGetterPublicSetterInt();
+
+      public abstract int packageProtectedGetterPublicBuilderGetterProtectedSetterInt();
+
+      abstract Builder setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt(int x);
+
+      public abstract Builder setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt(int x);
+
+      protected abstract Builder setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt(
+          int x);
+
+      public abstract BuilderOfManyAccessLevels build();
+    }
+  }
+
+  @Test
+  public void testBuilderOfManyAccessLevels_accessLevels() throws NoSuchMethodException {
+    Class<?> builderClass = AutoValue_AutoValueTest_BuilderOfManyAccessLevels.Builder.class;
+
+    testMethodAccess(
+        Access.PROTECTED,
+        builderClass,
+        "publicGetterProtectedBuilderGetterPackageProtectedSetterInt");
+    testMethodAccess(
+        Access.PACKAGE,
+        builderClass,
+        "protectedGetterPackageProtectedBuilderGetterPublicSetterInt");
+    testMethodAccess(
+        Access.PUBLIC, builderClass, "packageProtectedGetterPublicBuilderGetterProtectedSetterInt");
+
+    testMethodAccess(
+        Access.PACKAGE,
+        builderClass,
+        "setPublicGetterProtectedBuilderGetterPackageProtectedSetterInt",
+        int.class);
+    testMethodAccess(
+        Access.PUBLIC,
+        builderClass,
+        "setProtectedGetterPackageProtectedBuilderGetterPublicSetterInt",
+        int.class);
+    testMethodAccess(
+        Access.PROTECTED,
+        builderClass,
+        "setPackageProtectedGetterPublicBuilderGetterProtectedSetterInt",
+        int.class);
+  }
+
+  private enum Access {
+    PRIVATE,
+    PACKAGE,
+    PROTECTED,
+    PUBLIC
+  }
+
+  private static final ImmutableMap<Integer, Access> MODIFIER_BITS_TO_ACCESS =
+      ImmutableMap.of(
+          Modifier.PUBLIC,
+          Access.PUBLIC,
+          Modifier.PROTECTED,
+          Access.PROTECTED,
+          Modifier.PRIVATE,
+          Access.PRIVATE,
+          0,
+          Access.PACKAGE);
+
+  private static void testMethodAccess(
+      Access expectedAccess, Class<?> clazz, String methodName, Class<?>... parameterTypes)
+      throws NoSuchMethodException {
+    Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
+    int modBits = method.getModifiers() & (Modifier.PUBLIC | Modifier.PROTECTED | Modifier.PRIVATE);
+    Access actualAccess = MODIFIER_BITS_TO_ACCESS.get(modBits);
+    assertWithMessage("Wrong access for %s", methodName)
+        .that(actualAccess)
+        .isEqualTo(expectedAccess);
+  }
+
+  static class VersionId {}
+
+  static class ItemVersionId extends VersionId {}
+
+  interface VersionedPersistent {
+    VersionId getVersionId();
+  }
+
+  interface Item extends VersionedPersistent {
+    @Override
+    ItemVersionId getVersionId();
+  }
+
+  @AutoValue
+  abstract static class FakeItem implements Item {
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_FakeItem.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder setVersionId(ItemVersionId x);
+
+      abstract FakeItem build();
+    }
+  }
+
+  @Test
+  public void testParentInterfaceOverridesGrandparent() {
+    ItemVersionId version = new ItemVersionId();
+    FakeItem fakeItem = FakeItem.builder().setVersionId(version).build();
+    assertThat(fakeItem.getVersionId()).isSameInstanceAs(version);
+  }
+
+  /** Fake ApkVersionCode class. */
+  public static class ApkVersionCode {}
+
+  /**
+   * Illustrates a potential problem that showed up while generalizing builders. If our imports are
+   * not accurate we may end up importing ImmutableList.Builder, which won't work because the
+   * generated Builder subclass of ReleaseInfoBuilder will supersede it. Normally we wouldn't import
+   * ImmutableList.Builder because the nested Builder class in the {@code @AutoValue} class would
+   * prevent us trying. But in this case the nested class is called ReleaseInfoBuilder so we might
+   * import anyway if we're not careful. This is one reason why we moved away from importing nested
+   * classes to only importing top-level classes.
+   */
+  @AutoValue
+  public abstract static class ReleaseInfo {
+    public static ReleaseInfoBuilder newBuilder() {
+      return new AutoValue_AutoValueTest_ReleaseInfo.Builder();
+    }
+
+    public abstract ImmutableList<ApkVersionCode> apkVersionCodes();
+
+    ReleaseInfo() {}
+
+    /** Notice that this is called ReleaseInfoBuilder and not Builder. */
+    @AutoValue.Builder
+    public abstract static class ReleaseInfoBuilder {
+      public ReleaseInfoBuilder addApkVersionCode(ApkVersionCode code) {
+        apkVersionCodesBuilder().add(code);
+        return this;
+      }
+
+      abstract ImmutableList.Builder<ApkVersionCode> apkVersionCodesBuilder();
+
+      public abstract ReleaseInfo build();
+    }
+  }
+
+  @Test
+  public void testUnusualBuilderName() {
+    ApkVersionCode apkVersionCode = new ApkVersionCode();
+    ReleaseInfo x = ReleaseInfo.newBuilder().addApkVersionCode(apkVersionCode).build();
+    assertThat(x.apkVersionCodes()).containsExactly(apkVersionCode);
+  }
+
+  @AutoValue
+  public abstract static class OuterWithDefaultableInner {
+    public abstract ImmutableList<String> names();
+
+    public abstract DefaultableInner inner();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_OuterWithDefaultableInner.Builder();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder {
+      public abstract ImmutableList<String> names();
+
+      public abstract ImmutableList.Builder<String> namesBuilder();
+
+      public abstract DefaultableInner inner();
+
+      public abstract DefaultableInner.Builder innerBuilder();
+
+      public abstract OuterWithDefaultableInner build();
+    }
+  }
+
+  @AutoValue
+  public abstract static class DefaultableInner {
+    public abstract int bar();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_DefaultableInner.Builder().setBar(23);
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder {
+      public abstract Builder setBar(int x);
+
+      public abstract DefaultableInner build();
+    }
+  }
+
+  @Test
+  public void testOuterWithDefaultableInner_Defaults() {
+    DefaultableInner defaultInner = DefaultableInner.builder().build();
+    OuterWithDefaultableInner x = OuterWithDefaultableInner.builder().build();
+    assertThat(x.names()).isEmpty();
+    assertThat(x.inner()).isEqualTo(defaultInner);
+  }
+
+  @Test
+  public void testOuterWithDefaultableInner_Getters() {
+    DefaultableInner defaultInner = DefaultableInner.builder().build();
+
+    OuterWithDefaultableInner.Builder builder = OuterWithDefaultableInner.builder();
+    assertThat(builder.names()).isEmpty();
+    assertThat(builder.inner()).isEqualTo(defaultInner);
+
+    OuterWithDefaultableInner x1 = builder.build();
+    assertThat(x1.names()).isEmpty();
+    assertThat(x1.inner()).isEqualTo(defaultInner);
+
+    builder.namesBuilder().add("Fred");
+    builder.innerBuilder().setBar(17);
+    OuterWithDefaultableInner x2 = builder.build();
+    assertThat(x2.names()).containsExactly("Fred");
+    assertThat(x2.inner().bar()).isEqualTo(17);
+  }
+
+  @AutoValue
+  public abstract static class OuterWithNonDefaultableInner<T> {
+    public abstract int foo();
+
+    public abstract NonDefaultableInner<T> inner();
+
+    public static <T> Builder<T> builder() {
+      return new AutoValue_AutoValueTest_OuterWithNonDefaultableInner.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder<T> {
+      public abstract Builder<T> setFoo(int x);
+
+      public abstract NonDefaultableInner.Builder<T> innerBuilder();
+
+      public abstract OuterWithNonDefaultableInner<T> build();
+    }
+  }
+
+  @AutoValue
+  public abstract static class NonDefaultableInner<E> {
+    public abstract E bar();
+
+    public static <E> Builder<E> builder() {
+      return new AutoValue_AutoValueTest_NonDefaultableInner.Builder<E>();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder<E> {
+      public abstract Builder<E> setBar(E x);
+
+      public abstract NonDefaultableInner<E> build();
+    }
+  }
+
+  @Test
+  public void testOuterWithNonDefaultableInner() {
+    OuterWithNonDefaultableInner.Builder<String> builder = OuterWithNonDefaultableInner.builder();
+    builder.setFoo(23);
+    try {
+      builder.build();
+      fail("Did not get expected exception for unbuilt inner instance");
+    } catch (IllegalStateException expected) {
+    }
+  }
+
+  @SuppressWarnings("JavaLangClash")
+  @AutoValue
+  public abstract static class RedeclareJavaLangClasses {
+    // If you really really want to do this, we have you covered.
+
+    public static class Object {}
+
+    public static class String {}
+
+    public abstract Object alienObject();
+
+    public abstract String alienString();
+
+    public static Builder builder() {
+      return new AutoValue_AutoValueTest_RedeclareJavaLangClasses.Builder();
+    }
+
+    @AutoValue.Builder
+    public abstract static class Builder {
+      public abstract Builder setAlienObject(Object x);
+
+      public abstract Builder setAlienString(String x);
+
+      public abstract RedeclareJavaLangClasses build();
+    }
+  }
+
+  @Test
+  public void testRedeclareJavaLangClasses() {
+    RedeclareJavaLangClasses x =
+        RedeclareJavaLangClasses.builder()
+            .setAlienObject(new RedeclareJavaLangClasses.Object())
+            .setAlienString(new RedeclareJavaLangClasses.String())
+            .build();
+    assertThat(x).isNotNull();
+  }
+
+  // b/28382293
+  @AutoValue
+  abstract static class GenericExtends {
+    abstract ImmutableSet<Number> metrics();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_GenericExtends.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder setMetrics(ImmutableSet<? extends Number> metrics);
+      abstract GenericExtends build();
+    }
+  }
+
+  @Test
+  public void testGenericExtends() {
+    ImmutableSet<Integer> ints = ImmutableSet.of(1, 2, 3);
+    GenericExtends g = GenericExtends.builder().setMetrics(ints).build();
+    assertThat(g.metrics()).isEqualTo(ints);
+  }
+
+  abstract static class Parent<T> {
+    abstract List<T> getList();
+  }
+
+  @AutoValue
+  abstract static class Child extends Parent<String> {
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_Child.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder setList(List<String> list);
+      abstract Child build();
+    }
+  }
+
+  @Test
+  public void nonGenericExtendsGeneric() {
+    List<String> list = ImmutableList.of("foo", "bar", "baz");
+    Child child = Child.builder().setList(list).build();
+    assertThat(child.getList()).containsExactlyElementsIn(list).inOrder();
+  }
+
+  abstract static class AbstractGenericParentWithBuilder<T> {
+    abstract T foo();
+
+    abstract static class Builder<T, B extends Builder<T, B>> {
+      abstract B foo(T s);
+    }
+  }
+
+  @AutoValue
+  abstract static class ChildOfAbstractGenericParentWithBuilder<T>
+      extends AbstractGenericParentWithBuilder<T> {
+    static <T> Builder<T> builder() {
+      return new AutoValue_AutoValueTest_ChildOfAbstractGenericParentWithBuilder.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder<T>
+        extends AbstractGenericParentWithBuilder.Builder<T, Builder<T>> {
+      abstract ChildOfAbstractGenericParentWithBuilder<T> build();
+    }
+  }
+
+  @Test
+  public void genericExtendsGeneric() {
+    ChildOfAbstractGenericParentWithBuilder<String> child =
+        ChildOfAbstractGenericParentWithBuilder.<String>builder().foo("foo").build();
+    assertThat(child.foo()).isEqualTo("foo");
+  }
+
+  @SuppressWarnings("ClassCanBeStatic")
+  static class OuterWithTypeParam<T extends Number> {
+    class InnerWithTypeParam<U> {}
+    class InnerWithoutTypeParam {}
+    static class Nested {}
+  }
+
+  @AutoValue
+  abstract static class Nesty {
+    abstract OuterWithTypeParam<Double>.InnerWithTypeParam<String> innerWithTypeParam();
+    abstract OuterWithTypeParam<Double>.InnerWithoutTypeParam innerWithoutTypeParam();
+    abstract OuterWithTypeParam.Nested nested();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_Nesty.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract Builder setInnerWithTypeParam(
+          OuterWithTypeParam<Double>.InnerWithTypeParam<String> x);
+      abstract Builder setInnerWithoutTypeParam(OuterWithTypeParam<Double>.InnerWithoutTypeParam x);
+      abstract Builder setNested(OuterWithTypeParam.Nested x);
+      abstract Nesty build();
+    }
+  }
+
+  @Test
+  public void outerWithTypeParam() throws ReflectiveOperationException {
+    @SuppressWarnings("UseDiamond") // Currently we compile this with -source 6 in the Eclipse test.
+    OuterWithTypeParam<Double> outer = new OuterWithTypeParam<Double>();
+    Nesty nesty = Nesty.builder()
+        .setInnerWithTypeParam(outer.new InnerWithTypeParam<String>())
+        .setInnerWithoutTypeParam(outer.new InnerWithoutTypeParam())
+        .setNested(new OuterWithTypeParam.Nested())
+        .build();
+    Type originalReturnType =
+        Nesty.class.getDeclaredMethod("innerWithTypeParam").getGenericReturnType();
+    Type generatedReturnType =
+        nesty.getClass().getDeclaredMethod("innerWithTypeParam").getGenericReturnType();
+    assertThat(generatedReturnType).isEqualTo(originalReturnType);
+    Type generatedBuilderParamType =
+        Nesty.builder()
+            .getClass()
+            .getDeclaredMethod("setInnerWithTypeParam", OuterWithTypeParam.InnerWithTypeParam.class)
+            .getGenericParameterTypes()[0];
+    assertThat(generatedBuilderParamType).isEqualTo(originalReturnType);
+  }
+
+  @AutoValue
+  abstract static class BuilderAnnotationsNotCopied {
+    abstract String foo();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_BuilderAnnotationsNotCopied.Builder();
+    }
+
+    @AutoValue.Builder
+    @MyAnnotation("thing")
+    abstract static class Builder {
+      abstract Builder setFoo(String x);
+      abstract BuilderAnnotationsNotCopied build();
+    }
+  }
+
+  @Test
+  public void builderAnnotationsNotCopiedByDefault() {
+    BuilderAnnotationsNotCopied.Builder builder = BuilderAnnotationsNotCopied.builder();
+    assertThat(builder.getClass().getAnnotations()).isEmpty();
+    assertThat(builder.setFoo("foo").build().foo()).isEqualTo("foo");
+  }
+
+  @AutoValue
+  abstract static class BuilderAnnotationsCopied {
+    abstract String foo();
+
+    static Builder builder() {
+      return new AutoValue_AutoValueTest_BuilderAnnotationsCopied.Builder();
+    }
+
+    @AutoValue.Builder
+    @AutoValue.CopyAnnotations
+    @MyAnnotation("thing")
+    abstract static class Builder {
+      abstract Builder setFoo(String x);
+      abstract BuilderAnnotationsCopied build();
+    }
+  }
+
+  @Test
+  public void builderAnnotationsCopiedIfRequested() {
+    BuilderAnnotationsCopied.Builder builder = BuilderAnnotationsCopied.builder();
+    assertThat(builder.getClass().getAnnotations()).asList().containsExactly(myAnnotation("thing"));
+    assertThat(builder.setFoo("foo").build().foo()).isEqualTo("foo");
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/CompileWithEclipseTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/CompileWithEclipseTest.java
new file mode 100644
index 0000000..1518827
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/CompileWithEclipseTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import static com.google.common.base.StandardSystemProperty.JAVA_HOME;
+import static com.google.common.collect.ImmutableSet.toImmutableSet;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import com.google.auto.value.processor.AutoAnnotationProcessor;
+import com.google.auto.value.processor.AutoOneOfProcessor;
+import com.google.auto.value.processor.AutoValueProcessor;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+import javax.annotation.processing.Processor;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
+import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests that we can compile our AutoValue tests using the Eclipse batch compiler. Since the tests
+ * exercise many AutoValue subtleties, the ability to compile them all is a good indication of
+ * Eclipse support.
+ */
+@RunWith(JUnit4.class)
+public class CompileWithEclipseTest {
+  private static final String SOURCE_ROOT = System.getProperty("basedir");
+
+  @BeforeClass
+  public static void setSourceRoot() {
+    assertWithMessage("basedir property must be set - test must be run from Maven")
+        .that(SOURCE_ROOT).isNotNull();
+  }
+
+  public @Rule TemporaryFolder tmp = new TemporaryFolder();
+
+  private static final ImmutableSet<String> IGNORED_TEST_FILES =
+      ImmutableSet.of("AutoValueNotEclipseTest.java", "CompileWithEclipseTest.java");
+
+  private static final Predicate<File> JAVA_FILE =
+      f -> f.getName().endsWith(".java") && !IGNORED_TEST_FILES.contains(f.getName());
+
+  private static final Predicate<File> JAVA8_TEST =
+      f -> f.getName().equals("AutoValueJava8Test.java")
+          || f.getName().equals("AutoOneOfJava8Test.java")
+          || f.getName().equals("EmptyExtension.java");
+
+  @Test
+  public void compileWithEclipseJava6() throws Exception {
+    compileWithEclipse("6", JAVA_FILE.and(JAVA8_TEST.negate()));
+  }
+
+  @Test
+  public void compileWithEclipseJava8() throws Exception {
+    compileWithEclipse("8", JAVA_FILE);
+  }
+
+  private void compileWithEclipse(String version, Predicate<File> predicate) throws IOException {
+    File sourceRootFile = new File(SOURCE_ROOT);
+    File javaDir = new File(sourceRootFile, "src/main/java");
+    File javatestsDir = new File(sourceRootFile, "src/test/java");
+    Set<File> sources =
+        new ImmutableSet.Builder<File>()
+            .addAll(filesUnderDirectory(javaDir, predicate))
+            .addAll(filesUnderDirectory(javatestsDir, predicate))
+            .build();
+    assertThat(sources).isNotEmpty();
+    JavaCompiler compiler = new EclipseCompiler();
+    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
+    // This hack is only needed in a Google-internal Java 8 environment where symbolic links make it
+    // hard for ecj to find the boot class path. Elsewhere it is unnecessary but harmless. Notably,
+    // on Java 9+ there is no rt.jar. There, fileManager.getLocation(PLATFORM_CLASS_PATH) returns
+    // null, because the relevant classes are in modules inside
+    // fileManager.getLocation(SYSTEM_MODULES).
+    File rtJar = new File(JAVA_HOME.value() + "/lib/rt.jar");
+    if (rtJar.exists()) {
+      List<File> bootClassPath = ImmutableList.<File>builder()
+          .add(rtJar)
+          .addAll(fileManager.getLocation(StandardLocation.PLATFORM_CLASS_PATH))
+          .build();
+      fileManager.setLocation(StandardLocation.PLATFORM_CLASS_PATH, bootClassPath);
+    }
+    Iterable<? extends JavaFileObject> sourceFileObjects =
+        fileManager.getJavaFileObjectsFromFiles(sources);
+    String outputDir = tmp.getRoot().toString();
+    ImmutableList<String> options =
+        ImmutableList.of("-d", outputDir, "-s", outputDir, "-source", version, "-target", version);
+    JavaCompiler.CompilationTask task =
+        compiler.getTask(null, fileManager, null, options, null, sourceFileObjects);
+    // Explicitly supply an empty list of extensions for AutoValueProcessor, because otherwise this
+    // test will pick up a test one and get confused.
+    AutoValueProcessor autoValueProcessor = new AutoValueProcessor(ImmutableList.of());
+    ImmutableList<? extends Processor> processors =
+        ImmutableList.of(
+            autoValueProcessor, new AutoOneOfProcessor(), new AutoAnnotationProcessor());
+    task.setProcessors(processors);
+    assertWithMessage("Compilation should succeed").that(task.call()).isTrue();
+  }
+
+  private static ImmutableSet<File> filesUnderDirectory(File dir, Predicate<File> predicate)
+      throws IOException {
+    assertWithMessage(dir.toString()).that(dir.isDirectory()).isTrue();
+    try (Stream<Path> paths = Files.walk(dir.toPath())) {
+      return paths.map(Path::toFile).filter(predicate).collect(toImmutableSet());
+    }
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/SimpleValueTypeTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/SimpleValueTypeTest.java
new file mode 100644
index 0000000..de70dc2
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/SimpleValueTypeTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.testing.NullPointerTester;
+import java.util.Map;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class SimpleValueTypeTest {
+  @Test
+  public void testSimpleValueType() {
+    final String happy = "happy";
+    final int testInt = 23;
+    final Map<String, Long> testMap = ImmutableMap.of("happy", 23L);
+    SimpleValueType simple = SimpleValueType.create(happy, testInt, testMap);
+    assertSame(happy, simple.string());
+    assertEquals(testInt, simple.integer());
+    assertSame(testMap, simple.map());
+    assertEquals("SimpleValueType{string=happy, integer=23, map={happy=23}}", simple.toString());
+    int expectedHashCode = 1;
+    expectedHashCode = (expectedHashCode * 1000003) ^ happy.hashCode();
+    expectedHashCode = (expectedHashCode * 1000003) ^ ((Object) testInt).hashCode();
+    expectedHashCode = (expectedHashCode * 1000003) ^ testMap.hashCode();
+    assertEquals(expectedHashCode, simple.hashCode());
+  }
+
+  @Test
+  public void testNestedValueType() {
+    ImmutableMap<Integer, String> numberNames = ImmutableMap.of(1, "un", 2, "deux");
+    NestedValueType.Nested nested = NestedValueType.Nested.create(numberNames);
+    assertEquals(numberNames, nested.numberNames());
+  }
+
+  @Test
+  public void testNull() {
+    NullPointerTester tester = new NullPointerTester();
+    tester.testAllPublicStaticMethods(SimpleValueType.class);
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/annotations/Empty.java b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/Empty.java
new file mode 100644
index 0000000..cff5f13
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/Empty.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An annotation with no members, for tests, and runtime retention so it can be accessed through
+ * reflection.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Empty {}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/annotations/GwtArrays.java b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/GwtArrays.java
new file mode 100644
index 0000000..3fbc9bf
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/GwtArrays.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.annotations;
+
+import com.google.common.annotations.GwtCompatible;
+
+/**
+ * An annotation that is marked {@code @GwtCompatible} and that contains an array member.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@GwtCompatible
+public @interface GwtArrays {
+  String[] strings();
+
+  int[] ints();
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/annotations/StringValues.java b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/StringValues.java
new file mode 100644
index 0000000..9f41ff0
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/annotations/StringValues.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.annotations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * An annotation with one member, an array of strings with the default name {@code value}, and
+ * runtime retention so it can be accessed through reflection.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface StringValues {
+  String[] value();
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/enums/MyEnum.java b/value/src/it/functional/src/test/java/com/google/auto/value/enums/MyEnum.java
new file mode 100644
index 0000000..f4c2307
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/enums/MyEnum.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.enums;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+public enum MyEnum {
+  ONE,
+  TWO,
+  BUCKLE_MY_SHOE
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/gwt/CustomFieldSerializerTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/CustomFieldSerializerTest.java
new file mode 100644
index 0000000..fa1bbfb
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/CustomFieldSerializerTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.gwt;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.gwt.user.client.rpc.SerializationException;
+import com.google.gwt.user.client.rpc.SerializationStreamWriter;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests that the generated GWT serializer for GwtValueType serializes fields in the expected way.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class CustomFieldSerializerTest {
+  @Before
+  public void setUp() throws Exception {
+    MockitoAnnotations.initMocks(this);
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class ValueType implements Serializable {
+    abstract String string();
+
+    abstract int integer();
+
+    @Nullable
+    abstract ValueType other();
+
+    abstract List<ValueType> others();
+
+    static ValueType create(String string, int integer, @Nullable ValueType other) {
+      return create(string, integer, other, Collections.<ValueType>emptyList());
+    }
+
+    static ValueType create(
+        String string, int integer, @Nullable ValueType other, List<ValueType> others) {
+      return new AutoValue_CustomFieldSerializerTest_ValueType(string, integer, other, others);
+    }
+  }
+
+  private static final ValueType SIMPLE = ValueType.create("anotherstring", 1729, null);
+  private static final ValueType CONS = ValueType.create("whatever", 1296, SIMPLE);
+  private static final ValueType WITH_LIST =
+      ValueType.create("blim", 11881376, SIMPLE, ImmutableList.of(SIMPLE, CONS));
+
+  @Mock SerializationStreamWriter streamWriter;
+
+  @Test
+  public void testCustomFieldSerializer() throws SerializationException {
+    AutoValue_CustomFieldSerializerTest_ValueType withList =
+        (AutoValue_CustomFieldSerializerTest_ValueType) WITH_LIST;
+    AutoValue_CustomFieldSerializerTest_ValueType_CustomFieldSerializer.serialize(
+        streamWriter, withList);
+    verify(streamWriter).writeString("blim");
+    verify(streamWriter).writeInt(11881376);
+    verify(streamWriter).writeObject(SIMPLE);
+    verify(streamWriter).writeObject(ImmutableList.of(SIMPLE, CONS));
+    verifyNoMoreInteractions(streamWriter);
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class ValueTypeWithGetters implements Serializable {
+    abstract String getPackage();
+
+    abstract boolean isDefault();
+
+    static ValueTypeWithGetters create(String pkg, boolean dflt) {
+      return new AutoValue_CustomFieldSerializerTest_ValueTypeWithGetters(pkg, dflt);
+    }
+  }
+
+  @Test
+  public void testCustomFieldSerializerWithGetters() throws SerializationException {
+    AutoValue_CustomFieldSerializerTest_ValueTypeWithGetters instance =
+        (AutoValue_CustomFieldSerializerTest_ValueTypeWithGetters)
+            ValueTypeWithGetters.create("package", true);
+    AutoValue_CustomFieldSerializerTest_ValueTypeWithGetters_CustomFieldSerializer.serialize(
+        streamWriter, instance);
+    verify(streamWriter).writeString("package");
+    verify(streamWriter).writeBoolean(true);
+    verifyNoMoreInteractions(streamWriter);
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class GenericValueType<K extends Comparable<K>, V extends K>
+      implements Serializable {
+    abstract Map<K, V> map();
+
+    static <K extends Comparable<K>, V extends K> GenericValueType<K, V> create(Map<K, V> map) {
+      return new AutoValue_CustomFieldSerializerTest_GenericValueType<K, V>(map);
+    }
+  }
+
+  @Test
+  public void testCustomFieldSerializerGeneric() throws SerializationException {
+    Map<Integer, Integer> map = ImmutableMap.of(2, 2);
+    AutoValue_CustomFieldSerializerTest_GenericValueType<Integer, Integer> instance =
+        (AutoValue_CustomFieldSerializerTest_GenericValueType<Integer, Integer>)
+            GenericValueType.create(map);
+    AutoValue_CustomFieldSerializerTest_GenericValueType_CustomFieldSerializer.serialize(
+        streamWriter, instance);
+    verify(streamWriter).writeObject(map);
+    verifyNoMoreInteractions(streamWriter);
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class ValueTypeWithBuilder implements Serializable {
+    abstract String string();
+
+    abstract ImmutableList<String> strings();
+
+    static Builder builder() {
+      return new AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    interface Builder {
+      Builder string(String x);
+
+      Builder strings(ImmutableList<String> x);
+
+      ValueTypeWithBuilder build();
+    }
+  }
+
+  @Test
+  public void testCustomFieldSerializerWithBuilder() throws SerializationException {
+    AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilder instance =
+        (AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilder)
+            ValueTypeWithBuilder.builder().string("s").strings(ImmutableList.of("a", "b")).build();
+    AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilder_CustomFieldSerializer.serialize(
+        streamWriter, instance);
+    verify(streamWriter).writeString("s");
+    verify(streamWriter).writeObject(ImmutableList.of("a", "b"));
+    verifyNoMoreInteractions(streamWriter);
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class ValueTypeWithBuilderAndGetters implements Serializable {
+    abstract String getPackage();
+
+    abstract boolean isDefault();
+
+    static Builder builder() {
+      return new AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilderAndGetters.Builder();
+    }
+
+    @AutoValue.Builder
+    interface Builder {
+      Builder setPackage(String x);
+
+      Builder setDefault(boolean x);
+
+      ValueTypeWithBuilderAndGetters build();
+    }
+  }
+
+  @Test
+  public void testCustomFieldSerializerWithBuilderAndGetters() throws SerializationException {
+    AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilderAndGetters instance =
+        (AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilderAndGetters)
+            ValueTypeWithBuilderAndGetters.builder().setPackage("s").setDefault(false).build();
+    AutoValue_CustomFieldSerializerTest_ValueTypeWithBuilderAndGetters_CustomFieldSerializer
+        .serialize(streamWriter, instance);
+    verify(streamWriter).writeString("s");
+    verify(streamWriter).writeBoolean(false);
+    verifyNoMoreInteractions(streamWriter);
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class GenericValueTypeWithBuilder<K extends Comparable<K>, V extends K>
+      implements Serializable {
+    abstract Map<K, V> map();
+
+    static <K extends Comparable<K>, V extends K> Builder<K, V> builder() {
+      return new AutoValue_CustomFieldSerializerTest_GenericValueTypeWithBuilder.Builder<K, V>();
+    }
+
+    @AutoValue.Builder
+    interface Builder<K extends Comparable<K>, V extends K> {
+      Builder<K, V> map(Map<K, V> map);
+
+      GenericValueTypeWithBuilder<K, V> build();
+    }
+  }
+
+  @Test
+  public void testCustomFieldSerializerGenericWithBuilder() throws SerializationException {
+    Map<Integer, Integer> map = ImmutableMap.of(2, 2);
+    AutoValue_CustomFieldSerializerTest_GenericValueTypeWithBuilder<Integer, Integer> instance =
+        (AutoValue_CustomFieldSerializerTest_GenericValueTypeWithBuilder<Integer, Integer>)
+            GenericValueTypeWithBuilder.<Integer, Integer>builder().map(map).build();
+    AutoValue_CustomFieldSerializerTest_GenericValueTypeWithBuilder_CustomFieldSerializer.serialize(
+        streamWriter, instance);
+    verify(streamWriter).writeObject(map);
+    verifyNoMoreInteractions(streamWriter);
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/gwt/EmptyExtension.java b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/EmptyExtension.java
new file mode 100644
index 0000000..0476906
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/EmptyExtension.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.gwt;
+
+import static java.util.stream.Collectors.joining;
+
+import com.google.auto.service.AutoService;
+import com.google.auto.value.extension.AutoValueExtension;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.escapevelocity.Template;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * An AutoValue extension that generates a subclass that does nothing useful.
+ */
+@AutoService(AutoValueExtension.class)
+public class EmptyExtension extends AutoValueExtension {
+  // TODO(emcmanus): it is way too difficult to write a trivial extension. Problems we have here:
+  //   (1) We have to generate a constructor that calls the superclass constructor, which means
+  //       declaring the appropriate constructor parameters and then forwarding them to a super
+  //       call.
+  //   (2) We have to avoid generating variable names that are keywords (we append $ here
+  //       to avoid that).
+  //   (3) We have to concoct appropriate type parameter strings, for example
+  //       final class AutoValue_Foo<K extends Comparable<K>, V> extends $AutoValue_Foo<K, V>.
+  //   These problems show up with the template approach here, but also using JavaPoet as the
+  //   Memoize extension does.
+  private static final ImmutableList<String> TEMPLATE_LINES =
+      ImmutableList.of(
+          "package $package;",
+          "\n",
+          "#if ($isFinal) final #end class ${className}${formalTypes}"
+              + " extends ${classToExtend}${actualTypes} {\n",
+          "  ${className}(",
+          "    #foreach ($property in $propertyTypes.keySet())",
+          "    $propertyTypes[$property] ${property}$ #if ($foreach.hasNext) , #end",
+          "    #end",
+          "  ) {",
+          "    super(",
+          "      #foreach ($property in $propertyTypes.keySet())",
+          "      ${property}$ #if ($foreach.hasNext) , #end",
+          "      #end",
+          "    );",
+          "  }",
+          "}");
+
+  @Override
+  public boolean applicable(Context context) {
+    return true;
+  }
+
+  @Override
+  public String generateClass(
+      Context context, String className, String classToExtend, boolean isFinal) {
+    String templateString = Joiner.on('\n').join(TEMPLATE_LINES);
+    StringReader templateReader = new StringReader(templateString);
+    Template template;
+    try {
+      template = Template.parseFrom(templateReader);
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+    TypeElement autoValueClass = context.autoValueClass();
+    ImmutableMap<String, Object> vars =
+        ImmutableMap.<String, Object>builder()
+            .put("package", context.packageName())
+            .put("className", className)
+            .put("classToExtend", classToExtend)
+            .put("isFinal", isFinal)
+            .put("propertyTypes", context.propertyTypes())
+            .put("formalTypes", formalTypeParametersString(autoValueClass))
+            .put("actualTypes", actualTypeParametersString(autoValueClass))
+            .build();
+    return template.evaluate(vars);
+  }
+
+  private static String actualTypeParametersString(TypeElement type) {
+    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();
+    if (typeParameters.isEmpty()) {
+      return "";
+    }
+    return typeParameters
+        .stream()
+        .map(e -> e.getSimpleName().toString())
+        .collect(joining(", ", "<", ">"));
+  }
+
+  private static String formalTypeParametersString(TypeElement type) {
+    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();
+    if (typeParameters.isEmpty()) {
+      return "";
+    }
+    StringBuilder sb = new StringBuilder("<");
+    String sep = "";
+    for (TypeParameterElement typeParameter : typeParameters) {
+      sb.append(sep);
+      sep = ", ";
+      appendTypeParameterWithBounds(typeParameter, sb);
+    }
+    return sb.append(">").toString();
+  }
+
+  private static void appendTypeParameterWithBounds(
+      TypeParameterElement typeParameter, StringBuilder sb) {
+    sb.append(typeParameter.getSimpleName());
+    String sep = " extends ";
+    for (TypeMirror bound : typeParameter.getBounds()) {
+      if (!bound.toString().equals("java.lang.Object")) {
+        sb.append(sep);
+        sep = " & ";
+        sb.append(bound);
+      }
+    }
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtCompilationTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtCompilationTest.java
new file mode 100644
index 0000000..6a48b35
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtCompilationTest.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.gwt;
+
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+
+import com.google.auto.value.processor.AutoValueProcessor;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.JavaFileObjects;
+import javax.lang.model.SourceVersion;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test of generated source for GWT serialization classes.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class GwtCompilationTest {
+  private static final JavaFileObject GWT_COMPATIBLE =
+      JavaFileObjects.forSourceLines(
+          "com.google.annotations.GwtCompatible",
+          "package com.google.annotations;",
+          "",
+          "public @interface GwtCompatible {",
+          "  boolean serializable() default false;",
+          "}");
+
+  /**
+   * Test where the serialized properties don't include generics, so no {@code @SuppressWarnings}
+   * annotation is needed. We explicitly check that one is not included anyway, because Eclipse for
+   * example can be configured to complain about unnecessary warning suppression.
+   */
+  @Test
+  public void testBasic() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.annotations.GwtCompatible;",
+            "",
+            "@AutoValue",
+            "@GwtCompatible(serializable = true)",
+            "public abstract class Baz {",
+            "  public abstract int buh();",
+            "",
+            "  public static Baz create(int buh) {",
+            "    return new AutoValue_Baz(buh);",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoValue_Baz_CustomFieldSerializer",
+            "package foo.bar;",
+            "",
+            "import com.google.gwt.user.client.rpc.CustomFieldSerializer;",
+            "import com.google.gwt.user.client.rpc.SerializationException;",
+            "import com.google.gwt.user.client.rpc.SerializationStreamReader;",
+            "import com.google.gwt.user.client.rpc.SerializationStreamWriter;",
+            "import " + generatedAnnotationType() + ";",
+            "",
+            "@Generated(\"com.google.auto.value.processor.AutoValueProcessor\")",
+            "public final class AutoValue_Baz_CustomFieldSerializer"
+                + " extends CustomFieldSerializer<AutoValue_Baz> {",
+            "",
+            "  public static AutoValue_Baz instantiate(",
+            "      SerializationStreamReader streamReader) throws SerializationException {",
+            "    int buh = streamReader.readInt();",
+            "    return new AutoValue_Baz(buh);",
+            "  }",
+            "",
+            "  public static void serialize(",
+            "      SerializationStreamWriter streamWriter,",
+            "      AutoValue_Baz instance) throws SerializationException {",
+            "    streamWriter.writeInt(instance.buh());",
+            "  }",
+            "",
+            "  public static void deserialize(",
+            "      @SuppressWarnings(\"unused\") SerializationStreamReader streamReader,",
+            "      @SuppressWarnings(\"unused\") AutoValue_Baz instance) {",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"unused\") private int dummy_3f8e1b04;",
+            "",
+            "  @Override",
+            "  public void deserializeInstance(",
+            "      SerializationStreamReader streamReader,",
+            "      AutoValue_Baz instance) {",
+            "    deserialize(streamReader, instance);",
+            "  }",
+            "",
+            "  @Override",
+            "  public boolean hasCustomInstantiateInstance() {",
+            "    return true;",
+            "  }",
+            "",
+            "  @Override",
+            "  public AutoValue_Baz instantiateInstance(",
+            "      SerializationStreamReader streamReader) throws SerializationException {",
+            "    return instantiate(streamReader);",
+            "  }",
+            "",
+            "  @Override",
+            "  public void serializeInstance(",
+            "    SerializationStreamWriter streamWriter,",
+            "    AutoValue_Baz instance) throws SerializationException {",
+            "    serialize(streamWriter, instance);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject, GWT_COMPATIBLE);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz_CustomFieldSerializer")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  /**
+   * Test where the serialized properties don't include generics, so a {@code @SuppressWarnings}
+   * annotation is needed.
+   */
+  @Test
+  public void testSuppressWarnings() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.annotations.GwtCompatible;",
+            "",
+            "import java.util.List;",
+            "",
+            "@AutoValue",
+            "@GwtCompatible(serializable = true)",
+            "public abstract class Baz {",
+            "  public abstract List<String> buh();",
+            "",
+            "  public static Baz create(List<String> buh) {",
+            "    return new AutoValue_Baz(buh);",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoValue_Baz_CustomFieldSerializer",
+            "package foo.bar;",
+            "",
+            "import com.google.gwt.user.client.rpc.CustomFieldSerializer;",
+            "import com.google.gwt.user.client.rpc.SerializationException;",
+            "import com.google.gwt.user.client.rpc.SerializationStreamReader;",
+            "import com.google.gwt.user.client.rpc.SerializationStreamWriter;",
+            "import java.util.List;",
+            "import " + generatedAnnotationType() + ";",
+            "",
+            "@Generated(\"com.google.auto.value.processor.AutoValueProcessor\")",
+            "public final class AutoValue_Baz_CustomFieldSerializer"
+                + " extends CustomFieldSerializer<AutoValue_Baz> {",
+            "",
+            "  public static AutoValue_Baz instantiate(",
+            "      SerializationStreamReader streamReader) throws SerializationException {",
+            "    @SuppressWarnings(\"unchecked\")",
+            "    List<String> buh = (List<String>) streamReader.readObject();",
+            "    return new AutoValue_Baz(buh);",
+            "  }",
+            "",
+            "  public static void serialize(",
+            "      SerializationStreamWriter streamWriter,",
+            "      AutoValue_Baz instance) throws SerializationException {",
+            "    streamWriter.writeObject(instance.buh());",
+            "  }",
+            "",
+            "  public static void deserialize(",
+            "      @SuppressWarnings(\"unused\") SerializationStreamReader streamReader,",
+            "      @SuppressWarnings(\"unused\") AutoValue_Baz instance) {",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"unused\") private int dummy_949e312e;",
+            "",
+            "  @Override",
+            "  public void deserializeInstance(",
+            "      SerializationStreamReader streamReader,",
+            "      AutoValue_Baz instance) {",
+            "    deserialize(streamReader, instance);",
+            "  }",
+            "",
+            "  @Override",
+            "  public boolean hasCustomInstantiateInstance() {",
+            "    return true;",
+            "  }",
+            "",
+            "  @Override",
+            "  public AutoValue_Baz instantiateInstance(",
+            "      SerializationStreamReader streamReader) throws SerializationException {",
+            "    return instantiate(streamReader);",
+            "  }",
+            "",
+            "  @Override",
+            "  public void serializeInstance(",
+            "    SerializationStreamWriter streamWriter,",
+            "    AutoValue_Baz instance) throws SerializationException {",
+            "    serialize(streamWriter, instance);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject, GWT_COMPATIBLE);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz_CustomFieldSerializer")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  /**
+   * Test builders and classes that are generic (as opposed to just containing properties with
+   * generics).
+   */
+  @Test
+  public void testBuildersAndGenerics() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.annotations.GwtCompatible;",
+            "import com.google.common.collect.ImmutableMap;",
+            "import java.util.Map;",
+            "",
+            "@AutoValue",
+            "@GwtCompatible(serializable = true)",
+            "public abstract class Baz<K extends Comparable<K>, V extends K> {",
+            "  public abstract Map<K, V> map();",
+            "  public abstract ImmutableMap<K, V> immutableMap();",
+            "",
+            "  public static <K extends Comparable<K>, V extends K> Builder<K, V> builder() {",
+            "    return new AutoValue_Baz.Builder<K, V>();",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<K extends Comparable<K>, V extends K> {",
+            "    Builder<K, V> map(Map<K, V> map);",
+            "    ImmutableMap.Builder<K, V> immutableMapBuilder();",
+            "    Baz<K, V> build();",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoValue_Baz_CustomFieldSerializer",
+            "package foo.bar;",
+            "",
+            "import com.google.common.collect.ImmutableMap;",
+            "import com.google.gwt.user.client.rpc.CustomFieldSerializer;",
+            "import com.google.gwt.user.client.rpc.SerializationException;",
+            "import com.google.gwt.user.client.rpc.SerializationStreamReader;",
+            "import com.google.gwt.user.client.rpc.SerializationStreamWriter;",
+            "import java.util.Map;",
+            "import " + generatedAnnotationType() + ";",
+            "",
+            "@Generated(\"com.google.auto.value.processor.AutoValueProcessor\")",
+            "public final class AutoValue_Baz_CustomFieldSerializer"
+                + "<K extends Comparable<K>, V extends K>"
+                + " extends CustomFieldSerializer<AutoValue_Baz<K, V>> {",
+            "",
+            "  public static <K extends Comparable<K>, V extends K> AutoValue_Baz<K, V>"
+                + " instantiate(",
+            "      SerializationStreamReader streamReader) throws SerializationException {",
+            "    @SuppressWarnings(\"unchecked\")",
+            "    Map<K, V> map = (Map<K, V>) streamReader.readObject();",
+            "    @SuppressWarnings(\"unchecked\")",
+            "    ImmutableMap<K, V> immutableMap = (ImmutableMap<K, V>) streamReader.readObject();",
+            "    AutoValue_Baz.Builder<K, V> builder$ = new AutoValue_Baz.Builder<K, V>();",
+            "    builder$.map(map);",
+            "    builder$.immutableMapBuilder().putAll(immutableMap);",
+            "    return (AutoValue_Baz<K, V>) builder$.build();",
+            "  }",
+            "",
+            "  public static <K extends Comparable<K>, V extends K> void serialize(",
+            "      SerializationStreamWriter streamWriter,",
+            "      AutoValue_Baz<K, V> instance) throws SerializationException {",
+            "    streamWriter.writeObject(instance.map());",
+            "    streamWriter.writeObject(instance.immutableMap());",
+            "  }",
+            "",
+            "  public static <K extends Comparable<K>, V extends K> void deserialize(",
+            "      @SuppressWarnings(\"unused\") SerializationStreamReader streamReader,",
+            "      @SuppressWarnings(\"unused\") AutoValue_Baz<K, V> instance) {",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"unused\")",
+            "  private int dummy_2865d9ec;",
+            "",
+            "  @Override",
+            "  public void deserializeInstance(",
+            "      SerializationStreamReader streamReader,",
+            "      AutoValue_Baz<K, V> instance) {",
+            "    deserialize(streamReader, instance);",
+            "  }",
+            "",
+            "  @Override",
+            "  public boolean hasCustomInstantiateInstance() {",
+            "    return true;",
+            "  }",
+            "",
+            "  @Override",
+            "  public AutoValue_Baz<K, V> instantiateInstance(",
+            "      SerializationStreamReader streamReader) throws SerializationException {",
+            "    return instantiate(streamReader);",
+            "  }",
+            "",
+            "  @Override",
+            "  public void serializeInstance(",
+            "    SerializationStreamWriter streamWriter,",
+            "    AutoValue_Baz<K, V> instance) throws SerializationException {",
+            "    serialize(streamWriter, instance);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject, GWT_COMPATIBLE);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz_CustomFieldSerializer")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  private String generatedAnnotationType() {
+    return isJavaxAnnotationProcessingGeneratedAvailable()
+        ? "javax.annotation.processing.Generated"
+        : "javax.annotation.Generated";
+  }
+
+  private boolean isJavaxAnnotationProcessingGeneratedAvailable() {
+    return SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0;
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtValueType.java b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtValueType.java
new file mode 100644
index 0000000..b015ac9
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtValueType.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.gwt;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.annotations.GwtCompatible;
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/**
+ * A class that is serializable with both Java and GWT serialization.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@AutoValue
+@GwtCompatible(serializable = true)
+abstract class GwtValueType implements Serializable {
+  abstract String string();
+
+  abstract int integer();
+
+  @Nullable
+  abstract GwtValueType other();
+
+  abstract List<GwtValueType> others();
+
+  static GwtValueType create(String string, int integer, @Nullable GwtValueType other) {
+    return create(string, integer, other, Collections.<GwtValueType>emptyList());
+  }
+
+  static GwtValueType create(
+      String string, int integer, @Nullable GwtValueType other, List<GwtValueType> others) {
+    return new AutoValue_GwtValueType(string, integer, other, others);
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtValueTypeWithBuilder.java b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtValueTypeWithBuilder.java
new file mode 100644
index 0000000..781e537
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/GwtValueTypeWithBuilder.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.gwt;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.collect.ImmutableList;
+import java.io.Serializable;
+import java.util.List;
+import javax.annotation.Nullable;
+
+/**
+ * A class that is serializable with both Java and GWT serialization.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@AutoValue
+@GwtCompatible(serializable = true)
+abstract class GwtValueTypeWithBuilder<T> implements Serializable {
+  abstract String string();
+
+  abstract int integer();
+
+  @Nullable
+  abstract GwtValueTypeWithBuilder<T> other();
+
+  abstract List<GwtValueTypeWithBuilder<T>> others();
+
+  abstract ImmutableList<T> list();
+
+  abstract ImmutableList<T> otherList();
+
+  abstract ImmutableList<String> listWithBuilder();
+
+  static <T> Builder<T> builder() {
+    return new AutoValue_GwtValueTypeWithBuilder.Builder<T>();
+  }
+
+  @AutoValue.Builder
+  interface Builder<T> {
+    Builder<T> string(String x);
+
+    Builder<T> integer(int x);
+
+    Builder<T> other(@Nullable GwtValueTypeWithBuilder<T> x);
+
+    Builder<T> others(List<GwtValueTypeWithBuilder<T>> x);
+
+    Builder<T> list(ImmutableList<T> x);
+
+    Builder<T> otherList(List<T> x);
+
+    ImmutableList.Builder<String> listWithBuilderBuilder();
+
+    GwtValueTypeWithBuilder<T> build();
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/gwt/NonSerializableGwtValueType.java b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/NonSerializableGwtValueType.java
new file mode 100644
index 0000000..565b1d4
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/NonSerializableGwtValueType.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.gwt;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.annotations.GwtCompatible;
+import java.io.Serializable;
+
+/**
+ * A class that is serializable with native Java serialization but not with GWT serialization.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@AutoValue
+@GwtCompatible
+abstract class NonSerializableGwtValueType implements Serializable {
+  abstract String string();
+
+  abstract int integer();
+
+  static NonSerializableGwtValueType create(String string, int integer) {
+    return new AutoValue_NonSerializableGwtValueType(string, integer);
+  }
+}
diff --git a/value/src/it/functional/src/test/java/com/google/auto/value/gwt/SerialSignatureTest.java b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/SerialSignatureTest.java
new file mode 100644
index 0000000..65067fb
--- /dev/null
+++ b/value/src/it/functional/src/test/java/com/google/auto/value/gwt/SerialSignatureTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.gwt;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.annotations.GwtCompatible;
+import java.lang.reflect.Field;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests that the generated serializer class for a GWT-serializable class contains a dummy field to
+ * influence the signature, and that different classes have different signatures.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class SerialSignatureTest {
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class One {
+    abstract int foo();
+
+    static One create(int foo) {
+      return new AutoValue_SerialSignatureTest_One(foo);
+    }
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class Two {
+    abstract int foo();
+
+    static Two create(int foo) {
+      return new AutoValue_SerialSignatureTest_Two(foo);
+    }
+  }
+
+  @Test
+  public void testSerialSignatures() {
+    Class<?> serializerOne = AutoValue_SerialSignatureTest_One_CustomFieldSerializer.class;
+    Class<?> serializerTwo = AutoValue_SerialSignatureTest_Two_CustomFieldSerializer.class;
+    String fieldNameOne = dummySignatureFieldName(serializerOne);
+    String fieldNameTwo = dummySignatureFieldName(serializerTwo);
+    assertFalse(fieldNameOne.equals(fieldNameTwo));
+  }
+
+  private static String dummySignatureFieldName(Class<?> c) {
+    String name = null;
+    for (Field f : c.getDeclaredFields()) {
+      if (f.getName().startsWith("dummy_")) {
+        assertNull("More than one field begins with dummy_: " + name + ", " + f.getName(), name);
+      }
+      name = f.getName();
+    }
+    assertNotNull("No field begins with dummy_", name);
+    return name;
+  }
+}
diff --git a/value/src/it/gwtserializer/invoker.properties b/value/src/it/gwtserializer/invoker.properties
new file mode 100644
index 0000000..e2a44e3
--- /dev/null
+++ b/value/src/it/gwtserializer/invoker.properties
@@ -0,0 +1 @@
+invoker.goals = clean verify
diff --git a/value/src/it/gwtserializer/pom.xml b/value/src/it/gwtserializer/pom.xml
new file mode 100644
index 0000000..cd56484
--- /dev/null
+++ b/value/src/it/gwtserializer/pom.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2015 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<!-- TODO(gak): see if we can manage these dependencies any better -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.google.auto.value</groupId>
+    <artifactId>auto-value-parent</artifactId>
+    <version>HEAD-SNAPSHOT</version>
+    <relativePath>../../../pom.xml</relativePath>
+  </parent>
+  <url>https://github.com/google/auto/tree/master/value</url>
+
+  <groupId>com.google.auto.value.it.gwtserializer</groupId>
+  <artifactId>gwtserializer</artifactId>
+  <version>HEAD-SNAPSHOT</version>
+  <name>Auto-Value GWT-RPC Serialization Integration Test</name>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>com.google.gwt</groupId>
+        <artifactId>gwt</artifactId>
+        <version>2.8.2</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+  <dependencies>
+    <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value-annotations</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.google.auto.value</groupId>
+      <artifactId>auto-value</artifactId>
+      <version>${project.version}</version>
+      <optional>true</optional>
+    </dependency>
+    <dependency>
+      <groupId>com.google.gwt</groupId>
+      <artifactId>gwt-user</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.gwt</groupId>
+      <artifactId>gwt-dev</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava-gwt</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <testResources>
+      <testResource>
+        <directory>src/test/java</directory>
+      </testResource>
+      <testResource>
+        <directory>${project.build.directory}/generated-test-sources/test-annotations</directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.7.0</version>
+        <dependencies>
+          <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-java</artifactId>
+            <version>0.9.4</version>
+          </dependency>
+        </dependencies>
+        <configuration>
+          <source>1.7</source>
+          <target>1.7</target>
+          <compilerArgument>-Xlint:all</compilerArgument>
+          <showWarnings>true</showWarnings>
+          <showDeprecation>true</showDeprecation>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <skipTests>true</skipTests>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-resources-plugin</artifactId>
+        <version>3.0.2</version>
+        <executions>
+          <execution>
+            <!-- postpone resources:testResources until after compiler:testCompile to get generated sources -->
+            <id>default-testResources</id>
+            <phase>process-test-classes</phase>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>net.ltgt.gwt.maven</groupId>
+        <artifactId>gwt-maven-plugin</artifactId>
+        <version>1.0-rc-6</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-deploy-plugin</artifactId>
+        <version>2.7</version>
+        <configuration>
+          <!-- Build/test, but don't deploy -->
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/value/src/it/gwtserializer/src/test/java/com/google/auto/value/GwtSerializerSuite.gwt.xml b/value/src/it/gwtserializer/src/test/java/com/google/auto/value/GwtSerializerSuite.gwt.xml
new file mode 100644
index 0000000..e556933
--- /dev/null
+++ b/value/src/it/gwtserializer/src/test/java/com/google/auto/value/GwtSerializerSuite.gwt.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Copyright 2015 Google LLC
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       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.
+-->
+<module>
+  <inherits name="com.google.gwt.user.User" />
+
+  <servlet path="/test" class="com.google.auto.value.client.GwtSerializerTest$TestServiceImpl" />
+</module>
diff --git a/value/src/it/gwtserializer/src/test/java/com/google/auto/value/GwtSerializerSuite.java b/value/src/it/gwtserializer/src/test/java/com/google/auto/value/GwtSerializerSuite.java
new file mode 100644
index 0000000..f0b4087
--- /dev/null
+++ b/value/src/it/gwtserializer/src/test/java/com/google/auto/value/GwtSerializerSuite.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import com.google.auto.value.client.GwtSerializerTest;
+import com.google.gwt.junit.tools.GWTTestSuite;
+import junit.framework.Test;
+
+public class GwtSerializerSuite {
+  public static Test suite() {
+    GWTTestSuite suite = new GWTTestSuite();
+
+    suite.addTestSuite(GwtSerializerTest.class);
+
+    return suite;
+  }
+}
diff --git a/value/src/it/gwtserializer/src/test/java/com/google/auto/value/client/GwtSerializerTest.java b/value/src/it/gwtserializer/src/test/java/com/google/auto/value/client/GwtSerializerTest.java
new file mode 100644
index 0000000..ca2be17
--- /dev/null
+++ b/value/src/it/gwtserializer/src/test/java/com/google/auto/value/client/GwtSerializerTest.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.client;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.annotations.GwtCompatible;
+import com.google.common.annotations.GwtIncompatible;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.gwt.user.client.rpc.RemoteService;
+import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
+import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+
+public class GwtSerializerTest extends GWTTestCase {
+
+  @RemoteServiceRelativePath("test")
+  public interface TestService extends RemoteService {
+    Simple echo(Simple simple);
+
+    SimpleWithBuilder echo(SimpleWithBuilder simple);
+
+    Nested echo(Nested nested);
+
+    NestedWithBuilder echo(NestedWithBuilder nested);
+
+    Generics<Simple> echo(Generics<Simple> generics);
+
+    GenericsWithBuilder<SimpleWithBuilder> echo(GenericsWithBuilder<SimpleWithBuilder> generics);
+  }
+
+  interface TestServiceAsync {
+    void echo(Simple simple, AsyncCallback<Simple> callback);
+
+    void echo(SimpleWithBuilder simple, AsyncCallback<SimpleWithBuilder> callback);
+
+    void echo(Nested nested, AsyncCallback<Nested> callback);
+
+    void echo(NestedWithBuilder nested, AsyncCallback<NestedWithBuilder> callback);
+
+    void echo(Generics<Simple> generics, AsyncCallback<Generics<Simple>> callback);
+
+    void echo(
+        GenericsWithBuilder<SimpleWithBuilder> generics,
+        AsyncCallback<GenericsWithBuilder<SimpleWithBuilder>> callback);
+  }
+
+  class AssertEqualsCallback<T> implements AsyncCallback<T> {
+    private final T expected;
+
+    AssertEqualsCallback(T expected) {
+      this.expected = expected;
+    }
+
+    @Override
+    public void onSuccess(T actual) {
+      assertEquals(expected, actual);
+      finishTest();
+    }
+
+    @Override
+    public void onFailure(Throwable caught) {
+      fail();
+    }
+  }
+
+  @GwtIncompatible("RemoteServiceServlet")
+  @SuppressWarnings("serial")
+  public static class TestServiceImpl extends RemoteServiceServlet implements TestService {
+    @Override
+    public Simple echo(Simple simple) {
+      return Simple.create(simple.message());
+    }
+
+    @Override
+    public SimpleWithBuilder echo(SimpleWithBuilder simple) {
+      return SimpleWithBuilder.builder().message(simple.message()).build();
+    }
+
+    @Override
+    public Nested echo(Nested nested) {
+      return Nested.create(nested.message(), echo(nested.simple()));
+    }
+
+    @Override
+    public NestedWithBuilder echo(NestedWithBuilder nested) {
+      return NestedWithBuilder.builder()
+          .message(nested.message())
+          .simple(echo(nested.simple()))
+          .build();
+    }
+
+    @Override
+    public Generics<Simple> echo(Generics<Simple> generics) {
+      return Generics.create(echo(generics.simple()));
+    }
+
+    @Override
+    public GenericsWithBuilder<SimpleWithBuilder> echo(
+        GenericsWithBuilder<SimpleWithBuilder> generics) {
+      return GenericsWithBuilder.<SimpleWithBuilder>builder()
+          .simple(echo(generics.simple()))
+          .build();
+    }
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class Simple {
+    public abstract String message();
+
+    public static Simple create(String message) {
+      return new AutoValue_GwtSerializerTest_Simple(message);
+    }
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class SimpleWithBuilder {
+    public abstract String message();
+
+    public static Builder builder() {
+      return new AutoValue_GwtSerializerTest_SimpleWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder message(String message);
+
+      SimpleWithBuilder build();
+    }
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class Nested {
+    public abstract String message();
+
+    public abstract Simple simple();
+
+    public static Nested create(String message, Simple simple) {
+      return new AutoValue_GwtSerializerTest_Nested(message, simple);
+    }
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class NestedWithBuilder {
+    public abstract String message();
+
+    public abstract SimpleWithBuilder simple();
+
+    public static Builder builder() {
+      return new AutoValue_GwtSerializerTest_NestedWithBuilder.Builder();
+    }
+
+    @AutoValue.Builder
+    public interface Builder {
+      Builder message(String message);
+
+      Builder simple(SimpleWithBuilder simple);
+
+      NestedWithBuilder build();
+    }
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class Generics<T> {
+    public abstract T simple();
+
+    public static <T> Generics<T> create(T simple) {
+      return new AutoValue_GwtSerializerTest_Generics<T>(simple);
+    }
+  }
+
+  @AutoValue
+  @GwtCompatible(serializable = true)
+  abstract static class GenericsWithBuilder<T> {
+    public abstract T simple();
+
+    public static <T> Builder<T> builder() {
+      return new AutoValue_GwtSerializerTest_GenericsWithBuilder.Builder<T>();
+    }
+
+    @AutoValue.Builder
+    public interface Builder<T> {
+      Builder<T> simple(T simple);
+
+      GenericsWithBuilder<T> build();
+    }
+  }
+
+  private TestServiceAsync testService;
+
+  @Override
+  public String getModuleName() {
+    return "com.google.auto.value.GwtSerializerSuite";
+  }
+
+  @Override
+  public void gwtSetUp() {
+    testService = GWT.create(TestService.class);
+  }
+
+  public void testSimple() {
+    delayTestFinish(2000);
+    Simple simple = Simple.create("able");
+    testService.echo(simple, new AssertEqualsCallback<Simple>(simple));
+  }
+
+  public void testSimpleWithBuilder() {
+    delayTestFinish(2000);
+    SimpleWithBuilder simple = SimpleWithBuilder.builder().message("able").build();
+    testService.echo(simple, new AssertEqualsCallback<SimpleWithBuilder>(simple));
+  }
+
+  public void testNested() {
+    delayTestFinish(2000);
+    Nested nested = Nested.create("able", Simple.create("baker"));
+    testService.echo(nested, new AssertEqualsCallback<Nested>(nested));
+  }
+
+  public void testNestedWithBuilder() {
+    delayTestFinish(2000);
+    NestedWithBuilder nested =
+        NestedWithBuilder.builder()
+            .message("able")
+            .simple(SimpleWithBuilder.builder().message("baker").build())
+            .build();
+    testService.echo(nested, new AssertEqualsCallback<NestedWithBuilder>(nested));
+  }
+
+  public void testGenerics() {
+    delayTestFinish(2000);
+    Generics<Simple> generics = Generics.create(Simple.create("able"));
+    testService.echo(generics, new AssertEqualsCallback<Generics<Simple>>(generics));
+  }
+
+  public void testGenericsWithBuilder() {
+    delayTestFinish(2000);
+    GenericsWithBuilder<SimpleWithBuilder> generics =
+        GenericsWithBuilder.<SimpleWithBuilder>builder()
+            .simple(SimpleWithBuilder.builder().message("able").build())
+            .build();
+    testService.echo(
+        generics, new AssertEqualsCallback<GenericsWithBuilder<SimpleWithBuilder>>(generics));
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/AutoAnnotation.java b/value/src/main/java/com/google/auto/value/AutoAnnotation.java
new file mode 100644
index 0000000..d36d8e2
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/AutoAnnotation.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.AnnotatedElement;
+
+/**
+ * Annotation that causes an implementation of an annotation interface to be generated. The
+ * annotation is applied to a method whose return type is an annotation interface. The method can
+ * then create and return an instance of the generated class that conforms to the specification of
+ * {@link Annotation}, in particular as regards {@link Annotation#equals equals} and {@link
+ * Annotation#hashCode hashCode}. These instances behave essentially the same as instances returned
+ * by {@link AnnotatedElement#getAnnotation}.
+ *
+ * <p>For example, suppose you have an annotation like this:
+ *
+ * <pre>
+ * package com.google.inject.name;
+ *
+ * public &#64;interface Named {
+ *   String value();
+ * }</pre>
+ *
+ * <p>You could write a method like this to construct implementations of the interface:
+ *
+ * <pre>
+ * package com.example;
+ *
+ * public class Names {
+ *   &#64;AutoAnnotation public static Named named(String value) {
+ *     return new AutoAnnotation_Names_named(value);
+ *   }
+ * }</pre>
+ *
+ * <p>Because the annotated method is called {@code Names.named}, the generated class is called
+ * {@code AutoAnnotation_Names_named} in the same package. If the annotated method were in a nested
+ * class, for example {@code Outer.Names.named}, then the generated class would be called {@code
+ * AutoAnnotation_Outer_Names_named}. The generated class is package-private and it is not expected
+ * that it will be referenced outside the {@code @AutoAnnotation} method.
+ *
+ * <p>The names and types of the parameters in the annotated method must be the same as the names
+ * and types of the annotation elements, except that elements which have default values can be
+ * omitted. The parameters do not need to be in any particular order.
+ *
+ * <p>The annotated method does not need to be public. It can have any visibility, including
+ * private. This means the method can be a private implementation called by a public method with a
+ * different API, for example using a builder.
+ *
+ * <p>It is a compile-time error if more than one method with the same name in the same class is
+ * annotated {@code @AutoAnnotation}.
+ *
+ * <p>The constructor of the generated class has the same parameters as the {@code @AutoAnnotation}
+ * method. It will throw {@code NullPointerException} if any parameter is null. In order to
+ * guarantee that the constructed object is immutable, the constructor will clone each array
+ * parameter corresponding to an array-valued annotation member, and the implementation of each such
+ * member will also return a clone of the array.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface AutoAnnotation {}
diff --git a/value/src/main/java/com/google/auto/value/AutoOneOf.java b/value/src/main/java/com/google/auto/value/AutoOneOf.java
new file mode 100644
index 0000000..064b777
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/AutoOneOf.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Specifies that the annotated class is a <em>one-of</em> class, also known as a <a
+ * href="https://en.wikipedia.org/wiki/Tagged_union"><em>tagged union</em></a>. An
+ * {@code @AutoOneOf} class is very similar to an {@link AutoValue @AutoValue} class, in that its
+ * abstract methods define a set of properties. But unlike {@code @AutoValue}, only one of those
+ * properties is defined in any given instance.
+ *
+ * <pre>{@code @AutoOneOf(StringOrInteger.Kind.class)
+ * public abstract class StringOrInteger {
+ *   public enum Kind {STRING, INTEGER}
+ *
+ *   public abstract Kind getKind();
+ *
+ *   public abstract String string();
+ *   public abstract int integer();
+ *
+ *   public static StringOrInteger ofString(String s) {
+ *     return AutoOneOf_StringOrInteger.string(s);
+ *   }
+ *
+ *   public static StringOrInteger ofInteger(int i) {
+ *     return AutoOneOf_StringOrInteger.integer(i);
+ *   }
+ * }
+ *
+ * String client(StringOrInteger stringOrInteger) {
+ *   switch (stringOrInteger.getKind()) {
+ *     case STRING:
+ *       return "the string '" + stringOrInteger.string() + "'";
+ *     case INTEGER:
+ *       return "the integer " + stringOrInteger.integer();
+ *   }
+ *   throw new AssertionError();
+ * }}</pre>
+ *
+ * <p>{@code @AutoOneOf} is explained in more detail in the <a
+ * href="https://github.com/google/auto/blob/master/value/userguide/howto.md#oneof">user guide</a>.
+ *
+ * @author Chris Nokleberg
+ * @author Éamonn McManus
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface AutoOneOf {
+  /** Specifies an enum that has one entry per variant in the one-of. */
+  Class<? extends Enum<?>> value();
+}
diff --git a/value/src/main/java/com/google/auto/value/AutoValue.java b/value/src/main/java/com/google/auto/value/AutoValue.java
new file mode 100644
index 0000000..45a677c
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/AutoValue.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Specifies that <a href="https://github.com/google/auto/tree/master/value">AutoValue</a> should
+ * generate an implementation class for the annotated abstract class, implementing the standard
+ * {@link Object} methods like {@link Object#equals equals} to have conventional value semantics. A
+ * simple example:
+ *
+ * <pre>
+ *
+ *   {@code @}AutoValue
+ *   abstract class Person {
+ *     static Person create(String name, int id) {
+ *       return new AutoValue_Person(name, id);
+ *     }
+ *
+ *     abstract String name();
+ *     abstract int id();
+ *   }</pre>
+ *
+ * @see <a href="https://github.com/google/auto/tree/master/value">AutoValue User's Guide</a>
+ * @author Éamonn McManus
+ * @author Kevin Bourrillion
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target(ElementType.TYPE)
+public @interface AutoValue {
+
+  /**
+   * Specifies that AutoValue should generate an implementation of the annotated class or interface,
+   * to serve as a <i>builder</i> for the value-type class it is nested within. As a simple example,
+   * here is an alternative way to write the {@code Person} class mentioned in the {@link AutoValue}
+   * example:
+   *
+   * <pre>
+   *
+   *   {@code @}AutoValue
+   *   abstract class Person {
+   *     static Builder builder() {
+   *       return new AutoValue_Person.Builder();
+   *     }
+   *
+   *     abstract String name();
+   *     abstract int id();
+   *
+   *     {@code @}AutoValue.Builder
+   *     interface Builder {
+   *       Builder name(String x);
+   *       Builder id(int x);
+   *       Person build();
+   *     }
+   *   }</pre>
+   *
+   * @author Éamonn McManus
+   */
+  @Retention(RetentionPolicy.CLASS)
+  @Target(ElementType.TYPE)
+  public @interface Builder {}
+
+  /**
+   * Specifies that AutoValue should copy any annotations from the annotated element to the
+   * generated class. This annotation supports classes and methods.
+   *
+   * <p>The following annotations are excluded:
+   *
+   * <ol>
+   *   <li>AutoValue and its nested annotations;
+   *   <li>any annotation appearing in the {@link AutoValue.CopyAnnotations#exclude} field;
+   *   <li>any class annotation which is itself annotated with the {@link
+   *       java.lang.annotation.Inherited} meta-annotation.
+   * </ol>
+   *
+   * <p>For historical reasons, annotations are always copied from an {@code @AutoValue} property
+   * method to its implementation, unless {@code @CopyAnnotations} is present and explicitly
+   * {@linkplain CopyAnnotations#exclude excludes} that annotation. But annotations are not copied
+   * from the {@code @AutoValue} class itself to its implementation unless {@code @CopyAnnotations}
+   * is present.
+   *
+   * <p>If you want to copy annotations from your {@literal @}AutoValue-annotated class's methods to
+   * the generated fields in the AutoValue_... implementation, annotate your method
+   * with {@literal @}AutoValue.CopyAnnotations. For example, if Example.java is:<pre>
+
+   *   {@code @}Immutable
+   *   {@code @}AutoValue
+   *   abstract class Example {
+   *     {@code @}CopyAnnotations
+   *     {@code @}SuppressWarnings("Immutable") // justification ...
+   *     abstract Object getObject();
+   *     // other details ...
+   *   }</pre>
+   *
+   * <p>Then AutoValue will generate the following AutoValue_Example.java:<pre>
+   *
+   *   final class AutoValue_Example extends Example {
+   *     {@code @}SuppressWarnings("Immutable")
+   *     private final Object object;
+   *
+   *     {@code @}SuppressWarnings("Immutable")
+   *     {@code @}Override
+   *     Object getObject() {
+   *       return object;
+   *     }
+   *
+   *     // other details ...
+   *   }</pre>
+   *
+   * <p>When the <i>type</i> of an {@code @AutoValue} property method has annotations, those are
+   * part of the type, so by default they are copied to the implementation of the method. But if
+   * a type annotation is mentioned in {@code exclude} then it is not copied.
+   *
+   * <p>For example, suppose {@code @Confidential} is a
+   * {@link java.lang.annotation.ElementType#TYPE_USE TYPE_USE} annotation:
+   *
+   * <pre>
+   *
+   *   {@code @}AutoValue
+   *   abstract class Person {
+   *     static Person create({@code @}Confidential String name, int id) {
+   *       return new AutoValue_Person(name, id);
+   *     }
+   *
+   *     abstract {@code @}Confidential String name();
+   *     abstract int id();
+   *   }</pre>
+   *
+   * Then the implementation of the {@code name()} method will also have return type
+   * {@code @Confidential String}. But if {@code name()} were written like this...
+   *
+   * <pre>
+   *
+   *     {@code @AutoValue.CopyAnnotations(exclude = Confidential.class)}
+   *     abstract {@code @}Confidential String name();</pre>
+   *
+   * <p>...then the implementation of {@code name()} would have return type {@code String} without
+   * the annotation.
+   *
+   * @author Carmi Grushko
+   */
+  @Retention(RetentionPolicy.CLASS)
+  @Target({ElementType.TYPE, ElementType.METHOD})
+  public @interface CopyAnnotations {
+    Class<? extends Annotation>[] exclude() default {};
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/AutoValueExtension.java b/value/src/main/java/com/google/auto/value/extension/AutoValueExtension.java
new file mode 100644
index 0000000..2c8a3fb
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/AutoValueExtension.java
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension;
+
+import com.google.common.collect.ImmutableSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.SupportedOptions;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * An AutoValueExtension allows for extra functionality to be created during the generation of an
+ * AutoValue class.
+ *
+ * <p>Extensions are discovered at compile time using the {@link java.util.ServiceLoader} APIs,
+ * allowing them to run without any additional annotations. To be found by {@code ServiceLoader}, an
+ * extension class must be public with a public no-arg constructor, and its fully-qualified name
+ * must appear in a file called {@code
+ * META-INF/services/com.google.auto.value.extension.AutoValueExtension} in a jar that is on the
+ * compiler's {@code -classpath} or {@code -processorpath}.
+ *
+ * <p>When the AutoValue processor runs for a class {@code Foo}, it will ask each Extension whether
+ * it is {@linkplain #applicable applicable}. Suppose two Extensions reply that they are. Then
+ * the processor will generate the AutoValue logic in a direct subclass of {@code Foo}, and it
+ * will ask the first Extension to generate a subclass of that, and the second Extension to generate
+ * a subclass of the subclass. So we might have this hierarchy:
+ *
+ * <pre>
+ * &#64;AutoValue abstract class Foo {...}                          // the hand-written class
+ * abstract class $$AutoValue_Foo extends Foo {...}             // generated by AutoValue processor
+ * abstract class $AutoValue_Foo extends $$AutoValue_Foo {...}  // generated by first Extension
+ * final class AutoValue_Foo extends $AutoValue_Foo {...}       // generated by second Extension
+ * </pre>
+ *
+ * <p>(The exact naming scheme illustrated here is not fixed and should not be relied on.)
+ *
+ * <p>If an Extension needs its generated class to be the final class in the inheritance hierarchy,
+ * its {@link #mustBeFinal(Context)} method returns true. Only one Extension can return true for a
+ * given context. Only generated classes that will be the final class in the inheritance hierarchy
+ * can be declared final. All others should be declared abstract.
+ *
+ * <p>The first generated class in the hierarchy will always be the one generated by the AutoValue
+ * processor and the last one will always be the one generated by the Extension that {@code
+ * mustBeFinal}, if any. Other than that, the order of the classes in the hierarchy is unspecified.
+ * The last class in the hierarchy is {@code AutoValue_Foo} and that is the one that the
+ * {@code Foo} class will reference, for example with {@code new AutoValue_Foo(...)}.
+ *
+ * <p>Each Extension must also be sure to generate a constructor with arguments corresponding to all
+ * properties in {@link com.google.auto.value.extension.AutoValueExtension.Context#propertyTypes()},
+ * in order, and to call the superclass constructor with the same arguments. This constructor must
+ * have at least package visibility.
+ *
+ * <p>Because the class generated by the AutoValue processor is at the top of the generated
+ * hierarchy, Extensions can override its methods, for example {@code hashCode()},
+ * {@code toString()}, or the implementations of the various {@code bar()} property methods.
+ */
+public abstract class AutoValueExtension {
+
+  /** The context of the generation cycle. */
+  public interface Context {
+
+    /**
+     * Returns the processing environment of this generation cycle. This can be used, among other
+     * things, to produce compilation warnings or errors, using {@link
+     * ProcessingEnvironment#getMessager()}.
+     */
+    ProcessingEnvironment processingEnvironment();
+
+    /** Returns the package name of the classes to be generated. */
+    String packageName();
+
+    /**
+     * Returns the annotated class that this generation cycle is based on.
+     *
+     * <p>Given {@code @AutoValue public class Foo {...}}, this will be {@code Foo}.
+     */
+    TypeElement autoValueClass();
+
+    /**
+     * The fully-qualified name of the last class in the {@code AutoValue} hierarchy. For an
+     * {@code @AutoValue} class {@code foo.bar.Baz}, this will be {@code foo.bar.AutoValue_Baz}.
+     * The class may be generated by an extension, which will be the current extension if the
+     * {@code isFinal} parameter to {@link AutoValueExtension#generateClass} is true and the
+     * returned string is not {@code null}.
+     *
+     * <p>For compatibility reasons, this method has a default implementation that throws an
+     * exception. The AutoValue processor supplies an implementation that behaves as documented.
+     */
+    default String finalAutoValueClassName() {
+      throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns the ordered collection of properties to be generated by AutoValue. Each key is a
+     * property name, and the corresponding value is the getter method for that property. For
+     * example, if property {@code bar} is defined by {@code abstract String getBar()} then this map
+     * will have an entry mapping {@code "bar"} to the {@code ExecutableElement} for {@code
+     * getBar()}.
+     *
+     * <p>To determine the type of a property, it is best to use {@link #propertyTypes()} rather
+     * than looking at the return type of the {@link ExecutableElement} in this map. The reason is
+     * that the final type of the property might be different because of type variables. For
+     * example, if you have...
+     *
+     * <pre>
+     *   interface Parent<T> {
+     *     T bar();
+     *   }
+     *
+     *  {@code @AutoValue abstract class Foo implements Parent<String> {...}}
+     * </pre>
+     *
+     * ...then the type of the {@code bar} property in {@code Foo} is actually {@code String}, but
+     * the {@code ExecutableElement} will be the the method in {@code Parent}, whose return type is
+     * {@code T}.
+     */
+    Map<String, ExecutableElement> properties();
+
+    /**
+     * Returns the properties to be generated by AutoValue, with their types. Each key is a property
+     * name, and the corresponding value is the type of that property. The order of the map entries
+     * is the same as the order of the {@code @AutoValue} properties.
+     *
+     * <p>For example, if property {@code bar} is defined by {@code abstract String getBar()} then
+     * this map will have an entry mapping {@code "bar"} to the {@code TypeMirror} for {@code
+     * String}.
+     *
+     * <p>For compatibility reasons, this method has a default implementation that throws an
+     * exception. The AutoValue processor supplies an implementation that behaves as documented.
+     */
+    default Map<String, TypeMirror> propertyTypes() {
+      throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Returns the complete set of abstract methods defined in or inherited by the
+     * {@code @AutoValue} class. This includes all methods that define properties (like {@code
+     * abstract String getBar()}), any abstract {@code toBuilder()} method, and any other abstract
+     * method even if it has been consumed by this or another Extension.
+     */
+    Set<ExecutableElement> abstractMethods();
+
+    /**
+     * Returns a representation of the {@code Builder} associated with the {@code @AutoValue} class,
+     * if there is one.
+     *
+     * <p>This method returns {@link Optional#empty()} if called from within the {@link #applicable}
+     * method. If an Extension needs {@code Builder} information to decide whether it is applicable,
+     * it should return {@code true} from the {@link #applicable} method and then return {@code
+     * null} from the {@link #generateClass} method if it does not need to generate a class after
+     * all.
+     *
+     * <p>The default implementation of this method returns {@link Optional#empty()} for
+     * compatibility with extensions which may have implemented this interface themselves.
+     */
+    default Optional<BuilderContext> builder() {
+      return Optional.empty();
+    }
+  }
+
+  /**
+   * Represents a {@code Builder} associated with an {@code @AutoValue} class.
+   */
+  public interface BuilderContext {
+    /**
+     * Returns the {@code @AutoValue.Builder} interface or abstract class that this object
+     * represents.
+     */
+    TypeElement builderType();
+
+    /**
+     * Returns abstract no-argument methods in the {@code @AutoValue} class that return the builder
+     * type.
+     *
+     * <p>Consider a class like this:
+     * <pre>
+     *   {@code @AutoValue} abstract class Foo {
+     *     abstract String bar();
+     *
+     *     abstract Builder toBuilder();
+     *
+     *     ...
+     *     {@code @AutoValue.Builder}
+     *     abstract static class Builder {...}
+     *   }
+     * </pre>
+     *
+     * <p>Here {@code toBuilderMethods()} will return a set containing the method
+     * {@code Foo.toBuilder()}.
+     */
+    Set<ExecutableElement> toBuilderMethods();
+
+    /**
+     * Returns static no-argument methods in the {@code @AutoValue} class that return the builder
+     * type.
+     *
+     * <p>Consider a class like this:
+     * <pre>
+     *   {@code @AutoValue} abstract class Foo {
+     *     abstract String bar();
+     *
+     *     static Builder builder() {
+     *       return new AutoValue_Foo.Builder()
+     *           .setBar("default bar");
+     *     }
+     *
+     *     {@code @AutoValue.Builder}
+     *     abstract class Builder {
+     *       abstract Builder setBar(String x);
+     *       abstract Foo build();
+     *     }
+     *   }
+     * </pre>
+     *
+     * <p>Here {@code builderMethods()} will return a set containing the method
+     * {@code Foo.builder()}. Generated code should usually call this method in preference to
+     * constructing {@code AutoValue_Foo.Builder()} directly, because this method can establish
+     * default values for properties, as it does here.
+     */
+    Set<ExecutableElement> builderMethods();
+
+    /**
+     * Returns the method {@code build()} in the builder class, if it exists and returns the
+     * {@code @AutoValue} type. This is the method that generated code for
+     * {@code @AutoValue class Foo} should call in order to get an instance of {@code Foo} from its
+     * builder. The returned method is called {@code build()}; if the builder uses some other name
+     * then extensions have no good way to guess how they should build.
+     *
+     * <p>A common convention is for {@code build()} to be a concrete method in the
+     * {@code @AutoValue.Builder} class, which calls an abstract method {@code autoBuild()} that is
+     * implemented in the generated subclass. The {@code build()} method can then do validation,
+     * defaulting, and so on.
+     */
+    Optional<ExecutableElement> buildMethod();
+
+    /**
+     * Returns the abstract build method. If the {@code @AutoValue} class is {@code Foo}, this is an
+     * abstract no-argument method in the builder class that returns {@code Foo}. This might be
+     * called {@code build()}, or, following a common convention, it might be called
+     * {@code autoBuild()} and used in the implementation of a {@code build()} method that is
+     * defined in the builder class.
+     *
+     * <p>Extensions should call the {@code build()} method in preference to this one. But they
+     * should override this one if they want to customize build-time behaviour.
+     */
+    ExecutableElement autoBuildMethod();
+
+    /**
+     * Returns a map from property names to the corresponding setters. A property may have more than
+     * one setter. For example, an {@code ImmutableList<String>} might be set by
+     * {@code setFoo(ImmutableList<String>)} and {@code setFoo(String[])}.
+     */
+    Map<String, Set<ExecutableElement>> setters();
+
+    /**
+     * Returns a map from property names to property builders. For example, if there is a property
+     * {@code foo} defined by {@code abstract ImmutableList<String> foo();} or
+     * {@code abstract ImmutableList<String> getFoo();} in the {@code @AutoValue} class,
+     * then there can potentially be a builder defined by
+     * {@code abstract ImmutableList.Builder<String> fooBuilder();} in the
+     * {@code @AutoValue.Builder} class. This map would then map {@code "foo"} to the
+     * {@link ExecutableElement} representing {@code fooBuilder()}.
+     */
+    Map<String, ExecutableElement> propertyBuilders();
+  }
+
+  /**
+   * Indicates to an annotation processor environment supporting incremental annotation processing
+   * (currently a feature specific to Gradle starting with version 4.8) the incremental type of an
+   * Extension.
+   *
+   * <p>The constants for this enum are ordered by increasing performance (but also constraints).
+   *
+   * @see <a
+   *     href="https://docs.gradle.org/current/userguide/java_plugin.html#sec:incremental_annotation_processing">Gradle
+   *     documentation of its incremental annotation processing</a>
+   */
+  public enum IncrementalExtensionType {
+    /**
+     * The incrementality of this extension is unknown, or it is neither aggregating nor isolating.
+     */
+    UNKNOWN,
+
+    /**
+     * This extension is <i>aggregating</i>, meaning that it may generate outputs based on several
+     * annotated input classes and it respects the constraints imposed on aggregating processors.
+     * It is unusual for AutoValue extensions to be aggregating.
+     *
+     * @see <a
+     *     href="https://docs.gradle.org/current/userguide/java_plugin.html#aggregating_annotation_processors">Gradle
+     *     definition of aggregating processors</a>
+     */
+    AGGREGATING,
+
+    /**
+     * This extension is <i>isolating</i>, meaning roughly that its output depends on the
+     * {@code @AutoValue} class and its dependencies, but not on other {@code @AutoValue} classes
+     * that might be compiled at the same time. The constraints that an isolating extension must
+     * respect are the same as those that Gradle imposes on an isolating annotation processor.
+     *
+     * @see <a
+     *     href="https://docs.gradle.org/current/userguide/java_plugin.html#isolating_annotation_processors">Gradle
+     *     definition of isolating processors</a>
+     */
+    ISOLATING
+  }
+
+  /**
+   * Determines the incremental type of this Extension.
+   *
+   * <p>The {@link ProcessingEnvironment} can be used, among other things, to obtain the processor
+   * options, using {@link ProcessingEnvironment#getOptions()}.
+   *
+   * <p>The actual incremental type of the AutoValue processor as a whole will be the loosest
+   * incremental types of the Extensions present in the annotation processor path. The default
+   * returned value is {@link IncrementalExtensionType#UNKNOWN}, which will disable incremental
+   * annotation processing entirely.
+   */
+  public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {
+    return IncrementalExtensionType.UNKNOWN;
+  }
+
+  /**
+   * Analogous to {@link Processor#getSupportedOptions()}, here to allow extensions to report their
+   * own.
+   *
+   * <p>By default, if the extension class is annotated with {@link SupportedOptions}, this will
+   * return a set with the strings in the annotation. If the class is not so annotated, an empty set
+   * is returned.
+   *
+   * @return the set of options recognized by this extension or an empty set if none
+   * @see SupportedOptions
+   */
+  public Set<String> getSupportedOptions() {
+    SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class);
+    if (so == null) {
+      return ImmutableSet.of();
+    } else {
+      return ImmutableSet.copyOf(so.value());
+    }
+  }
+
+  /**
+   * Determines whether this Extension applies to the given context. If an Extension returns {@code
+   * false} for a given class, it will not be called again during the processing of that class. An
+   * Extension can return {@code true} and still choose not to generate any code for the class, by
+   * returning {@code null} from {@link #generateClass}. That is often a more flexible approach.
+   *
+   * @param context The Context of the code generation for this class.
+   */
+  public boolean applicable(Context context) {
+    return false;
+  }
+
+  /**
+   * Denotes that the class generated by this Extension must be the final class in the inheritance
+   * hierarchy. Only one Extension may be the final class, so this should be used sparingly.
+   *
+   * @param context the Context of the code generation for this class.
+   */
+  public boolean mustBeFinal(Context context) {
+    return false;
+  }
+
+  /**
+   * Returns a possibly empty set of property names that this Extension intends to implement. This
+   * will prevent AutoValue from generating an implementation, and remove the supplied properties
+   * from builders, constructors, {@code toString}, {@code equals}, and {@code hashCode}. The
+   * default set returned by this method is empty.
+   *
+   * <p>Each returned string must be one of the property names in {@link Context#properties()}.
+   *
+   * <p>Returning a property name from this method is equivalent to returning the property's getter
+   * method from {@link #consumeMethods}.
+   *
+   * <p>For example, Android's {@code Parcelable} interface includes a <a
+   * href="http://developer.android.com/reference/android/os/Parcelable.html#describeContents()">method</a>
+   * {@code int describeContents()}. Since this is an abstract method with no parameters, by default
+   * AutoValue will consider that it defines an {@code int} property called {@code
+   * describeContents}. If an {@code @AutoValue} class implements {@code Parcelable} and does not
+   * provide an implementation of this method, by default its implementation will include {@code
+   * describeContents} in builders, constructors, and so on. But an {@code AutoValueExtension} that
+   * understands {@code Parcelable} can instead provide a useful implementation and return a set
+   * containing {@code "describeContents"}. Then {@code describeContents} will be omitted from
+   * builders and the rest.
+   *
+   * @param context the Context of the code generation for this class.
+   */
+  public Set<String> consumeProperties(Context context) {
+    return ImmutableSet.of();
+  }
+
+  /**
+   * Returns a possible empty set of abstract methods that this Extension intends to implement. This
+   * will prevent AutoValue from generating an implementation, in cases where it would have, and it
+   * will also avoid warnings about abstract methods that AutoValue doesn't expect. The default set
+   * returned by this method is empty.
+   *
+   * <p>Each returned method must be one of the abstract methods in {@link
+   * Context#abstractMethods()}.
+   *
+   * <p>For example, Android's {@code Parcelable} interface includes a <a
+   * href="http://developer.android.com/reference/android/os/Parcelable.html#writeToParcel(android.os.Parcel,
+   * int)">method</a> {@code void writeToParcel(Parcel, int)}. Normally AutoValue would not know
+   * what to do with that abstract method. But an {@code AutoValueExtension} that understands {@code
+   * Parcelable} can provide a useful implementation and return the {@code writeToParcel} method
+   * here. That will prevent a warning about the method from AutoValue.
+   *
+   * @param context the Context of the code generation for this class.
+   */
+  public Set<ExecutableElement> consumeMethods(Context context) {
+    return ImmutableSet.of();
+  }
+
+  /**
+   * Returns the generated source code of the class named {@code className} to extend {@code
+   * classToExtend}, or {@code null} if this extension does not generate a class in the hierarchy.
+   * If there is a generated class, it should be final if {@code isFinal} is true; otherwise it
+   * should be abstract. The returned string should be a complete Java class definition of the class
+   * {@code className} in the package {@link Context#packageName() context.packageName()}.
+   *
+   * <p>The returned string will typically look like this:
+   *
+   * <pre>{@code
+   * package <package>;
+   * ...
+   * <finalOrAbstract> class <className> extends <classToExtend> {
+   *   // Constructor
+   *   <className>(<constructorParameters>) {
+   *     super(<constructorParameterNames>);
+   *     ...
+   *   }
+   *   ...
+   * }}</pre>
+   *
+   * <p>Here, {@code <package>} is {@link Context#packageName()}; {@code <finalOrAbstract>} is the
+   * keyword {@code final} if {@code isFinal} is true or {@code abstract} otherwise; and {@code
+   * <className>} and {@code <classToExtend>} are the values of this method's parameters of the same
+   * name. The {@code <constructorParameters>} and {@code <constructorParameterNames>} are typically
+   * derived from {@link Context#propertyTypes()}.
+   *
+   * @param context The {@link Context} of the code generation for this class.
+   * @param className The simple name of the resulting class. The returned code will be written to a
+   *     file named accordingly.
+   * @param classToExtend The simple name of the direct parent of the generated class. This could be
+   *     the AutoValue generated class, or a class generated as the result of another Extension.
+   * @param isFinal True if this class is the last class in the chain, meaning it should be marked
+   *     as final. Otherwise it should be marked as abstract.
+   * @return The source code of the generated class, or {@code null} if this extension does not
+   *     generate a class in the hierarchy.
+   */
+  public abstract String generateClass(
+      Context context, String className, String classToExtend, boolean isFinal);
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/memoized/Memoized.java b/value/src/main/java/com/google/auto/value/extension/memoized/Memoized.java
new file mode 100644
index 0000000..ef16135
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/memoized/Memoized.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.memoized;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.CLASS;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Annotates methods in {@link com.google.auto.value.AutoValue @AutoValue} classes for which the
+ * generated subclass will <a href="https://en.wikipedia.org/wiki/Memoization">memoize</a> the
+ * returned value.
+ *
+ * <p>Methods annotated with {@code @Memoized} cannot:
+ *
+ * <ul>
+ *   <li>be {@code abstract} (except for {@link #hashCode()} and {@link #toString()}), {@code
+ *       private}, {@code final}, or {@code static}
+ *   <li>return {@code void}
+ *   <li>have any parameters
+ * </ul>
+ *
+ * <p>If you want to memoize {@link #hashCode()} or {@link #toString()}, you can redeclare them,
+ * keeping them {@code abstract}, and annotate them with {@code @Memoize}.
+ *
+ * <p>If a {@code @Memoized} method is annotated with an annotation whose simple name is {@code
+ * Nullable}, then {@code null} values will also be memoized. Otherwise, if the method returns
+ * {@code null}, the overriding method will throw a {@link NullPointerException}.
+ *
+ * <p>The overriding method uses <a
+ * href="https://errorprone.info/bugpattern/DoubleCheckedLocking">double-checked locking</a> to
+ * ensure that the annotated method is called at most once.
+ *
+ * <h3>Example</h3>
+ *
+ * <pre>
+ *   {@code @AutoValue}
+ *   abstract class Value {
+ *     abstract String stringProperty();
+ *
+ *     {@code @Memoized}
+ *     String derivedProperty() {
+ *       return someCalculationOn(stringProperty());
+ *     }
+ *   }
+ *
+ *   {@code @Generated}
+ *   class AutoValue_Value {
+ *     // …
+ *
+ *     private volatile String derivedProperty;
+ *
+ *     {@code Override}
+ *     String derivedProperty() {
+ *       if (derivedProperty == null) {
+ *         synchronized (this) {
+ *           if (derivedProperty == null) {
+ *             derivedProperty = super.derivedProperty();
+ *           }
+ *         }
+ *       }
+ *       return derivedProperty;
+ *     }
+ *   }</pre>
+ */
+@Documented
+@Retention(CLASS)
+@Target(METHOD)
+public @interface Memoized {}
diff --git a/value/src/main/java/com/google/auto/value/extension/memoized/processor/ClassNames.java b/value/src/main/java/com/google/auto/value/extension/memoized/processor/ClassNames.java
new file mode 100644
index 0000000..83794f6
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/memoized/processor/ClassNames.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.memoized.processor;
+
+/** Names of classes that are referenced in the processor/extension. */
+final class ClassNames {
+  static final String MEMOIZED_NAME = "com.google.auto.value.extension.memoized.Memoized";
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/memoized/processor/MemoizeExtension.java b/value/src/main/java/com/google/auto/value/extension/memoized/processor/MemoizeExtension.java
new file mode 100644
index 0000000..db2f221
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/memoized/processor/MemoizeExtension.java
@@ -0,0 +1,599 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.memoized.processor;
+
+import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
+import static com.google.auto.common.GeneratedAnnotationSpecs.generatedAnnotationSpec;
+import static com.google.auto.common.MoreElements.getPackage;
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.auto.value.extension.memoized.processor.ClassNames.MEMOIZED_NAME;
+import static com.google.auto.value.extension.memoized.processor.MemoizedValidator.getAnnotationMirror;
+import static com.google.common.base.Predicates.equalTo;
+import static com.google.common.base.Predicates.not;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.ImmutableSet.toImmutableSet;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Sets.union;
+import static com.squareup.javapoet.MethodSpec.constructorBuilder;
+import static com.squareup.javapoet.MethodSpec.methodBuilder;
+import static com.squareup.javapoet.TypeSpec.classBuilder;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+import static javax.lang.model.element.Modifier.ABSTRACT;
+import static javax.lang.model.element.Modifier.FINAL;
+import static javax.lang.model.element.Modifier.PRIVATE;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.lang.model.element.Modifier.STATIC;
+import static javax.lang.model.element.Modifier.TRANSIENT;
+import static javax.lang.model.element.Modifier.VOLATILE;
+import static javax.lang.model.type.TypeKind.VOID;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+import static javax.tools.Diagnostic.Kind.ERROR;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.common.Visibility;
+import com.google.auto.service.AutoService;
+import com.google.auto.value.extension.AutoValueExtension;
+import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.errorprone.annotations.FormatMethod;
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeVariableName;
+import java.lang.annotation.Inherited;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.QualifiedNameable;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic.Kind;
+
+/**
+ * An extension that implements the {@link com.google.auto.value.extension.memoized.Memoized}
+ * contract.
+ */
+@AutoService(AutoValueExtension.class)
+public final class MemoizeExtension extends AutoValueExtension {
+  private static final ImmutableSet<String> DO_NOT_PULL_DOWN_ANNOTATIONS =
+      ImmutableSet.of(Override.class.getCanonicalName(), MEMOIZED_NAME);
+
+  // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+  private static final String AUTO_VALUE_PACKAGE_NAME = "com.google.auto.value.";
+  private static final String AUTO_VALUE_NAME = AUTO_VALUE_PACKAGE_NAME + "AutoValue";
+  private static final String COPY_ANNOTATIONS_NAME = AUTO_VALUE_NAME + ".CopyAnnotations";
+
+  private static final ClassName LAZY_INIT =
+      ClassName.get("com.google.errorprone.annotations.concurrent", "LazyInit");
+
+  private static final AnnotationSpec SUPPRESS_WARNINGS =
+      AnnotationSpec.builder(SuppressWarnings.class).addMember("value", "$S", "Immutable").build();
+
+  @Override
+  public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {
+    return IncrementalExtensionType.ISOLATING;
+  }
+
+  @Override
+  public boolean applicable(Context context) {
+    return !memoizedMethods(context).isEmpty();
+  }
+
+  @Override
+  public String generateClass(
+      Context context, String className, String classToExtend, boolean isFinal) {
+    return new Generator(context, className, classToExtend, isFinal).generate();
+  }
+
+  private static ImmutableSet<ExecutableElement> memoizedMethods(Context context) {
+    ImmutableSet.Builder<ExecutableElement> memoizedMethods = ImmutableSet.builder();
+    for (ExecutableElement method : methodsIn(context.autoValueClass().getEnclosedElements())) {
+      if (getAnnotationMirror(method, MEMOIZED_NAME).isPresent()) {
+        memoizedMethods.add(method);
+      }
+    }
+    return memoizedMethods.build();
+  }
+
+  static final class Generator {
+    private final Context context;
+    private final String className;
+    private final String classToExtend;
+    private final boolean isFinal;
+    private final Elements elements;
+    private final Types types;
+    private final SourceVersion sourceVersion;
+    private final Messager messager;
+    private final Optional<AnnotationSpec> lazyInitAnnotation;
+    private boolean hasErrors;
+
+    Generator(Context context, String className, String classToExtend, boolean isFinal) {
+      this.context = context;
+      this.className = className;
+      this.classToExtend = classToExtend;
+      this.isFinal = isFinal;
+      this.elements = context.processingEnvironment().getElementUtils();
+      this.types = context.processingEnvironment().getTypeUtils();
+      this.sourceVersion = context.processingEnvironment().getSourceVersion();
+      this.messager = context.processingEnvironment().getMessager();
+      this.lazyInitAnnotation = getLazyInitAnnotation(elements);
+    }
+
+    String generate() {
+      TypeSpec.Builder generated =
+          classBuilder(className)
+              .superclass(superType())
+              .addAnnotations(copiedClassAnnotations(context.autoValueClass()))
+              .addTypeVariables(typeVariableNames())
+              .addModifiers(isFinal ? FINAL : ABSTRACT)
+              .addMethod(constructor());
+      generatedAnnotationSpec(elements, sourceVersion, MemoizeExtension.class)
+          .ifPresent(generated::addAnnotation);
+      for (ExecutableElement method : memoizedMethods(context)) {
+        MethodOverrider methodOverrider = new MethodOverrider(method);
+        generated.addFields(methodOverrider.fields());
+        generated.addMethod(methodOverrider.method());
+      }
+      if (isHashCodeMemoized() && !isEqualsFinal()) {
+        generated.addMethod(equalsWithHashCodeCheck());
+      }
+      if (hasErrors) {
+        return null;
+      }
+      return JavaFile.builder(context.packageName(), generated.build()).build().toString();
+    }
+
+    private TypeName superType() {
+      ClassName superType = ClassName.get(context.packageName(), classToExtend);
+      ImmutableList<TypeVariableName> typeVariableNames = typeVariableNames();
+
+      return typeVariableNames.isEmpty()
+          ? superType
+          : ParameterizedTypeName.get(superType, typeVariableNames.toArray(new TypeName[] {}));
+    }
+
+    private ImmutableList<TypeVariableName> typeVariableNames() {
+      ImmutableList.Builder<TypeVariableName> typeVariableNamesBuilder = ImmutableList.builder();
+      for (TypeParameterElement typeParameter : context.autoValueClass().getTypeParameters()) {
+        typeVariableNamesBuilder.add(TypeVariableName.get(typeParameter));
+      }
+      return typeVariableNamesBuilder.build();
+    }
+
+    private MethodSpec constructor() {
+      MethodSpec.Builder constructor = constructorBuilder();
+      for (Map.Entry<String, TypeMirror> property : context.propertyTypes().entrySet()) {
+        constructor.addParameter(annotatedType(property.getValue()), property.getKey() + "$");
+      }
+      List<String> namesWithDollars = new ArrayList<String>();
+      for (String property : context.properties().keySet()) {
+        namesWithDollars.add(property + "$");
+      }
+      constructor.addStatement("super($L)", Joiner.on(", ").join(namesWithDollars));
+      return constructor.build();
+    }
+
+    private boolean isHashCodeMemoized() {
+      return memoizedMethods(context).stream()
+          .anyMatch(method -> method.getSimpleName().contentEquals("hashCode"));
+    }
+
+    private boolean isEqualsFinal() {
+      TypeMirror objectType = elements.getTypeElement(Object.class.getCanonicalName()).asType();
+      ExecutableElement equals =
+          MoreElements.getLocalAndInheritedMethods(context.autoValueClass(), types, elements)
+              .stream()
+              .filter(method -> method.getSimpleName().contentEquals("equals"))
+              .filter(method -> method.getParameters().size() == 1)
+              .filter(
+                  method ->
+                      types.isSameType(getOnlyElement(method.getParameters()).asType(), objectType))
+              .findFirst()
+              .get();
+      return equals.getModifiers().contains(FINAL);
+    }
+
+    private MethodSpec equalsWithHashCodeCheck() {
+      return methodBuilder("equals")
+          .addModifiers(PUBLIC)
+          .returns(TypeName.BOOLEAN)
+          .addAnnotation(Override.class)
+          .addParameter(TypeName.OBJECT, "that")
+          .beginControlFlow("if (this == that)")
+          .addStatement("return true")
+          .endControlFlow()
+          .addStatement(
+              "return that instanceof $N "
+                  + "&& this.hashCode() == that.hashCode() "
+                  + "&& super.equals(that)",
+              className)
+          .build();
+    }
+
+    /**
+     * True if the given class name is in the com.google.auto.value package or a subpackage. False
+     * if the class name contains {@code Test}, since many AutoValue tests under
+     * com.google.auto.value define their own annotations.
+     */
+    // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+    private boolean isInAutoValuePackage(String className) {
+      return className.startsWith(AUTO_VALUE_PACKAGE_NAME) && !className.contains("Test");
+    }
+
+    /**
+     * Returns the fully-qualified name of an annotation-mirror, e.g.
+     * "com.google.auto.value.AutoValue".
+     */
+    // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+    private static String getAnnotationFqName(AnnotationMirror annotation) {
+      return ((QualifiedNameable) annotation.getAnnotationType().asElement())
+          .getQualifiedName()
+          .toString();
+    }
+
+    // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+    private boolean annotationVisibleFrom(AnnotationMirror annotation, Element from) {
+      Element annotationElement = annotation.getAnnotationType().asElement();
+      Visibility visibility = Visibility.effectiveVisibilityOfElement(annotationElement);
+      switch (visibility) {
+        case PUBLIC:
+          return true;
+        case PROTECTED:
+          // If the annotation is protected, it must be inside another class, call it C. If our
+          // @AutoValue class is Foo then, for the annotation to be visible, either Foo must be in
+          // the same package as C or Foo must be a subclass of C. If the annotation is visible from
+          // Foo then it is also visible from our generated subclass AutoValue_Foo.
+          // The protected case only applies to method annotations. An annotation on the
+          // AutoValue_Foo class itself can't be protected, even if AutoValue_Foo ultimately
+          // inherits from the class that defines the annotation. The JLS says "Access is permitted
+          // only within the body of a subclass":
+          // https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.2.1
+          // AutoValue_Foo is a top-level class, so an annotation on it cannot be in the body of a
+          // subclass of anything.
+          return getPackage(annotationElement).equals(getPackage(from))
+              || types.isSubtype(from.asType(), annotationElement.getEnclosingElement().asType());
+        case DEFAULT:
+          return getPackage(annotationElement).equals(getPackage(from));
+        default:
+          return false;
+      }
+    }
+
+    /** Implements the semantics of {@code AutoValue.CopyAnnotations}; see its javadoc. */
+    // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+    private ImmutableList<AnnotationMirror> annotationsToCopy(
+        Element autoValueType, Element typeOrMethod, Set<String> excludedAnnotations) {
+      ImmutableList.Builder<AnnotationMirror> result = ImmutableList.builder();
+      for (AnnotationMirror annotation : typeOrMethod.getAnnotationMirrors()) {
+        String annotationFqName = getAnnotationFqName(annotation);
+        // To be included, the annotation should not be in com.google.auto.value,
+        // and it should not be in the excludedAnnotations set.
+        if (!isInAutoValuePackage(annotationFqName)
+            && !excludedAnnotations.contains(annotationFqName)
+            && annotationVisibleFrom(annotation, autoValueType)) {
+          result.add(annotation);
+        }
+      }
+
+      return result.build();
+    }
+
+    /** Implements the semantics of {@code AutoValue.CopyAnnotations}; see its javadoc. */
+    // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+    private ImmutableList<AnnotationSpec> copyAnnotations(
+        Element autoValueType, Element typeOrMethod, Set<String> excludedAnnotations) {
+      ImmutableList<AnnotationMirror> annotationsToCopy =
+          annotationsToCopy(autoValueType, typeOrMethod, excludedAnnotations);
+      return annotationsToCopy.stream().map(AnnotationSpec::get).collect(toImmutableList());
+    }
+
+    // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+    private static boolean hasAnnotationMirror(Element element, String annotationName) {
+      return getAnnotationMirror(element, annotationName).isPresent();
+    }
+
+    /**
+     * Returns the contents of the {@code AutoValue.CopyAnnotations.exclude} element, as a set of
+     * {@code TypeMirror} where each type is an annotation type.
+     */
+    // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+    private ImmutableSet<TypeMirror> getExcludedAnnotationTypes(Element element) {
+      Optional<AnnotationMirror> maybeAnnotation =
+          getAnnotationMirror(element, COPY_ANNOTATIONS_NAME);
+      if (!maybeAnnotation.isPresent()) {
+        return ImmutableSet.of();
+      }
+
+      @SuppressWarnings("unchecked")
+      List<AnnotationValue> excludedClasses =
+          (List<AnnotationValue>) getAnnotationValue(maybeAnnotation.get(), "exclude").getValue();
+      return excludedClasses.stream()
+          .map(
+              annotationValue ->
+                  MoreTypes.equivalence().wrap((TypeMirror) annotationValue.getValue()))
+          // TODO(b/122509249): Move TypeMirrorSet to common package instead of doing this.
+          .distinct()
+          .map(Wrapper::get)
+          .collect(toImmutableSet());
+    }
+
+    /**
+     * Returns the contents of the {@code AutoValue.CopyAnnotations.exclude} element, as a set of
+     * strings that are fully-qualified class names.
+     */
+    // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+    private Set<String> getExcludedAnnotationClassNames(Element element) {
+      return getExcludedAnnotationTypes(element).stream()
+          .map(MoreTypes::asTypeElement)
+          .map(typeElement -> typeElement.getQualifiedName().toString())
+          .collect(toSet());
+    }
+
+    // TODO(b/122509249): Move code copied from com.google.auto.value.processor to auto-common.
+    private static Set<String> getAnnotationsMarkedWithInherited(Element element) {
+      return element.getAnnotationMirrors().stream()
+          .filter(a -> isAnnotationPresent(a.getAnnotationType().asElement(), Inherited.class))
+          .map(Generator::getAnnotationFqName)
+          .collect(toSet());
+    }
+
+    private ImmutableList<AnnotationSpec> copiedClassAnnotations(TypeElement type) {
+      // Only copy annotations from a class if it has @AutoValue.CopyAnnotations.
+      if (hasAnnotationMirror(type, COPY_ANNOTATIONS_NAME)) {
+        Set<String> excludedAnnotations =
+            union(getExcludedAnnotationClassNames(type), getAnnotationsMarkedWithInherited(type));
+
+        return copyAnnotations(type, type, excludedAnnotations);
+      } else {
+        return ImmutableList.of();
+      }
+    }
+
+    /**
+     * Determines the required fields and overriding method for a {@link
+     * com.google.auto.value.extension.memoized.Memoized @Memoized} method.
+     */
+    private final class MethodOverrider {
+      private final ExecutableElement method;
+      private final MethodSpec.Builder override;
+      private final FieldSpec cacheField;
+      private final ImmutableList.Builder<FieldSpec> fields = ImmutableList.builder();
+
+      MethodOverrider(ExecutableElement method) {
+        this.method = method;
+        validate();
+        cacheField =
+            buildCacheField(
+                annotatedType(method.getReturnType()), method.getSimpleName().toString());
+        fields.add(cacheField);
+        override =
+            methodBuilder(method.getSimpleName().toString())
+                .addAnnotation(Override.class)
+                .returns(cacheField.type)
+                .addExceptions(
+                    method.getThrownTypes().stream().map(TypeName::get).collect(toList()))
+                .addModifiers(filter(method.getModifiers(), not(equalTo(ABSTRACT))));
+        for (AnnotationMirror annotation : method.getAnnotationMirrors()) {
+          AnnotationSpec annotationSpec = AnnotationSpec.get(annotation);
+          if (pullDownMethodAnnotation(annotation)) {
+            override.addAnnotation(annotationSpec);
+          }
+        }
+
+        InitializationStrategy checkStrategy = strategy();
+        fields.addAll(checkStrategy.additionalFields());
+        override
+            .beginControlFlow("if ($L)", checkStrategy.checkMemoized())
+            .beginControlFlow("synchronized (this)")
+            .beginControlFlow("if ($L)", checkStrategy.checkMemoized())
+            .addStatement("$N = super.$L()", cacheField, method.getSimpleName())
+            .addCode(checkStrategy.setMemoized())
+            .endControlFlow()
+            .endControlFlow()
+            .endControlFlow()
+            .addStatement("return $N", cacheField);
+      }
+
+      /** The fields that should be added to the subclass. */
+      Iterable<FieldSpec> fields() {
+        return fields.build();
+      }
+
+      /** The overriding method that should be added to the subclass. */
+      MethodSpec method() {
+        return override.build();
+      }
+
+      private void validate() {
+        if (method.getReturnType().getKind().equals(VOID)) {
+          printMessage(ERROR, "@Memoized methods cannot be void");
+        }
+        if (!method.getParameters().isEmpty()) {
+          printMessage(ERROR, "@Memoized methods cannot have parameters");
+        }
+        checkIllegalModifier(PRIVATE);
+        checkIllegalModifier(FINAL);
+        checkIllegalModifier(STATIC);
+
+        if (!overridesObjectMethod("hashCode") && !overridesObjectMethod("toString")) {
+          checkIllegalModifier(ABSTRACT);
+        }
+      }
+
+      private void checkIllegalModifier(Modifier modifier) {
+        if (method.getModifiers().contains(modifier)) {
+          printMessage(ERROR, "@Memoized methods cannot be %s", modifier.toString());
+        }
+      }
+
+      @FormatMethod
+      private void printMessage(Kind kind, String format, Object... args) {
+        if (kind.equals(ERROR)) {
+          hasErrors = true;
+        }
+        messager.printMessage(kind, String.format(format, args), method);
+      }
+
+      private boolean overridesObjectMethod(String methodName) {
+        return elements.overrides(method, objectMethod(methodName), context.autoValueClass());
+      }
+
+      private ExecutableElement objectMethod(final String methodName) {
+        TypeElement object = elements.getTypeElement(Object.class.getName());
+        for (ExecutableElement method : methodsIn(object.getEnclosedElements())) {
+          if (method.getSimpleName().contentEquals(methodName)) {
+            return method;
+          }
+        }
+        throw new IllegalArgumentException(
+            String.format("No method in Object named \"%s\"", methodName));
+      }
+
+      private boolean pullDownMethodAnnotation(AnnotationMirror annotation) {
+        return !DO_NOT_PULL_DOWN_ANNOTATIONS.contains(
+            MoreElements.asType(annotation.getAnnotationType().asElement())
+                .getQualifiedName()
+                .toString());
+      }
+
+      /**
+       * Builds a {@link FieldSpec} for use in property caching. Field will be {@code private
+       * transient volatile} and have the given type and name. If the @LazyInit annotation is
+       * available it is added as well.
+       */
+      private FieldSpec buildCacheField(TypeName type, String name) {
+        FieldSpec.Builder builder = FieldSpec.builder(type, name, PRIVATE, TRANSIENT, VOLATILE);
+        if (lazyInitAnnotation.isPresent()) {
+          builder.addAnnotation(lazyInitAnnotation.get());
+          builder.addAnnotation(SUPPRESS_WARNINGS);
+        }
+        return builder.build();
+      }
+
+      InitializationStrategy strategy() {
+        if (method.getReturnType().getKind().isPrimitive()) {
+          return new CheckBooleanField();
+        }
+        if (containsNullable(method.getAnnotationMirrors())
+            || containsNullable(method.getReturnType().getAnnotationMirrors())) {
+          return new CheckBooleanField();
+        }
+        return new NullMeansUninitialized();
+      }
+
+      private abstract class InitializationStrategy {
+
+        abstract Iterable<FieldSpec> additionalFields();
+
+        abstract CodeBlock checkMemoized();
+
+        abstract CodeBlock setMemoized();
+      }
+
+      private final class NullMeansUninitialized extends InitializationStrategy {
+        @Override
+        Iterable<FieldSpec> additionalFields() {
+          return ImmutableList.of();
+        }
+
+        @Override
+        CodeBlock checkMemoized() {
+          return CodeBlock.of("$N == null", cacheField);
+        }
+
+        @Override
+        CodeBlock setMemoized() {
+          return CodeBlock.builder()
+              .beginControlFlow("if ($N == null)", cacheField)
+              .addStatement(
+                  "throw new NullPointerException($S)",
+                  method.getSimpleName() + "() cannot return null")
+              .endControlFlow()
+              .build();
+        }
+      }
+
+      private final class CheckBooleanField extends InitializationStrategy {
+
+        private final FieldSpec field =
+            buildCacheField(TypeName.BOOLEAN, method.getSimpleName() + "$Memoized");
+
+        @Override
+        Iterable<FieldSpec> additionalFields() {
+          return ImmutableList.of(field);
+        }
+
+        @Override
+        CodeBlock checkMemoized() {
+          return CodeBlock.of("!$N", field);
+        }
+
+        @Override
+        CodeBlock setMemoized() {
+          return CodeBlock.builder().addStatement("$N = true", field).build();
+        }
+      }
+    }
+  }
+
+  /** Returns the errorprone {@code @LazyInit} annotation if it is found on the classpath. */
+  private static Optional<AnnotationSpec> getLazyInitAnnotation(Elements elements) {
+    if (elements.getTypeElement(LAZY_INIT.toString()) == null) {
+      return Optional.empty();
+    }
+    return Optional.of(AnnotationSpec.builder(LAZY_INIT).build());
+  }
+
+  /** True if one of the given annotations is {@code @Nullable} in any package. */
+  private static boolean containsNullable(List<? extends AnnotationMirror> annotations) {
+    return annotations.stream()
+        .map(a -> a.getAnnotationType().asElement().getSimpleName())
+        .anyMatch(n -> n.contentEquals("Nullable"));
+  }
+
+  /** Translate a {@link TypeMirror} into a {@link TypeName}, including type annotations. */
+  private static TypeName annotatedType(TypeMirror type) {
+    List<AnnotationSpec> annotations =
+        type.getAnnotationMirrors().stream()
+            .map(AnnotationSpec::get)
+            .collect(toList());
+    return TypeName.get(type).annotated(annotations);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/memoized/processor/MemoizedValidator.java b/value/src/main/java/com/google/auto/value/extension/memoized/processor/MemoizedValidator.java
new file mode 100644
index 0000000..5a77050
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/memoized/processor/MemoizedValidator.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.memoized.processor;
+
+import static com.google.auto.value.extension.memoized.processor.ClassNames.MEMOIZED_NAME;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+import static javax.tools.Diagnostic.Kind.ERROR;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.service.AutoService;
+import java.util.Optional;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;
+
+/**
+ * An annotation {@link Processor} that reports errors for {@link Memoized @Memoized} methods that
+ * are not inside {@code AutoValue}-annotated classes.
+ */
+@AutoService(Processor.class)
+@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)
+@SupportedAnnotationTypes(MEMOIZED_NAME)
+public final class MemoizedValidator extends AbstractProcessor {
+  @Override
+  public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    Messager messager = processingEnv.getMessager();
+    TypeElement memoized = processingEnv.getElementUtils().getTypeElement(MEMOIZED_NAME);
+    for (ExecutableElement method : methodsIn(roundEnv.getElementsAnnotatedWith(memoized))) {
+      if (!isAutoValue(method.getEnclosingElement())) {
+        messager.printMessage(
+            ERROR,
+            "@Memoized methods must be declared only in @AutoValue classes",
+            method,
+            getAnnotationMirror(method, MEMOIZED_NAME).get());
+      }
+    }
+    return false;
+  }
+
+  @Override
+  public SourceVersion getSupportedSourceVersion() {
+    return SourceVersion.latestSupported();
+  }
+
+  private static boolean isAutoValue(Element element) {
+    return element
+        .getAnnotationMirrors()
+        .stream()
+        .map(annotation -> MoreTypes.asTypeElement(annotation.getAnnotationType()))
+        .anyMatch(type -> type.getQualifiedName().contentEquals("com.google.auto.value.AutoValue"));
+  }
+
+  static Optional<AnnotationMirror> getAnnotationMirror(Element element, String annotationName) {
+    for (AnnotationMirror annotation : element.getAnnotationMirrors()) {
+      TypeElement annotationElement = MoreTypes.asTypeElement(annotation.getAnnotationType());
+      if (annotationElement.getQualifiedName().contentEquals(annotationName)) {
+        return Optional.of(annotation);
+      }
+    }
+    return Optional.empty();
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/SerializableAutoValue.java b/value/src/main/java/com/google/auto/value/extension/serializable/SerializableAutoValue.java
new file mode 100644
index 0000000..b100e79
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/SerializableAutoValue.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotates {@link com.google.auto.value.AutoValue @AutoValue} classes that implement {@link
+ * java.io.Serializable}. A serializable subclass is generated for classes with normally
+ * un-serializable fields like {@link java.util.Optional}.
+ */
+@Retention(RetentionPolicy.SOURCE)
+@Target(ElementType.TYPE)
+public @interface SerializableAutoValue {}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/processor/ClassNames.java b/value/src/main/java/com/google/auto/value/extension/serializable/processor/ClassNames.java
new file mode 100644
index 0000000..96a9576
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/processor/ClassNames.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.processor;
+
+/** Names of classes that are referenced in /processor. */
+final class ClassNames {
+  static final String SERIALIZABLE_AUTO_VALUE_NAME =
+      "com.google.auto.value.extension.serializable.SerializableAutoValue";
+
+  private ClassNames() {}
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/processor/PropertyMirror.java b/value/src/main/java/com/google/auto/value/extension/serializable/processor/PropertyMirror.java
new file mode 100644
index 0000000..966ce44
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/processor/PropertyMirror.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.processor;
+
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A POJO containing information about an AutoValue's property.
+ *
+ * <p>For example, given this AutoValue property: <code>abstract T getX();</code>
+ *
+ * <ol>
+ *   <li>The type would be T.
+ *   <li>The name would be x.
+ *   <li>The method would be getX.
+ */
+final class PropertyMirror {
+
+  private final TypeMirror type;
+  private final String name;
+  private final String method;
+
+  PropertyMirror(TypeMirror type, String name, String method) {
+    this.type = type;
+    this.name = name;
+    this.method = method;
+  }
+
+  /** Gets the AutoValue property's type. */
+  TypeMirror getType() {
+    return type;
+  }
+
+  /** Gets the AutoValue property's name. */
+  String getName() {
+    return name;
+  }
+
+  /** Gets the AutoValue property accessor method. */
+  String getMethod() {
+    return method;
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/processor/SerializableAutoValueExtension.java b/value/src/main/java/com/google/auto/value/extension/serializable/processor/SerializableAutoValueExtension.java
new file mode 100644
index 0000000..d3265d0
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/processor/SerializableAutoValueExtension.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.processor;
+
+import static com.google.auto.value.extension.serializable.processor.ClassNames.SERIALIZABLE_AUTO_VALUE_NAME;
+import static com.google.common.collect.ImmutableList.toImmutableList;
+import static com.google.common.collect.ImmutableMap.toImmutableMap;
+import static java.util.stream.Collectors.joining;
+
+import com.google.auto.common.GeneratedAnnotationSpecs;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.service.AutoService;
+import com.google.auto.value.extension.AutoValueExtension;
+import com.google.auto.value.extension.serializable.serializer.SerializerFactoryLoader;
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;
+import com.google.common.base.Equivalence;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.squareup.javapoet.AnnotationSpec;
+import com.squareup.javapoet.ClassName;
+import com.squareup.javapoet.CodeBlock;
+import com.squareup.javapoet.FieldSpec;
+import com.squareup.javapoet.JavaFile;
+import com.squareup.javapoet.MethodSpec;
+import com.squareup.javapoet.ParameterizedTypeName;
+import com.squareup.javapoet.TypeName;
+import com.squareup.javapoet.TypeSpec;
+import com.squareup.javapoet.TypeVariableName;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Function;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * An AutoValue extension that enables classes with unserializable fields to be serializable.
+ *
+ * <p>For this extension to work:
+ *
+ * <ul>
+ *   <li>The AutoValue class must implement {@link Serializable}.
+ *   <li>Unserializable fields in the AutoValue class must be supported by a {@link
+ *       com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension}.
+ */
+@AutoService(AutoValueExtension.class)
+public final class SerializableAutoValueExtension extends AutoValueExtension {
+
+  @Override
+  public boolean applicable(Context context) {
+    return hasSerializableInterface(context) && hasSerializableAutoValueAnnotation(context);
+  }
+
+  @Override
+  public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {
+    return IncrementalExtensionType.ISOLATING;
+  }
+
+  @Override
+  public String generateClass(
+      Context context, String className, String classToExtend, boolean isFinal) {
+    return new Generator(context, className, classToExtend, isFinal).generate();
+  }
+
+  private static final class Generator {
+    private final Context context;
+    private final String className;
+    private final String classToExtend;
+    private final boolean isFinal;
+    private final ImmutableList<PropertyMirror> propertyMirrors;
+    private final ImmutableList<TypeVariableName> typeVariableNames;
+    private final ProxyGenerator proxyGenerator;
+
+    Generator(Context context, String className, String classToExtend, boolean isFinal) {
+      this.context = context;
+      this.className = className;
+      this.classToExtend = classToExtend;
+      this.isFinal = isFinal;
+
+      this.propertyMirrors =
+          context.propertyTypes().entrySet().stream()
+              .map(
+                  entry ->
+                      new PropertyMirror(
+                          /* type= */ entry.getValue(),
+                          /* name= */ entry.getKey(),
+                          /* method= */ context
+                              .properties()
+                              .get(entry.getKey())
+                              .getSimpleName()
+                              .toString()))
+              .collect(toImmutableList());
+      this.typeVariableNames =
+          context.autoValueClass().getTypeParameters().stream()
+              .map(TypeVariableName::get)
+              .collect(toImmutableList());
+
+      TypeName classTypeName =
+          getClassTypeName(ClassName.get(context.packageName(), className), typeVariableNames);
+      this.proxyGenerator =
+          new ProxyGenerator(
+              classTypeName, typeVariableNames, propertyMirrors, buildSerializersMap());
+    }
+
+    private String generate() {
+      ClassName superclass = ClassName.get(context.packageName(), classToExtend);
+      Optional<AnnotationSpec> generatedAnnotationSpec =
+          GeneratedAnnotationSpecs.generatedAnnotationSpec(
+              context.processingEnvironment().getElementUtils(),
+              context.processingEnvironment().getSourceVersion(),
+              SerializableAutoValueExtension.class);
+
+      TypeSpec.Builder subclass =
+          TypeSpec.classBuilder(className)
+              .superclass(getClassTypeName(superclass, typeVariableNames))
+              .addTypeVariables(typeVariableNames)
+              .addModifiers(isFinal ? Modifier.FINAL : Modifier.ABSTRACT)
+              .addMethod(constructor())
+              .addMethod(writeReplace())
+              .addType(proxyGenerator.generate());
+      generatedAnnotationSpec.ifPresent(subclass::addAnnotation);
+
+      return JavaFile.builder(context.packageName(), subclass.build()).build().toString();
+    }
+
+    /** Creates a constructor that calls super with all the AutoValue fields. */
+    private MethodSpec constructor() {
+      MethodSpec.Builder constructor =
+          MethodSpec.constructorBuilder()
+              .addStatement(
+                  "super($L)",
+                  propertyMirrors.stream().map(PropertyMirror::getName).collect(joining(", ")));
+
+      for (PropertyMirror propertyMirror : propertyMirrors) {
+        constructor.addParameter(TypeName.get(propertyMirror.getType()), propertyMirror.getName());
+      }
+
+      return constructor.build();
+    }
+
+    /**
+     * Creates an implementation of writeReplace that delegates serialization to its inner Proxy
+     * class.
+     */
+    private MethodSpec writeReplace() {
+      ImmutableList<CodeBlock> properties =
+          propertyMirrors.stream()
+              .map(propertyMirror -> CodeBlock.of("$L()", propertyMirror.getMethod()))
+              .collect(toImmutableList());
+
+      return MethodSpec.methodBuilder("writeReplace")
+          .returns(Object.class)
+          .addStatement(
+              "return new $T($L)",
+              getClassTypeName(
+                  ClassName.get(
+                      context.packageName(),
+                      className,
+                      SerializableAutoValueExtension.ProxyGenerator.PROXY_CLASS_NAME),
+                  typeVariableNames),
+              CodeBlock.join(properties, ", "))
+          .build();
+    }
+
+    private ImmutableMap<Equivalence.Wrapper<TypeMirror>, Serializer> buildSerializersMap() {
+      SerializerFactory factory =
+          SerializerFactoryLoader.getFactory(context.processingEnvironment());
+      return propertyMirrors.stream()
+          .map(PropertyMirror::getType)
+          .map(MoreTypes.equivalence()::wrap)
+          .distinct()
+          .collect(
+              toImmutableMap(
+                  Function.identity(), equivalence -> factory.getSerializer(equivalence.get())));
+    }
+
+    /** Adds type parameters to the given {@link ClassName}, if available. */
+    private static TypeName getClassTypeName(
+        ClassName className, List<TypeVariableName> typeVariableNames) {
+      return typeVariableNames.isEmpty()
+          ? className
+          : ParameterizedTypeName.get(className, typeVariableNames.toArray(new TypeName[] {}));
+    }
+  }
+
+  /** A generator of nested serializable Proxy classes. */
+  private static final class ProxyGenerator {
+    private static final String PROXY_CLASS_NAME = "Proxy$";
+
+    private final TypeName outerClassTypeName;
+    private final ImmutableList<TypeVariableName> typeVariableNames;
+    private final ImmutableList<PropertyMirror> propertyMirrors;
+    private final ImmutableMap<Equivalence.Wrapper<TypeMirror>, Serializer> serializersMap;
+
+    ProxyGenerator(
+        TypeName outerClassTypeName,
+        ImmutableList<TypeVariableName> typeVariableNames,
+        ImmutableList<PropertyMirror> propertyMirrors,
+        ImmutableMap<Equivalence.Wrapper<TypeMirror>, Serializer> serializersMap) {
+      this.outerClassTypeName = outerClassTypeName;
+      this.typeVariableNames = typeVariableNames;
+      this.propertyMirrors = propertyMirrors;
+      this.serializersMap = serializersMap;
+    }
+
+    private TypeSpec generate() {
+      TypeSpec.Builder proxy =
+          TypeSpec.classBuilder(PROXY_CLASS_NAME)
+              .addModifiers(Modifier.STATIC)
+              .addTypeVariables(typeVariableNames)
+              .addSuperinterface(Serializable.class)
+              .addField(serialVersionUid())
+              .addFields(properties())
+              .addMethod(constructor())
+              .addMethod(readResolve());
+
+      return proxy.build();
+    }
+
+    private static FieldSpec serialVersionUid() {
+      return FieldSpec.builder(
+              long.class, "serialVersionUID", Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
+          .initializer("0")
+          .build();
+    }
+
+    /** Maps each AutoValue property to a serializable type. */
+    private List<FieldSpec> properties() {
+      return propertyMirrors.stream()
+          .map(
+              propertyMirror ->
+                  FieldSpec.builder(
+                          TypeName.get(
+                              serializersMap
+                                  .get(MoreTypes.equivalence().wrap(propertyMirror.getType()))
+                                  .proxyFieldType()),
+                          propertyMirror.getName(),
+                          Modifier.PRIVATE)
+                      .build())
+          .collect(toImmutableList());
+    }
+
+    /** Creates a constructor that converts the AutoValue's properties to serializable values. */
+    private MethodSpec constructor() {
+      MethodSpec.Builder constructor = MethodSpec.constructorBuilder();
+
+      for (PropertyMirror propertyMirror : propertyMirrors) {
+        Serializer serializer =
+            serializersMap.get(MoreTypes.equivalence().wrap(propertyMirror.getType()));
+        String name = propertyMirror.getName();
+
+        constructor.addParameter(TypeName.get(propertyMirror.getType()), name);
+        constructor.addStatement(
+            CodeBlock.of("this.$L = $L", name, serializer.toProxy(CodeBlock.of(name))));
+      }
+
+      return constructor.build();
+    }
+
+    /**
+     * Creates an implementation of {@code readResolve} that returns the serializable values in the
+     * Proxy object back to their original types.
+     */
+    private MethodSpec readResolve() {
+      return MethodSpec.methodBuilder("readResolve")
+          .returns(Object.class)
+          .addException(Exception.class)
+          .addStatement(
+              "return new $T($L)",
+              outerClassTypeName,
+              CodeBlock.join(
+                  propertyMirrors.stream().map(this::resolve).collect(toImmutableList()), ", "))
+          .build();
+    }
+
+    /** Maps a serializable type back to its original AutoValue property. */
+    private CodeBlock resolve(PropertyMirror propertyMirror) {
+      return serializersMap
+          .get(MoreTypes.equivalence().wrap(propertyMirror.getType()))
+          .fromProxy(CodeBlock.of(propertyMirror.getName()));
+    }
+  }
+
+  private static boolean hasSerializableInterface(Context context) {
+    final TypeMirror serializableTypeMirror =
+        context
+            .processingEnvironment()
+            .getElementUtils()
+            .getTypeElement(Serializable.class.getCanonicalName())
+            .asType();
+
+    return context
+        .processingEnvironment()
+        .getTypeUtils()
+        .isAssignable(context.autoValueClass().asType(), serializableTypeMirror);
+  }
+
+  private static boolean hasSerializableAutoValueAnnotation(Context context) {
+    return context.autoValueClass().getAnnotationMirrors().stream()
+        .map(AnnotationMirror::getAnnotationType)
+        .map(MoreTypes::asTypeElement)
+        .map(TypeElement::getQualifiedName)
+        .anyMatch(name -> name.contentEquals(SERIALIZABLE_AUTO_VALUE_NAME));
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/SerializerFactoryLoader.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/SerializerFactoryLoader.java
new file mode 100644
index 0000000..12984b0
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/SerializerFactoryLoader.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer;
+
+import com.google.auto.value.extension.serializable.serializer.impl.SerializerFactoryImpl;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;
+import com.google.auto.value.processor.SimpleServiceLoader;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.tools.Diagnostic;
+
+/**
+ * Builds a {@link SerializerFactory} populated with discovered {@link SerializerExtension}
+ * instances.
+ */
+public final class SerializerFactoryLoader {
+
+  /**
+   * Returns a {@link SerializerFactory} with {@link SerializerExtension} instances provided by the
+   * {@link java.util.ServiceLoader}.
+   */
+  public static SerializerFactory getFactory(ProcessingEnvironment processingEnv) {
+    return new SerializerFactoryImpl(loadExtensions(processingEnv), processingEnv);
+  }
+
+  private static ImmutableList<SerializerExtension> loadExtensions(
+      ProcessingEnvironment processingEnv) {
+    try {
+      return ImmutableList.copyOf(
+          SimpleServiceLoader.load(
+              SerializerExtension.class, SerializerFactoryLoader.class.getClassLoader()));
+    } catch (Throwable t) {
+      processingEnv
+          .getMessager()
+          .printMessage(
+              Diagnostic.Kind.ERROR,
+              "An exception occurred while looking for SerializerExtensions. No extensions will"
+                  + " function.\n"
+                  + Throwables.getStackTraceAsString(t));
+      return ImmutableList.of();
+    }
+  }
+
+  private SerializerFactoryLoader() {}
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/IdentitySerializerFactory.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/IdentitySerializerFactory.java
new file mode 100644
index 0000000..83b8634
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/IdentitySerializerFactory.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.squareup.javapoet.CodeBlock;
+import javax.lang.model.type.TypeMirror;
+
+/** Creates identity {@link Serializer} instances. */
+public final class IdentitySerializerFactory {
+
+  /** Returns a {@link Serializer} that leaves the type as is. */
+  public static Serializer getSerializer(TypeMirror typeMirror) {
+    return new IdentitySerializer(typeMirror);
+  }
+
+  private static class IdentitySerializer implements Serializer {
+
+    private final TypeMirror typeMirror;
+
+    IdentitySerializer(TypeMirror typeMirror) {
+      this.typeMirror = typeMirror;
+    }
+
+    @Override
+    public TypeMirror proxyFieldType() {
+      return typeMirror;
+    }
+
+    @Override
+    public CodeBlock toProxy(CodeBlock expression) {
+      return expression;
+    }
+
+    @Override
+    public CodeBlock fromProxy(CodeBlock expression) {
+      return expression;
+    }
+
+    @Override
+    public boolean isIdentity() {
+      return true;
+    }
+  }
+
+  private IdentitySerializerFactory() {}
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableListSerializerExtension.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableListSerializerExtension.java
new file mode 100644
index 0000000..7ff4f19
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableListSerializerExtension.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.service.AutoService;
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;
+import com.google.auto.value.extension.serializable.serializer.runtime.FunctionWithExceptions;
+import com.google.common.collect.ImmutableList;
+import com.squareup.javapoet.CodeBlock;
+import java.util.Optional;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A {@link SerializerExtension} that deserializes objects inside an {@link ImmutableList}.
+ *
+ * <p>Enables unserializable objects inside an ImmutableList to be serializable.
+ */
+@AutoService(SerializerExtension.class)
+public final class ImmutableListSerializerExtension implements SerializerExtension {
+
+  public ImmutableListSerializerExtension() {}
+
+  @Override
+  public Optional<Serializer> getSerializer(
+      TypeMirror typeMirror, SerializerFactory factory, ProcessingEnvironment processingEnv) {
+    if (!isImmutableList(typeMirror)) {
+      return Optional.empty();
+    }
+
+    // Extract the T of ImmutableList<T>.
+    TypeMirror containedType = getContainedType(typeMirror);
+    Serializer containedTypeSerializer = factory.getSerializer(containedType);
+
+    // We don't need this serializer if the T of ImmutableList<T> is serializable.
+    if (containedTypeSerializer.isIdentity()) {
+      return Optional.empty();
+    }
+
+    return Optional.of(new ImmutableListSerializer(containedTypeSerializer, processingEnv));
+  }
+
+  private static class ImmutableListSerializer implements Serializer {
+
+    private final Serializer containedTypeSerializer;
+    private final ProcessingEnvironment processingEnv;
+
+    ImmutableListSerializer(
+        Serializer containedTypeSerializer, ProcessingEnvironment processingEnv) {
+      this.containedTypeSerializer = containedTypeSerializer;
+      this.processingEnv = processingEnv;
+    }
+
+    @Override
+    public TypeMirror proxyFieldType() {
+      TypeElement immutableListTypeElement =
+          processingEnv.getElementUtils().getTypeElement(ImmutableList.class.getCanonicalName());
+      TypeMirror containedProxyType = containedTypeSerializer.proxyFieldType();
+      return processingEnv
+          .getTypeUtils()
+          .getDeclaredType(immutableListTypeElement, containedProxyType);
+    }
+
+    @Override
+    public CodeBlock toProxy(CodeBlock expression) {
+      CodeBlock element = CodeBlock.of("value$$");
+      return CodeBlock.of(
+          "$L.stream().map($T.wrapper($L -> $L)).collect($T.toImmutableList())",
+          expression,
+          FunctionWithExceptions.class,
+          element,
+          containedTypeSerializer.toProxy(element),
+          ImmutableList.class);
+    }
+
+    @Override
+    public CodeBlock fromProxy(CodeBlock expression) {
+      CodeBlock element = CodeBlock.of("value$$");
+      return CodeBlock.of(
+          "$L.stream().map($T.wrapper($L -> $L)).collect($T.toImmutableList())",
+          expression,
+          FunctionWithExceptions.class,
+          element,
+          containedTypeSerializer.fromProxy(element),
+          ImmutableList.class);
+    }
+  }
+
+  private static boolean isImmutableList(TypeMirror type) {
+    if (type.getKind() != TypeKind.DECLARED) {
+      return false;
+    }
+
+    return MoreTypes.asTypeElement(type)
+        .getQualifiedName()
+        .contentEquals("com.google.common.collect.ImmutableList");
+  }
+
+  private static TypeMirror getContainedType(TypeMirror type) {
+    return MoreTypes.asDeclared(type).getTypeArguments().get(0);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableMapSerializerExtension.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableMapSerializerExtension.java
new file mode 100644
index 0000000..9d571e3
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableMapSerializerExtension.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.service.AutoService;
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;
+import com.google.auto.value.extension.serializable.serializer.runtime.FunctionWithExceptions;
+import com.google.common.collect.ImmutableMap;
+import com.squareup.javapoet.CodeBlock;
+import java.util.Optional;
+import java.util.function.Function;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A {@link SerializerExtension} that deserializes objects inside an {@link ImmutableMap}.
+ *
+ * <p>Enables unserializable objects inside an ImmutableMap to be serializable.
+ */
+@AutoService(SerializerExtension.class)
+public final class ImmutableMapSerializerExtension implements SerializerExtension {
+
+  public ImmutableMapSerializerExtension() {}
+
+  @Override
+  public Optional<Serializer> getSerializer(
+      TypeMirror typeMirror, SerializerFactory factory, ProcessingEnvironment processingEnv) {
+    if (!isImmutableMap(typeMirror)) {
+      return Optional.empty();
+    }
+
+    // Extract the K, V of ImmutableMap<K, V>.
+    TypeMirror keyType = getKeyType(typeMirror);
+    TypeMirror valueType = getValueType(typeMirror);
+    Serializer keyTypeSerializer = factory.getSerializer(keyType);
+    Serializer valueTypeSerializer = factory.getSerializer(valueType);
+
+    // We don't need this serializer if the K and V of ImmutableMap<K, V> are serializable.
+    if (keyTypeSerializer.isIdentity() && valueTypeSerializer.isIdentity()) {
+      return Optional.empty();
+    }
+
+    return Optional.of(
+        new ImmutableMapSerializer(
+            keyType, valueType, keyTypeSerializer, valueTypeSerializer, processingEnv));
+  }
+
+  private static class ImmutableMapSerializer implements Serializer {
+
+    private final TypeMirror keyType;
+    private final TypeMirror valueType;
+    private final TypeMirror keyProxyType;
+    private final TypeMirror valueProxyType;
+    private final Serializer keyTypeSerializer;
+    private final Serializer valueTypeSerializer;
+    private final ProcessingEnvironment processingEnv;
+
+    ImmutableMapSerializer(
+        TypeMirror keyType,
+        TypeMirror valueType,
+        Serializer keyTypeSerializer,
+        Serializer valueTypeSerializer,
+        ProcessingEnvironment processingEnv) {
+      this.keyType = keyType;
+      this.valueType = valueType;
+      this.keyProxyType = keyTypeSerializer.proxyFieldType();
+      this.valueProxyType = valueTypeSerializer.proxyFieldType();
+      this.keyTypeSerializer = keyTypeSerializer;
+      this.valueTypeSerializer = valueTypeSerializer;
+      this.processingEnv = processingEnv;
+    }
+
+    @Override
+    public TypeMirror proxyFieldType() {
+      TypeElement immutableMapTypeElement =
+          processingEnv.getElementUtils().getTypeElement(ImmutableMap.class.getCanonicalName());
+      return processingEnv
+          .getTypeUtils()
+          .getDeclaredType(immutableMapTypeElement, keyProxyType, valueProxyType);
+    }
+
+    @Override
+    public CodeBlock toProxy(CodeBlock expression) {
+      return CodeBlock.of(
+          "$L.entrySet().stream().collect($T.toImmutableMap($L, $L))",
+          expression,
+          ImmutableMap.class,
+          generateKeyMapFunction(keyType, keyProxyType, keyTypeSerializer::toProxy),
+          generateValueMapFunction(valueType, valueProxyType, valueTypeSerializer::toProxy));
+    }
+
+    @Override
+    public CodeBlock fromProxy(CodeBlock expression) {
+      return CodeBlock.of(
+          "$L.entrySet().stream().collect($T.toImmutableMap($L, $L))",
+          expression,
+          ImmutableMap.class,
+          generateKeyMapFunction(keyProxyType, keyType, keyTypeSerializer::fromProxy),
+          generateValueMapFunction(valueProxyType, valueType, valueTypeSerializer::fromProxy));
+    }
+
+    private static CodeBlock generateKeyMapFunction(
+        TypeMirror originalType,
+        TypeMirror transformedType,
+        Function<CodeBlock, CodeBlock> proxyMap) {
+      CodeBlock element = CodeBlock.of("element$$");
+      return CodeBlock.of(
+          "value$$ -> $T.<$T, $T>wrapper($L -> $L).apply(value$$.getKey())",
+          FunctionWithExceptions.class,
+          originalType,
+          transformedType,
+          element,
+          proxyMap.apply(element));
+    }
+
+    private static CodeBlock generateValueMapFunction(
+        TypeMirror originalType,
+        TypeMirror transformedType,
+        Function<CodeBlock, CodeBlock> proxyMap) {
+      CodeBlock element = CodeBlock.of("element$$");
+      return CodeBlock.of(
+          "value$$ -> $T.<$T, $T>wrapper($L -> $L).apply(value$$.getValue())",
+          FunctionWithExceptions.class,
+          originalType,
+          transformedType,
+          element,
+          proxyMap.apply(element));
+    }
+  }
+
+  private static boolean isImmutableMap(TypeMirror type) {
+    if (type.getKind() != TypeKind.DECLARED) {
+      return false;
+    }
+
+    return MoreTypes.asTypeElement(type)
+        .getQualifiedName()
+        .contentEquals("com.google.common.collect.ImmutableMap");
+  }
+
+  private static TypeMirror getKeyType(TypeMirror type) {
+    return MoreTypes.asDeclared(type).getTypeArguments().get(0);
+  }
+
+  private static TypeMirror getValueType(TypeMirror type) {
+    return MoreTypes.asDeclared(type).getTypeArguments().get(1);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/OptionalSerializerExtension.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/OptionalSerializerExtension.java
new file mode 100644
index 0000000..a5025a8
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/OptionalSerializerExtension.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.service.AutoService;
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;
+import com.squareup.javapoet.CodeBlock;
+import java.util.Optional;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A {@link SerializerExtension} that enables {@link Optional} types to be serialized.
+ *
+ * <p>The type argument {@code T} of {@code Optional<T>} is queried against the {@link
+ * SerializerFactory}.
+ */
+@AutoService(SerializerExtension.class)
+public final class OptionalSerializerExtension implements SerializerExtension {
+
+  public OptionalSerializerExtension() {}
+
+  /** Creates a {@link Serializer} that supports {@link Optional} types. */
+  @Override
+  public Optional<Serializer> getSerializer(
+      TypeMirror typeMirror, SerializerFactory factory, ProcessingEnvironment processingEnv) {
+    if (!isOptional(typeMirror)) {
+      return Optional.empty();
+    }
+
+    // Extract the T of Optional<T>.
+    TypeMirror containedType = getContainedType(typeMirror);
+    Serializer containedTypeSerializer = factory.getSerializer(containedType);
+
+    return Optional.of(new OptionalSerializer(containedTypeSerializer));
+  }
+
+  private static class OptionalSerializer implements Serializer {
+
+    private final Serializer containedTypeSerializer;
+
+    OptionalSerializer(Serializer containedTypeSerializer) {
+      this.containedTypeSerializer = containedTypeSerializer;
+    }
+
+    @Override
+    public TypeMirror proxyFieldType() {
+      // If this is an Optional<String> then the proxy field type is String.
+      // If this is an Optional<Foo>, and the proxy field type for Foo is Bar, then the proxy field
+      // type for Optional<Foo> is Bar.
+      return containedTypeSerializer.proxyFieldType();
+    }
+
+    @Override
+    public CodeBlock toProxy(CodeBlock expression) {
+      return CodeBlock.of(
+          "$L.isPresent() ? $L : null",
+          expression,
+          containedTypeSerializer.toProxy(CodeBlock.of("$L.get()", expression)));
+    }
+
+    @Override
+    public CodeBlock fromProxy(CodeBlock expression) {
+      return CodeBlock.of(
+          "$T.ofNullable($L == null ? null : $L)",
+          Optional.class,
+          expression,
+          containedTypeSerializer.fromProxy(expression));
+    }
+  }
+
+  /** Checks if the given type is an {@link Optional}. */
+  private static boolean isOptional(TypeMirror type) {
+    if (type.getKind() != TypeKind.DECLARED) {
+      return false;
+    }
+
+    return MoreTypes.asTypeElement(type).getQualifiedName().contentEquals("java.util.Optional");
+  }
+
+  /**
+   * Gets the given type's first type argument.
+   *
+   * <p>Returns the {@code T} in {@code Optional<T>}.
+   */
+  private static TypeMirror getContainedType(TypeMirror type) {
+    return MoreTypes.asDeclared(type).getTypeArguments().get(0);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/SerializerFactoryImpl.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/SerializerFactoryImpl.java
new file mode 100644
index 0000000..57741f9
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/impl/SerializerFactoryImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;
+import com.google.common.collect.ImmutableList;
+import java.util.Optional;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.type.TypeMirror;
+
+/** A concrete implementation of {@link SerializerFactory}. */
+public final class SerializerFactoryImpl implements SerializerFactory {
+
+  private final ImmutableList<SerializerExtension> extensions;
+  private final ProcessingEnvironment env;
+
+  public SerializerFactoryImpl(
+      ImmutableList<SerializerExtension> extensions, ProcessingEnvironment env) {
+    this.extensions = extensions;
+    this.env = env;
+  }
+
+  @Override
+  public Serializer getSerializer(TypeMirror typeMirror) {
+    for (SerializerExtension extension : extensions) {
+      Optional<Serializer> serializer = extension.getSerializer(typeMirror, this, env);
+      if (serializer.isPresent()) {
+        return serializer.get();
+      }
+    }
+    return IdentitySerializerFactory.getSerializer(typeMirror);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/Serializer.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/Serializer.java
new file mode 100644
index 0000000..96b9308
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/Serializer.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.interfaces;
+
+import com.squareup.javapoet.CodeBlock;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A Serializer, at compile time, generates code to map an unserializable type to a serializable
+ * type. It also generates the reverse code to re-create the original type.
+ */
+public interface Serializer {
+
+  /** The proxy type the original unserializable type will be mapped to. */
+  TypeMirror proxyFieldType();
+
+  /** Creates an expression that converts the original type to the proxy type. */
+  CodeBlock toProxy(CodeBlock expression);
+
+  /** Creates an expression that converts the proxy type back to the original type. */
+  CodeBlock fromProxy(CodeBlock expression);
+
+  /** Returns true if this is an identity {@link Serializer}. */
+  default boolean isIdentity() {
+    return false;
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerExtension.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerExtension.java
new file mode 100644
index 0000000..6e38b9b
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerExtension.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.interfaces;
+
+import java.util.Optional;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A SerializerExtension allows unserializable types to be serialized by SerializableAutoValue.
+ *
+ * <p>Extensions are discovered at compile time using the {@link java.util.ServiceLoader} APIs,
+ * allowing them to run without any additional annotations. To be found by {@code ServiceLoader}, an
+ * extension class must be public with a public no-arg constructor, and its fully-qualified name
+ * must appear in a file called {@code
+ * META-INF/services/com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension}
+ * in a jar that is on the compiler's {@code -classpath} or {@code -processorpath}.
+ *
+ * <p>When SerializableAutoValue maps each field in an AutoValue to a serializable proxy object, it
+ * asks each SerializerExtension whether it can generate code to make the given type serializable. A
+ * SerializerExtension replies that it can by returning a non-empty {@link Serializer}.
+ *
+ * <p>A SerializerExtension is also provided with a SerializerFactory, which it can use to query
+ * nested types.
+ */
+public interface SerializerExtension {
+
+  /**
+   * Returns a {@link Serializer} if this {@link SerializerExtension} applies to the given {@code
+   * type}. Otherwise, {@code Optional.empty} is returned.
+   *
+   * @param type the type being serialized
+   * @param factory a {@link SerializerFactory} that can be used to serialize nested types
+   * @param processingEnv the processing environment provided by the annotation processing framework
+   */
+  Optional<Serializer> getSerializer(
+      TypeMirror type, SerializerFactory factory, ProcessingEnvironment processingEnv);
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerFactory.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerFactory.java
new file mode 100644
index 0000000..d05c88b
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerFactory.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.interfaces;
+
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A factory that returns a {@link Serializer} for any given {@link TypeMirror}.
+ *
+ * <p>Defaults to an identity serializer if no SerializerExtensions are suitable.
+ */
+public interface SerializerFactory {
+
+  /** Returns a {@link Serializer} for the given {@link TypeMirror}. */
+  Serializer getSerializer(TypeMirror type);
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/serializer/runtime/FunctionWithExceptions.java b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/runtime/FunctionWithExceptions.java
new file mode 100644
index 0000000..93aa600
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/serializer/runtime/FunctionWithExceptions.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.runtime;
+
+import java.util.function.Function;
+
+/** A utility for lambdas that throw exceptions. */
+public final class FunctionWithExceptions {
+
+  /** Creates a wrapper for lambdas that converts checked exceptions to runtime exceptions. */
+  public static <I, O> Function<I, O> wrapper(FunctionWithException<I, O> fe) {
+    return arg -> {
+      try {
+        return fe.apply(arg);
+      } catch (Exception e) {
+        throw new RuntimeException(e);
+      }
+    };
+  }
+
+  /** A function that can throw an exception. */
+  @FunctionalInterface
+  public interface FunctionWithException<I, O> {
+    O apply(I i) throws Exception;
+  }
+
+  private FunctionWithExceptions() {}
+}
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/userguide/index.md b/value/src/main/java/com/google/auto/value/extension/serializable/userguide/index.md
new file mode 100644
index 0000000..e766183
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/userguide/index.md
@@ -0,0 +1,103 @@
+# Serializable AutoValue Extension
+
+
+An [`AutoValue`] extension that enables `@AutoValue` classes with
+un-serializable properties to be serializable.
+
+
+## Usage
+
+To use the [`SerializableAutoValueExtension`] with your `AutoValue` class, the
+`AutoValue` class must:
+
+1.  Implement `java.io.Serializable`.
+2.  Be annotated with `@SerializableAutoValue`.
+
+## Example
+
+The following `AutoValue` class is un-serializable:
+
+```java
+@AutoValue
+public abstract class Foo implements Serializable {
+
+  public static Foo create(Optional<String> x) {
+    return new AutoValue_Foo(x);
+  }
+
+  // java.util.Optional is not serializable.
+  abstract Optional<String> x;
+}
+```
+
+This is because `java.util.Optional` is un-serializable. We can make `Foo`
+serializable by using the [`SerializableAutoValueExtension`].
+
+```java
+@SerializableAutoValue  // This annotation activates the extension.
+@AutoValue
+public abstract class Foo implements Serializable {
+  ...
+}
+```
+
+## Details
+
+For the example class `Foo` above, `SerializableAutoValueExtension` will
+generate the following code:
+
+```java
+@Generated("SerializableAutoValueExtension")
+final class AutoValue_Foo extends $AutoValue_Foo {
+
+  // Instead of serializing AutoValue_Foo, we delegate serialization to a
+  // proxy object.
+  Object writeReplace() throws ObjectStreamException {
+    return new Proxy$(this.x);
+  }
+
+  // When serializing, AutoValue_Foo's values are written to Proxy$.
+  // When de-serializing, Proxy$'s values used to create a new instance of
+  // AutoValue_Foo
+  static class Proxy$ implements Serializable {
+
+    private String x;
+
+    // During serialization, un-wrap the Optional field.
+    Proxy$(Optional<String> x) {
+      this.x = x.orElse(null);
+    }
+
+    // During de-serialization, re-create AutoValue_Foo.
+    Object readResolve() throws ObjectStreamException {
+      return new AutoValue_Foo(Optional.ofNullable(x));
+    }
+  }
+}
+```
+
+`SerializableAutoValueExtension` delegates the serialization of `Foo` to a proxy
+object `Proxy$` where `Foo`'s data is unwrapped.
+
+## Supported Types
+
+`SerializableAutoValueExtension` currently supports the following types:
+
+*   `java.util.Optional`
+*   `com.google.common.collect.ImmutableList`
+    *   Enables `ImmutableList<T>`, where `T` is an un-serializable but
+        supported type, to be serializable.
+*   `com.google.common.collect.ImmutableMap`
+    *   Enables `ImmutableMap<K, V>`, where `K` and/or `V` are un-serializable
+        but supported types, to be serializable.
+
+### Extensions
+
+`SerializableAutoValueExtension` can be extended to support additional
+un-serializable types with [SerializerExtensions].
+
+[`AutoValue`]: https://github.com/google/auto/tree/master/value
+[`SerializableAutoValue`]: https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/extension/serializable/SerializableAutoValue.java
+[`SerializableAutoValueExtension`]: https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/extension/serializable/extension/SerializableAutoValueExtension.java
+[SerializerExtensions]: https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/extension/serializable/userguide/serializer-extension.md
+
diff --git a/value/src/main/java/com/google/auto/value/extension/serializable/userguide/serializer-extension.md b/value/src/main/java/com/google/auto/value/extension/serializable/userguide/serializer-extension.md
new file mode 100644
index 0000000..edfa3ca
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/extension/serializable/userguide/serializer-extension.md
@@ -0,0 +1,246 @@
+# Serializer Extensions
+
+
+[`SerializableAutoValueExtension`] can be extended to support additional
+un-serializable types. Extensions are created by implementing
+[`SerializerExtension`].
+
+[TOC]
+
+## Using SerializerExtensions
+
+To use an extension that's not bundled with [`SerializableAutoValueExtension`],
+include it in your `AutoValue` class's dependencies.
+
+## Writing a SerializerExtension
+
+To add serialization support to a new type, write a class that extends
+[`SerializerExtension`]. Put that class on the `processorpath` along with
+`SerializerExtension`.
+
+See [`AutoService`] for Java extension loading information.
+
+### How SerializerExtension Works
+
+`SerializableAutoValueExtension` iterates through each property of the
+`@AutoValue` class and tries to look up a `SerializerExtension` for the
+property's type. If a `SerializerExtension` is available, a [`Serializer`] is
+returned. The `Serializer` does three things:
+
+1.  From the original property's type, determine what a suitable serializable
+    type is.
+2.  Generate an expression that maps the original property's value to the proxy
+    value.
+3.  Generate an expression that maps a proxy value back to the original
+    property's value.
+
+### Example
+
+We have a `Foo` AutoValue class that we would like to serialize:
+
+```java
+@SerializableAutoValue
+@AutoValue
+public abstract class Foo implements Serializable {
+
+  public static Foo create(Bar bar) {
+    return new AutoValue_Foo(bar);
+  }
+
+  // Bar is unserializable.
+  abstract Bar bar();
+}
+
+// An un-serializable class.
+public final class Bar {
+
+  public int x;
+
+  public Bar(int x) {
+    this.x = x;
+  }
+}
+```
+
+Unfortunately, `Bar` is un-serializable, which makes the entire class
+un-serializable. We can extend `SerializableAutoValue` to support `Bar` by
+implementing a `SerializerExtension` for `Bar`.
+
+```java
+// Use AutoService to make BarSerializerExtension discoverable by java.util.ServiceLoader.
+@AutoService(SerializerExtension.class)
+public final class BarSerializerExtension implements SerializerExtension {
+
+  // Service providers must have a public constructor with no formal parameters.
+  public BarSerializerExtension() {}
+
+  // This method is called for each property in an AutoValue.
+  // When this extension can handle a type (i.e. Bar), we return a Serializer.
+  called on all SerializerExtensions.
+  @Override
+  public Optional<Serializer> getSerializer(
+      TypeMirror type,
+      SerializerFactory factory,
+      ProcessingEnvironment env) {
+    // BarSerializerExtension only handles Bar types.
+    if (!isBar(type)) {
+      return Optional.empty();
+    }
+
+    return Optional.of(new BarSerializer(env));
+  }
+
+  // Our implementation of how Bar should be serialized + de-serialized.
+  private static class BarSerializer implements Serializer {
+
+    private final ProcessingEnvironment env;
+
+    BarSerializer(ProcessingEnvironment env) {
+      this.env = env;
+    }
+
+    // One way to serialize Bar is to just serialize Bar.x.
+    // We can do that by mapping Bar to an int.
+    @Override
+    public TypeMirror proxyFieldType() {
+      return Types.getPrimitiveType(TypeKind.INT);
+    }
+
+    // We need to map Bar to the type we declared in {@link #proxyFieldType}.
+    // Note that {@code expression} is a variable of type Bar.
+    @Override
+    public CodeBlock toProxy(CodeBlock expression) {
+      return CodeBlock.of("$L.x", expression);
+    }
+
+    // We need to map the integer back to a Bar.
+    @Override
+    public CodeBlock fromProxy(CodeBlock expression) {
+      return CodeBlock.of("new $T($L)", Bar.class, expression);
+    }
+  }
+}
+```
+
+`BarSerializerExtension` enables AutoValue classes with `Bar` properties to be
+serialized. For our example class `Foo`, it would help `SerializableAutoValue`
+generate the following code:
+
+```java
+@Generated("SerializableAutoValueExtension")
+final class AutoValue_Foo extends $AutoValue_Foo {
+
+  Object writeReplace() throws ObjectStreamException {
+    return new Proxy$(this.x);
+  }
+
+  static class Proxy$ implements Serializable {
+
+    // The type is generated by {@code BarSerializer#proxyFieldType}.
+    private int bar;
+
+    Proxy$(Bar bar) {
+      // The assignment expression is generated by {@code BarSerializer#toProxy}.
+      this.bar = bar.x;
+    }
+
+    Object readResolve() throws ObjectStreamException {
+      // The reverse mapping expression is generated by {@code BarSerializer#fromProxy}.
+      return new AutoValue_Foo(new Bar(bar));
+    }
+  }
+}
+```
+
+### Type Parameters
+
+Objects with type parameters are also supported by `SerializerExtension`.
+
+For example:
+
+```java
+// A potentially un-serializable class, depending on the actual type of T.
+public final class Baz<T> implements Serializable {
+
+  public T x;
+
+  public Baz(int x) {
+    this.x = x;
+  }
+}
+```
+
+`Baz`'s type argument `T` may not be serializable, but we could create a
+`SerializerExtension` that supports `Baz` by asking for a `SerializerExtension`
+for `T`.
+
+```java
+@AutoService(SerializerExtension.class)
+public final class BazSerializerExtension implements SerializerExtension {
+
+  public BazSerializerExtension() {}
+
+  @Override
+  public Optional<Serializer> getSerializer(
+        TypeMirror type,
+        SerializerFactory factory,
+        ProcessingEnvironment env) {
+    if (!isBaz(type)) {
+      return Optional.empty();
+    }
+
+    // Extract the T of Baz<T>.
+    TypeMirror containedType = getContainedType(type);
+
+    // Look up a serializer for the contained type T.
+    Serializer containedTypeSerializer = factory.getSerializer(containedType);
+
+    // If the serializer for the contained type T is an identity function, it
+    // means the contained type is either serializable or unsupported.
+    // Either way, nothing needs to be done. Baz can be serialized as is.
+    if (containedTypeSerializer.isIdentity()) {
+      return Optional.empty();
+    }
+
+    // Make Baz serializable by using the contained type T serializer.
+    return Optional.of(new BazSerializer(containedTypeSerializer));
+  }
+
+  private static class BazSerializer implements Serializer {
+
+    private Serializer serializer;
+
+    BazSerializer(Serializer serialize) {
+      this.serializer = serializer;
+    }
+
+    @Override
+    public TypeMirror proxyFieldType() {
+      // Since the contained type "T" is Baz's only field, we map Baz to "T"'s
+      // proxy type.
+      return serializer.proxyFieldType();
+    }
+
+    @Override
+    public CodeBlock toProxy(CodeBlock expression) {
+      return serializer.toProxy(expression);
+    }
+
+    @Override
+    public CodeBlock fromProxy(CodeBlock expression) {
+      return serializer.fromProxy(expression);
+    }
+  }
+}
+```
+
+This implementation uses `SerializerFactory` to find a `Serializer` for `T`. If
+a `Serializer` is available, we use it to map `Baz` to a serializable type. If
+no `Serializer` is available, we can do nothing and let `Baz` be serialized
+as-is.
+
+[AutoService]: https://github.com/google/auto/tree/master/service
+[`SerializableAutoValueExtension`]: https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/extension/serializable/extension/SerializableAutoValueExtension.java
+[`SerializerExtension`]: https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/SerializerExtension.java
+[`Serializer`]: https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/extension/serializable/serializer/interfaces/Serializer.java
+
diff --git a/value/src/main/java/com/google/auto/value/processor/AbortProcessingException.java b/value/src/main/java/com/google/auto/value/processor/AbortProcessingException.java
new file mode 100644
index 0000000..c234f22
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AbortProcessingException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+/**
+ * Exception thrown when annotation processing should be aborted for the current class. Processing
+ * can continue on other classes. Throwing this exception does not cause a compiler error, so either
+ * one should explicitly be emitted or it should be clear that the compiler will be producing its
+ * own error for other reasons.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@SuppressWarnings("serial")
+class AbortProcessingException extends RuntimeException {}
diff --git a/value/src/main/java/com/google/auto/value/processor/AnnotationOutput.java b/value/src/main/java/com/google/auto/value/processor/AnnotationOutput.java
new file mode 100644
index 0000000..ed986ab
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AnnotationOutput.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+import javax.tools.Diagnostic;
+
+/**
+ * Handling of default values for annotation members.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+final class AnnotationOutput {
+  private AnnotationOutput() {} // There are no instances of this class.
+
+  /**
+   * Visitor that produces a string representation of an annotation value, suitable for inclusion in
+   * a Java source file as an annotation member or as the initializer of a variable of the
+   * appropriate type. The syntax for the two is the same except for annotation members that are
+   * themselves annotations. Within an annotation, an annotation member can be written as
+   * {@code @NestedAnnotation(...)}, while in an initializer it must be written as an object, for
+   * example the construction of an {@code @AutoAnnotation} class. That's why we have this abstract
+   * class and two concrete subclasses.
+   */
+  private abstract static class SourceFormVisitor
+      extends SimpleAnnotationValueVisitor8<Void, StringBuilder> {
+    @Override
+    protected Void defaultAction(Object value, StringBuilder sb) {
+      sb.append(value);
+      return null;
+    }
+
+    @Override
+    public Void visitArray(List<? extends AnnotationValue> values, StringBuilder sb) {
+      sb.append('{');
+      String sep = "";
+      for (AnnotationValue value : values) {
+        sb.append(sep);
+        visit(value, sb);
+        sep = ", ";
+      }
+      sb.append('}');
+      return null;
+    }
+
+    @Override
+    public Void visitChar(char c, StringBuilder sb) {
+      appendQuoted(sb, c);
+      return null;
+    }
+
+    @Override
+    public Void visitLong(long i, StringBuilder sb) {
+      sb.append(i).append('L');
+      return null;
+    }
+
+    @Override
+    public Void visitDouble(double d, StringBuilder sb) {
+      if (Double.isNaN(d)) {
+        sb.append("Double.NaN");
+      } else if (d == Double.POSITIVE_INFINITY) {
+        sb.append("Double.POSITIVE_INFINITY");
+      } else if (d == Double.NEGATIVE_INFINITY) {
+        sb.append("Double.NEGATIVE_INFINITY");
+      } else {
+        sb.append(d);
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitFloat(float f, StringBuilder sb) {
+      if (Float.isNaN(f)) {
+        sb.append("Float.NaN");
+      } else if (f == Float.POSITIVE_INFINITY) {
+        sb.append("Float.POSITIVE_INFINITY");
+      } else if (f == Float.NEGATIVE_INFINITY) {
+        sb.append("Float.NEGATIVE_INFINITY");
+      } else {
+        sb.append(f).append('F');
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitEnumConstant(VariableElement c, StringBuilder sb) {
+      sb.append(TypeEncoder.encode(c.asType())).append('.').append(c.getSimpleName());
+      return null;
+    }
+
+    @Override
+    public Void visitString(String s, StringBuilder sb) {
+      appendQuoted(sb, s);
+      return null;
+    }
+
+    @Override
+    public Void visitType(TypeMirror classConstant, StringBuilder sb) {
+      sb.append(TypeEncoder.encode(classConstant)).append(".class");
+      return null;
+    }
+  }
+
+  private static class InitializerSourceFormVisitor extends SourceFormVisitor {
+    private final ProcessingEnvironment processingEnv;
+    private final String memberName;
+    private final Element context;
+
+    InitializerSourceFormVisitor(
+        ProcessingEnvironment processingEnv, String memberName, Element context) {
+      this.processingEnv = processingEnv;
+      this.memberName = memberName;
+      this.context = context;
+    }
+
+    @Override
+    public Void visitAnnotation(AnnotationMirror a, StringBuilder sb) {
+      processingEnv
+          .getMessager()
+          .printMessage(
+              Diagnostic.Kind.ERROR,
+              "@AutoAnnotation cannot yet supply a default value for annotation-valued member '"
+                  + memberName
+                  + "'",
+              context);
+      sb.append("null");
+      return null;
+    }
+  }
+
+  private static class AnnotationSourceFormVisitor extends SourceFormVisitor {
+    @Override
+    public Void visitArray(List<? extends AnnotationValue> values, StringBuilder sb) {
+      if (values.size() == 1) {
+        // We can shorten @Foo(a = {23}) to @Foo(a = 23). For the specific case where `a` is
+        // actually `value`, we'll already have shortened that in visitAnnotation, so effectively we
+        // go from @Foo(value = {23}) to @Foo({23}) to @Foo(23).
+        visit(values.get(0), sb);
+        return null;
+      }
+      return super.visitArray(values, sb);
+    }
+
+    @Override
+    public Void visitAnnotation(AnnotationMirror a, StringBuilder sb) {
+      sb.append('@').append(TypeEncoder.encode(a.getAnnotationType()));
+      ImmutableMap<ExecutableElement, AnnotationValue> map =
+          ImmutableMap.copyOf(a.getElementValues());
+      if (!map.isEmpty()) {
+        sb.append('(');
+        Optional<AnnotationValue> shortForm = shortForm(map);
+        if (shortForm.isPresent()) {
+          this.visit(shortForm.get(), sb);
+        } else {
+          String sep = "";
+          for (Map.Entry<ExecutableElement, AnnotationValue> entry : map.entrySet()) {
+            sb.append(sep).append(entry.getKey().getSimpleName()).append(" = ");
+            sep = ", ";
+            this.visit(entry.getValue(), sb);
+          }
+        }
+        sb.append(')');
+      }
+      return null;
+    }
+
+    // We can shorten @Annot(value = 23) to @Annot(23).
+    private static Optional<AnnotationValue> shortForm(
+        Map<ExecutableElement, AnnotationValue> values) {
+      if (values.size() == 1
+          && Iterables.getOnlyElement(values.keySet()).getSimpleName().contentEquals("value")) {
+        return Optional.of(Iterables.getOnlyElement(values.values()));
+      }
+      return Optional.empty();
+    }
+  }
+
+  /**
+   * Returns a string representation of the given annotation value, suitable for inclusion in a Java
+   * source file as the initializer of a variable of the appropriate type.
+   */
+  static String sourceFormForInitializer(
+      AnnotationValue annotationValue,
+      ProcessingEnvironment processingEnv,
+      String memberName,
+      Element context) {
+    SourceFormVisitor visitor =
+        new InitializerSourceFormVisitor(processingEnv, memberName, context);
+    StringBuilder sb = new StringBuilder();
+    visitor.visit(annotationValue, sb);
+    return sb.toString();
+  }
+
+  /**
+   * Returns a string representation of the given annotation mirror, suitable for inclusion in a
+   * Java source file to reproduce the annotation in source form.
+   */
+  static String sourceFormForAnnotation(AnnotationMirror annotationMirror) {
+    StringBuilder sb = new StringBuilder();
+    new AnnotationSourceFormVisitor().visitAnnotation(annotationMirror, sb);
+    return sb.toString();
+  }
+
+  private static StringBuilder appendQuoted(StringBuilder sb, String s) {
+    sb.append('"');
+    for (int i = 0; i < s.length(); i++) {
+      appendEscaped(sb, s.charAt(i));
+    }
+    return sb.append('"');
+  }
+
+  private static StringBuilder appendQuoted(StringBuilder sb, char c) {
+    sb.append('\'');
+    appendEscaped(sb, c);
+    return sb.append('\'');
+  }
+
+  private static void appendEscaped(StringBuilder sb, char c) {
+    switch (c) {
+      case '\\':
+      case '"':
+      case '\'':
+        sb.append('\\').append(c);
+        break;
+      case '\n':
+        sb.append("\\n");
+        break;
+      case '\r':
+        sb.append("\\r");
+        break;
+      case '\t':
+        sb.append("\\t");
+        break;
+      default:
+        if (c < 0x20) {
+          sb.append(String.format("\\%03o", (int) c));
+        } else if (c < 0x7f || Character.isLetter(c)) {
+          sb.append(c);
+        } else {
+          sb.append(String.format("\\u%04x", (int) c));
+        }
+        break;
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/AutoAnnotationProcessor.java b/value/src/main/java/com/google/auto/value/processor/AutoAnnotationProcessor.java
new file mode 100644
index 0000000..d3cd9bd
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AutoAnnotationProcessor.java
@@ -0,0 +1,568 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.auto.common.GeneratedAnnotations.generatedAnnotation;
+import static com.google.auto.value.processor.ClassNames.AUTO_ANNOTATION_NAME;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.SuperficialValidation;
+import com.google.auto.service.AutoService;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.primitives.Primitives;
+import com.google.errorprone.annotations.FormatMethod;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;
+
+/**
+ * Javac annotation processor (compiler plugin) to generate annotation implementations. User code
+ * never references this class.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@AutoService(Processor.class)
+@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)
+@SupportedAnnotationTypes(AUTO_ANNOTATION_NAME)
+public class AutoAnnotationProcessor extends AbstractProcessor {
+  public AutoAnnotationProcessor() {}
+
+  @Override
+  public SourceVersion getSupportedSourceVersion() {
+    return SourceVersion.latestSupported();
+  }
+
+  /**
+   * Issue a compilation error. This method does not throw an exception, since we want to continue
+   * processing and perhaps report other errors.
+   */
+  @FormatMethod
+  private void reportError(Element e, String msg, Object... msgParams) {
+    String formattedMessage = String.format(msg, msgParams);
+    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, formattedMessage, e);
+  }
+
+  /**
+   * Issue a compilation error and return an exception that, when thrown, will cause the processing
+   * of this class to be abandoned. This does not prevent the processing of other classes.
+   */
+  @FormatMethod
+  private AbortProcessingException abortWithError(Element e, String msg, Object... msgParams) {
+    reportError(e, msg, msgParams);
+    return new AbortProcessingException();
+  }
+
+  private Elements elementUtils;
+  private Types typeUtils;
+
+  @Override
+  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    elementUtils = processingEnv.getElementUtils();
+    typeUtils = processingEnv.getTypeUtils();
+    boolean claimed =
+        (annotations.size() == 1
+            && annotations
+                .iterator()
+                .next()
+                .getQualifiedName()
+                .contentEquals(AUTO_ANNOTATION_NAME));
+    if (claimed) {
+      process(roundEnv);
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  private void process(RoundEnvironment roundEnv) {
+    TypeElement autoAnnotation = elementUtils.getTypeElement(AUTO_ANNOTATION_NAME);
+    Collection<? extends Element> annotatedElements =
+        roundEnv.getElementsAnnotatedWith(autoAnnotation);
+    List<ExecutableElement> methods = ElementFilter.methodsIn(annotatedElements);
+    if (!SuperficialValidation.validateElements(methods) || methodsAreOverloaded(methods)) {
+      return;
+    }
+    for (ExecutableElement method : methods) {
+      try {
+        processMethod(method);
+      } catch (AbortProcessingException e) {
+        // We abandoned this type, but continue with the next.
+      } catch (RuntimeException e) {
+        String trace = Throwables.getStackTraceAsString(e);
+        reportError(method, "@AutoAnnotation processor threw an exception: %s", trace);
+        throw e;
+      }
+    }
+  }
+
+  private void processMethod(ExecutableElement method) {
+    if (!method.getModifiers().contains(Modifier.STATIC)) {
+      throw abortWithError(method, "@AutoAnnotation method must be static");
+    }
+
+    TypeElement annotationElement = getAnnotationReturnType(method);
+
+    Set<Class<?>> wrapperTypesUsedInCollections = wrapperTypesUsedInCollections(method);
+
+    ImmutableMap<String, ExecutableElement> memberMethods = getMemberMethods(annotationElement);
+    TypeElement methodClass = (TypeElement) method.getEnclosingElement();
+    String pkg = TypeSimplifier.packageNameOf(methodClass);
+
+    ImmutableMap<String, AnnotationValue> defaultValues = getDefaultValues(annotationElement);
+    ImmutableMap<String, Member> members = getMembers(method, memberMethods);
+    ImmutableMap<String, Parameter> parameters = getParameters(annotationElement, method, members);
+    validateParameters(annotationElement, method, members, parameters, defaultValues);
+
+    String generatedClassName = generatedClassName(method);
+
+    AutoAnnotationTemplateVars vars = new AutoAnnotationTemplateVars();
+    vars.annotationFullName = annotationElement.toString();
+    vars.annotationName = TypeEncoder.encode(annotationElement.asType());
+    vars.className = generatedClassName;
+    vars.generated = getGeneratedTypeName();
+    vars.members = members;
+    vars.params = parameters;
+    vars.pkg = pkg;
+    vars.wrapperTypesUsedInCollections = wrapperTypesUsedInCollections;
+    vars.gwtCompatible = isGwtCompatible(annotationElement);
+    ImmutableMap<String, Integer> invariableHashes = invariableHashes(members, parameters.keySet());
+    vars.invariableHashSum = 0;
+    for (int h : invariableHashes.values()) {
+      vars.invariableHashSum += h;
+    }
+    vars.invariableHashes = invariableHashes.keySet();
+    String text = vars.toText();
+    text = TypeEncoder.decode(text, processingEnv, pkg, annotationElement.asType());
+    text = Reformatter.fixup(text);
+    String fullName = fullyQualifiedName(pkg, generatedClassName);
+    writeSourceFile(fullName, text, methodClass);
+  }
+
+  private String getGeneratedTypeName() {
+    return generatedAnnotation(elementUtils, processingEnv.getSourceVersion())
+        .map(generatedAnnotation -> TypeEncoder.encode(generatedAnnotation.asType()))
+        .orElse("");
+  }
+
+  /**
+   * Returns the hashCode of the given AnnotationValue, if that hashCode is guaranteed to be always
+   * the same. The hashCode of a String or primitive type never changes. The hashCode of a Class or
+   * an enum constant does potentially change in different runs of the same program. The hashCode of
+   * an array doesn't change if the hashCodes of its elements don't. Although we could have a
+   * similar rule for nested annotation values, we currently don't.
+   */
+  private static Optional<Integer> invariableHash(AnnotationValue annotationValue) {
+    Object value = annotationValue.getValue();
+    if (value instanceof String || Primitives.isWrapperType(value.getClass())) {
+      return Optional.of(value.hashCode());
+    } else if (value instanceof List<?>) {
+      @SuppressWarnings("unchecked") // by specification
+      List<? extends AnnotationValue> list = (List<? extends AnnotationValue>) value;
+      return invariableHash(list);
+    } else {
+      return Optional.empty();
+    }
+  }
+
+  private static Optional<Integer> invariableHash(
+      List<? extends AnnotationValue> annotationValues) {
+    int h = 1;
+    for (AnnotationValue annotationValue : annotationValues) {
+      Optional<Integer> maybeHash = invariableHash(annotationValue);
+      if (!maybeHash.isPresent()) {
+        return Optional.empty();
+      }
+      h = h * 31 + maybeHash.get();
+    }
+    return Optional.of(h);
+  }
+
+  /**
+   * Returns a map from the names of members with invariable hashCodes to the values of those
+   * hashCodes.
+   */
+  private static ImmutableMap<String, Integer> invariableHashes(
+      ImmutableMap<String, Member> members, ImmutableSet<String> parameters) {
+    ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
+    for (String element : members.keySet()) {
+      if (!parameters.contains(element)) {
+        Member member = members.get(element);
+        AnnotationValue annotationValue = member.method.getDefaultValue();
+        Optional<Integer> invariableHash = invariableHash(annotationValue);
+        if (invariableHash.isPresent()) {
+          builder.put(element, (element.hashCode() * 127) ^ invariableHash.get());
+        }
+      }
+    }
+    return builder.build();
+  }
+
+  private boolean methodsAreOverloaded(List<ExecutableElement> methods) {
+    boolean overloaded = false;
+    Set<String> classNames = new HashSet<String>();
+    for (ExecutableElement method : methods) {
+      String qualifiedClassName =
+          fullyQualifiedName(
+              MoreElements.getPackage(method).getQualifiedName().toString(),
+              generatedClassName(method));
+      if (!classNames.add(qualifiedClassName)) {
+        overloaded = true;
+        reportError(method, "@AutoAnnotation methods cannot be overloaded");
+      }
+    }
+    return overloaded;
+  }
+
+  private String generatedClassName(ExecutableElement method) {
+    TypeElement type = (TypeElement) method.getEnclosingElement();
+    String name = type.getSimpleName().toString();
+    while (type.getEnclosingElement() instanceof TypeElement) {
+      type = (TypeElement) type.getEnclosingElement();
+      name = type.getSimpleName() + "_" + name;
+    }
+    return "AutoAnnotation_" + name + "_" + method.getSimpleName();
+  }
+
+  private TypeElement getAnnotationReturnType(ExecutableElement method) {
+    TypeMirror returnTypeMirror = method.getReturnType();
+    if (returnTypeMirror.getKind() == TypeKind.DECLARED) {
+      Element returnTypeElement = typeUtils.asElement(method.getReturnType());
+      if (returnTypeElement.getKind() == ElementKind.ANNOTATION_TYPE) {
+        return (TypeElement) returnTypeElement;
+      }
+    }
+    throw abortWithError(
+        method,
+        "Return type of @AutoAnnotation method must be an annotation type, not %s",
+        returnTypeMirror);
+  }
+
+  private ImmutableMap<String, ExecutableElement> getMemberMethods(TypeElement annotationElement) {
+    ImmutableMap.Builder<String, ExecutableElement> members = ImmutableMap.builder();
+    for (ExecutableElement member :
+        ElementFilter.methodsIn(annotationElement.getEnclosedElements())) {
+      String name = member.getSimpleName().toString();
+      members.put(name, member);
+    }
+    return members.build();
+  }
+
+  private ImmutableMap<String, Member> getMembers(
+      Element context, ImmutableMap<String, ExecutableElement> memberMethods) {
+    ImmutableMap.Builder<String, Member> members = ImmutableMap.builder();
+    for (Map.Entry<String, ExecutableElement> entry : memberMethods.entrySet()) {
+      ExecutableElement memberMethod = entry.getValue();
+      String name = memberMethod.getSimpleName().toString();
+      members.put(name, new Member(processingEnv, context, memberMethod));
+    }
+    return members.build();
+  }
+
+  private ImmutableMap<String, AnnotationValue> getDefaultValues(TypeElement annotationElement) {
+    ImmutableMap.Builder<String, AnnotationValue> defaultValues = ImmutableMap.builder();
+    for (ExecutableElement member :
+        ElementFilter.methodsIn(annotationElement.getEnclosedElements())) {
+      String name = member.getSimpleName().toString();
+      AnnotationValue defaultValue = member.getDefaultValue();
+      if (defaultValue != null) {
+        defaultValues.put(name, defaultValue);
+      }
+    }
+    return defaultValues.build();
+  }
+
+  private ImmutableMap<String, Parameter> getParameters(
+      TypeElement annotationElement, ExecutableElement method, Map<String, Member> members) {
+    ImmutableMap.Builder<String, Parameter> parameters = ImmutableMap.builder();
+    boolean error = false;
+    for (VariableElement parameter : method.getParameters()) {
+      String name = parameter.getSimpleName().toString();
+      Member member = members.get(name);
+      if (member == null) {
+        reportError(
+            parameter,
+            "@AutoAnnotation method parameter '%s' must have the same name as a member of %s",
+            name,
+            annotationElement);
+        error = true;
+      } else {
+        TypeMirror parameterType = parameter.asType();
+        TypeMirror memberType = member.getTypeMirror();
+        if (compatibleTypes(parameterType, memberType)) {
+          parameters.put(name, new Parameter(parameterType));
+        } else {
+          reportError(
+              parameter,
+              "@AutoAnnotation method parameter '%s' has type %s but %s.%s has type %s",
+              name,
+              parameterType,
+              annotationElement,
+              name,
+              memberType);
+          error = true;
+        }
+      }
+    }
+    if (error) {
+      throw new AbortProcessingException();
+    }
+    return parameters.build();
+  }
+
+  private void validateParameters(
+      TypeElement annotationElement,
+      ExecutableElement method,
+      ImmutableMap<String, Member> members,
+      ImmutableMap<String, Parameter> parameters,
+      ImmutableMap<String, AnnotationValue> defaultValues) {
+    boolean error = false;
+    for (String memberName : members.keySet()) {
+      if (!parameters.containsKey(memberName) && !defaultValues.containsKey(memberName)) {
+        reportError(
+            method,
+            "@AutoAnnotation method needs a parameter with name '%s' and type %s"
+                + " corresponding to %s.%s, which has no default value",
+            memberName,
+            members.get(memberName).getType(),
+            annotationElement,
+            memberName);
+        error = true;
+      }
+    }
+    if (error) {
+      throw new AbortProcessingException();
+    }
+  }
+
+  /**
+   * Returns true if {@code parameterType} can be used to provide the value of an annotation member
+   * of type {@code memberType}. They must either be the same type, or the member type must be an
+   * array and the parameter type must be a collection of a compatible type.
+   */
+  private boolean compatibleTypes(TypeMirror parameterType, TypeMirror memberType) {
+    if (typeUtils.isAssignable(parameterType, memberType)) {
+      // parameterType assignable to memberType, which in the restricted world of annotations
+      // means they are the same type, or maybe memberType is an annotation type and parameterType
+      // is a subtype of that annotation interface (why would you do that?).
+      return true;
+    }
+    // They're not the same, but we could still consider them compatible if for example
+    // parameterType is List<Integer> and memberType is int[]. We accept any type that is assignable
+    // to Collection<Integer> (in this example).
+    if (memberType.getKind() != TypeKind.ARRAY) {
+      return false;
+    }
+    TypeMirror arrayElementType = ((ArrayType) memberType).getComponentType();
+    TypeMirror wrappedArrayElementType =
+        arrayElementType.getKind().isPrimitive()
+            ? typeUtils.boxedClass((PrimitiveType) arrayElementType).asType()
+            : arrayElementType;
+    TypeElement javaUtilCollection =
+        elementUtils.getTypeElement(Collection.class.getCanonicalName());
+    DeclaredType collectionOfElement =
+        typeUtils.getDeclaredType(javaUtilCollection, wrappedArrayElementType);
+    return typeUtils.isAssignable(parameterType, collectionOfElement);
+  }
+
+  /**
+   * Returns the wrapper types ({@code Integer.class} etc) that are used in collection parameters
+   * like {@code List<Integer>}. This is needed because we will emit a helper method for each such
+   * type, for example to convert {@code Collection<Integer>} into {@code int[]}.
+   */
+  private Set<Class<?>> wrapperTypesUsedInCollections(ExecutableElement method) {
+    TypeElement javaUtilCollection = elementUtils.getTypeElement(Collection.class.getName());
+    ImmutableSet.Builder<Class<?>> usedInCollections = ImmutableSet.builder();
+    for (Class<?> wrapper : Primitives.allWrapperTypes()) {
+      DeclaredType collectionOfWrapper =
+          typeUtils.getDeclaredType(javaUtilCollection, getTypeMirror(wrapper));
+      for (VariableElement parameter : method.getParameters()) {
+        if (typeUtils.isAssignable(parameter.asType(), collectionOfWrapper)) {
+          usedInCollections.add(wrapper);
+          break;
+        }
+      }
+    }
+    return usedInCollections.build();
+  }
+
+  private TypeMirror getTypeMirror(Class<?> c) {
+    return elementUtils.getTypeElement(c.getName()).asType();
+  }
+
+  private static boolean isGwtCompatible(TypeElement annotationElement) {
+    return annotationElement
+        .getAnnotationMirrors()
+        .stream()
+        .map(mirror -> mirror.getAnnotationType().asElement())
+        .anyMatch(element -> element.getSimpleName().contentEquals("GwtCompatible"));
+  }
+
+  private static String fullyQualifiedName(String pkg, String cls) {
+    return pkg.isEmpty() ? cls : pkg + "." + cls;
+  }
+
+  private void writeSourceFile(String className, String text, TypeElement originatingType) {
+    try {
+      JavaFileObject sourceFile =
+          processingEnv.getFiler().createSourceFile(className, originatingType);
+      try (Writer writer = sourceFile.openWriter()) {
+        writer.write(text);
+      }
+    } catch (IOException e) {
+      // This should really be an error, but we make it a warning in the hope of resisting Eclipse
+      // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=367599. If that bug manifests, we may get
+      // invoked more than once for the same file, so ignoring the ability to overwrite it is the
+      // right thing to do. If we are unable to write for some other reason, we should get a compile
+      // error later because user code will have a reference to the code we were supposed to
+      // generate (new AutoValue_Foo() or whatever) and that reference will be undefined.
+      processingEnv
+          .getMessager()
+          .printMessage(
+              Diagnostic.Kind.WARNING, "Could not write generated class " + className + ": " + e);
+    }
+  }
+
+  public static class Member {
+    private final ProcessingEnvironment processingEnv;
+    private final Element context;
+    private final ExecutableElement method;
+
+    Member(ProcessingEnvironment processingEnv, Element context, ExecutableElement method) {
+      this.processingEnv = processingEnv;
+      this.context = context;
+      this.method = method;
+    }
+
+    @Override
+    public String toString() {
+      return method.getSimpleName().toString();
+    }
+
+    public String getType() {
+      return TypeEncoder.encode(getTypeMirror());
+    }
+
+    public String getComponentType() {
+      Preconditions.checkState(getTypeMirror().getKind() == TypeKind.ARRAY);
+      ArrayType arrayType = (ArrayType) getTypeMirror();
+      return TypeEncoder.encode(arrayType.getComponentType());
+    }
+
+    public TypeMirror getTypeMirror() {
+      return method.getReturnType();
+    }
+
+    public TypeKind getKind() {
+      return getTypeMirror().getKind();
+    }
+
+    // Used as part of the hashCode() computation.
+    // See https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Annotation.html#hashCode--
+    public int getNameHash() {
+      return 127 * toString().hashCode();
+    }
+
+    public boolean isArrayOfClassWithBounds() {
+      if (getTypeMirror().getKind() != TypeKind.ARRAY) {
+        return false;
+      }
+      TypeMirror componentType = ((ArrayType) getTypeMirror()).getComponentType();
+      if (componentType.getKind() != TypeKind.DECLARED) {
+        return false;
+      }
+      DeclaredType declared = (DeclaredType) componentType;
+      if (!((TypeElement) processingEnv.getTypeUtils().asElement(componentType))
+          .getQualifiedName()
+          .contentEquals("java.lang.Class")) {
+        return false;
+      }
+      if (declared.getTypeArguments().size() != 1) {
+        return false;
+      }
+      TypeMirror parameter = declared.getTypeArguments().get(0);
+      if (parameter.getKind() != TypeKind.WILDCARD) {
+        return true; // for Class<Foo>
+      }
+      WildcardType wildcard = (WildcardType) parameter;
+      // In theory, we should check if getExtendsBound() != Object, since '?' is equivalent to
+      // '? extends Object', but, experimentally, neither javac or ecj will sets getExtendsBound()
+      // to 'Object', so there isn't a point in checking.
+      return wildcard.getSuperBound() != null || wildcard.getExtendsBound() != null;
+    }
+
+    public String getDefaultValue() {
+      AnnotationValue defaultValue = method.getDefaultValue();
+      if (defaultValue == null) {
+        return null;
+      } else {
+        return AnnotationOutput.sourceFormForInitializer(
+            defaultValue, processingEnv, method.getSimpleName().toString(), context);
+      }
+    }
+  }
+
+  public static class Parameter {
+    private final String typeName;
+    private final TypeKind kind;
+
+    Parameter(TypeMirror type) {
+      this.typeName = TypeEncoder.encode(type);
+      this.kind = type.getKind();
+    }
+
+    public String getType() {
+      return typeName;
+    }
+
+    public TypeKind getKind() {
+      return kind;
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/AutoAnnotationTemplateVars.java b/value/src/main/java/com/google/auto/value/processor/AutoAnnotationTemplateVars.java
new file mode 100644
index 0000000..4db59c7
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AutoAnnotationTemplateVars.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.escapevelocity.Template;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The variables to substitute into the autoannotation.vm template.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@SuppressWarnings("unused") // the fields in this class are only read via reflection
+class AutoAnnotationTemplateVars extends TemplateVars {
+  /** The members of the annotation being implemented. */
+  Map<String, AutoAnnotationProcessor.Member> members;
+
+  /**
+   * The parameters in the {@code @AutoAnnotation} method, which are also the constructor parameters
+   * in the generated class.
+   */
+  Map<String, AutoAnnotationProcessor.Parameter> params;
+
+  /** The encoded form of the {@code Generated} class, or empty if it is not available. */
+  String generated;
+
+  /**
+   * The package of the class containing the {@code @AutoAnnotation} annotation, which is also the
+   * package where the annotation implementation will be generated.
+   */
+  String pkg;
+
+  /** The simple name of the generated class, like {@code AutoAnnotation_Foo_bar}. */
+  String className;
+
+  /** The name of the annotation interface as it can be referenced in the generated code. */
+  String annotationName;
+
+  /** The fully-qualified name of the annotation interface. */
+  String annotationFullName;
+
+  /**
+   * The wrapper types (like {@code Integer.class}) that are referenced in collection parameters
+   * (like {@code List<Integer>}).
+   */
+  Set<Class<?>> wrapperTypesUsedInCollections;
+
+  /**
+   * True if this annotation is marked {@code @GwtCompatible}. That means that we can't use {@code
+   * clone()} to make a copy of an array.
+   */
+  Boolean gwtCompatible;
+
+  /**
+   * The names of members that are defaulted (not mentioned) in this {@code @AutoAnnotation}, and
+   * whose hash codes are invariable.
+   */
+  Set<String> invariableHashes;
+
+  /** The sum of the hash code contributions from the members in {@link #invariableHashes}. */
+  Integer invariableHashSum;
+
+  private static final Template TEMPLATE = parsedTemplateForResource("autoannotation.vm");
+
+  @Override
+  Template parsedTemplate() {
+    return TEMPLATE;
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/AutoOneOfProcessor.java b/value/src/main/java/com/google/auto/value/processor/AutoOneOfProcessor.java
new file mode 100644
index 0000000..d05ed43
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AutoOneOfProcessor.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;
+import static com.google.auto.value.processor.ClassNames.AUTO_ONE_OF_NAME;
+import static java.util.stream.Collectors.toMap;
+import static java.util.stream.Collectors.toSet;
+
+import com.google.auto.common.AnnotationMirrors;
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.service.AutoService;
+import com.google.auto.value.processor.MissingTypes.MissingTypeException;
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;
+
+/**
+ * Javac annotation processor (compiler plugin) for {@linkplain com.google.auto.value.AutoOneOf
+ * one-of} types; user code never references this class.
+ *
+ * @author Éamonn McManus
+ * @see <a href="https://github.com/google/auto/tree/master/value">AutoValue User's Guide</a>
+ */
+@AutoService(Processor.class)
+@SupportedAnnotationTypes(AUTO_ONE_OF_NAME)
+@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)
+public class AutoOneOfProcessor extends AutoValueOrOneOfProcessor {
+  public AutoOneOfProcessor() {
+    super(AUTO_ONE_OF_NAME);
+  }
+
+  @Override
+  boolean propertiesCanBeVoid() {
+    return true;
+  }
+
+  @Override
+  void processType(TypeElement autoOneOfType) {
+    if (autoOneOfType.getKind() != ElementKind.CLASS) {
+      errorReporter()
+          .abortWithError(autoOneOfType, "@" + AUTO_ONE_OF_NAME + " only applies to classes");
+    }
+    checkModifiersIfNested(autoOneOfType);
+    DeclaredType kindMirror = mirrorForKindType(autoOneOfType);
+
+    // We are going to classify the methods of the @AutoOneOf class into several categories.
+    // This covers the methods in the class itself and the ones it inherits from supertypes.
+    // First, the only concrete (non-abstract) methods we are interested in are overrides of
+    // Object methods (equals, hashCode, toString), which signal that we should not generate
+    // an implementation of those methods.
+    // Then, each abstract method is one of the following:
+    // (1) A property getter, like "abstract String foo()" or "abstract String getFoo()".
+    // (2) A kind getter, which is a method that returns the enum in @AutoOneOf. For
+    //     example if we have @AutoOneOf(PetKind.class), this would be a method that returns
+    //     PetKind.
+    // If there are abstract methods that don't fit any of the categories above, that is an error
+    // which we signal explicitly to avoid confusion.
+
+    ImmutableSet<ExecutableElement> methods =
+        getLocalAndInheritedMethods(
+            autoOneOfType, processingEnv.getTypeUtils(), processingEnv.getElementUtils());
+    ImmutableSet<ExecutableElement> abstractMethods = abstractMethodsIn(methods);
+    ExecutableElement kindGetter =
+        findKindGetterOrAbort(autoOneOfType, kindMirror, abstractMethods);
+    Set<ExecutableElement> otherMethods = new LinkedHashSet<>(abstractMethods);
+    otherMethods.remove(kindGetter);
+
+    ImmutableMap<ExecutableElement, TypeMirror> propertyMethodsAndTypes =
+        propertyMethodsIn(otherMethods, autoOneOfType);
+    ImmutableBiMap<String, ExecutableElement> properties =
+        propertyNameToMethodMap(propertyMethodsAndTypes.keySet());
+    validateMethods(autoOneOfType, abstractMethods, propertyMethodsAndTypes.keySet(), kindGetter);
+    ImmutableMap<String, String> propertyToKind =
+        propertyToKindMap(kindMirror, properties.keySet());
+
+    String subclass = generatedClassName(autoOneOfType, "AutoOneOf_");
+    AutoOneOfTemplateVars vars = new AutoOneOfTemplateVars();
+    vars.generatedClass = TypeSimplifier.simpleNameOf(subclass);
+    vars.propertyToKind = propertyToKind;
+    defineSharedVarsForType(autoOneOfType, methods, vars);
+    defineVarsForType(autoOneOfType, vars, propertyMethodsAndTypes, kindGetter);
+
+    String text = vars.toText();
+    text = TypeEncoder.decode(text, processingEnv, vars.pkg, autoOneOfType.asType());
+    text = Reformatter.fixup(text);
+    writeSourceFile(subclass, text, autoOneOfType);
+  }
+
+  private DeclaredType mirrorForKindType(TypeElement autoOneOfType) {
+    Optional<AnnotationMirror> oneOfAnnotation =
+        getAnnotationMirror(autoOneOfType, AUTO_ONE_OF_NAME);
+    if (!oneOfAnnotation.isPresent()) {
+      // This shouldn't happen unless the compilation environment is buggy,
+      // but it has happened in the past and can crash the compiler.
+      errorReporter()
+          .abortWithError(
+              autoOneOfType,
+              "annotation processor for @AutoOneOf was invoked with a type"
+                  + " that does not have that annotation; this is probably a compiler bug");
+    }
+    AnnotationValue kindValue =
+        AnnotationMirrors.getAnnotationValue(oneOfAnnotation.get(), "value");
+    Object value = kindValue.getValue();
+    if (value instanceof TypeMirror) {
+      TypeMirror kindType = (TypeMirror) value;
+      switch (kindType.getKind()) {
+        case DECLARED:
+          return MoreTypes.asDeclared(kindType);
+        case ERROR:
+          throw new MissingTypeException(MoreTypes.asError(kindType));
+        default:
+          break;
+      }
+    }
+    throw new MissingTypeException(null);
+  }
+
+  private ImmutableMap<String, String> propertyToKindMap(
+      DeclaredType kindMirror, ImmutableSet<String> propertyNames) {
+    // We require a one-to-one correspondence between the property names and the enum constants.
+    // We must have transformName(propertyName) = transformName(constantName) for each one.
+    // So we build two maps, transformName(propertyName) → propertyName and
+    // transformName(constantName) → constant. The key sets of the two maps must match, and we
+    // can then join them to make propertyName → constantName.
+    TypeElement kindElement = MoreElements.asType(kindMirror.asElement());
+    Map<String, String> transformedPropertyNames =
+        propertyNames.stream().collect(toMap(this::transformName, s -> s));
+    Map<String, Element> transformedEnumConstants =
+        kindElement
+            .getEnclosedElements()
+            .stream()
+            .filter(e -> e.getKind().equals(ElementKind.ENUM_CONSTANT))
+            .collect(toMap(e -> transformName(e.getSimpleName().toString()), e -> e));
+
+    if (transformedPropertyNames.keySet().equals(transformedEnumConstants.keySet())) {
+      ImmutableMap.Builder<String, String> mapBuilder = ImmutableMap.builder();
+      for (String transformed : transformedPropertyNames.keySet()) {
+        mapBuilder.put(
+            transformedPropertyNames.get(transformed),
+            transformedEnumConstants.get(transformed).getSimpleName().toString());
+      }
+      return mapBuilder.build();
+    }
+
+    // The names don't match. Emit errors for the differences.
+    // Properties that have no enum constant
+    transformedPropertyNames.forEach(
+        (transformed, property) -> {
+          if (!transformedEnumConstants.containsKey(transformed)) {
+            errorReporter()
+                .reportError(
+                    kindElement,
+                    "Enum has no constant with name corresponding to property '%s'",
+                    property);
+          }
+        });
+    // Enum constants that have no property
+    transformedEnumConstants.forEach(
+        (transformed, constant) -> {
+          if (!transformedPropertyNames.containsKey(transformed)) {
+            errorReporter()
+                .reportError(
+                    constant,
+                    "Name of enum constant '%s' does not correspond to any property name",
+                    constant.getSimpleName());
+          }
+        });
+    throw new AbortProcessingException();
+  }
+
+  private String transformName(String s) {
+    return s.toLowerCase(Locale.ROOT).replace("_", "");
+  }
+
+  private ExecutableElement findKindGetterOrAbort(
+      TypeElement autoOneOfType,
+      TypeMirror kindMirror,
+      ImmutableSet<ExecutableElement> abstractMethods) {
+    Set<ExecutableElement> kindGetters =
+        abstractMethods
+            .stream()
+            .filter(e -> sameType(kindMirror, e.getReturnType()))
+            .filter(e -> e.getParameters().isEmpty())
+            .collect(toSet());
+    switch (kindGetters.size()) {
+      case 0:
+        errorReporter()
+            .reportError(
+                autoOneOfType,
+                "%s must have a no-arg abstract method returning %s",
+                autoOneOfType,
+                kindMirror);
+        break;
+      case 1:
+        return Iterables.getOnlyElement(kindGetters);
+      default:
+        for (ExecutableElement getter : kindGetters) {
+          errorReporter()
+              .reportError(getter, "More than one abstract method returns %s", kindMirror);
+        }
+    }
+    throw new AbortProcessingException();
+  }
+
+  private void validateMethods(
+      TypeElement type,
+      ImmutableSet<ExecutableElement> abstractMethods,
+      ImmutableSet<ExecutableElement> propertyMethods,
+      ExecutableElement kindGetter) {
+    for (ExecutableElement method : abstractMethods) {
+      if (propertyMethods.contains(method)) {
+        checkReturnType(type, method);
+      } else if (!method.equals(kindGetter)
+          && objectMethodToOverride(method) == ObjectMethod.NONE) {
+        // This could reasonably be an error, were it not for an Eclipse bug in
+        // ElementUtils.override that sometimes fails to recognize that one method overrides
+        // another, and therefore leaves us with both an abstract method and the subclass method
+        // that overrides it. This shows up in AutoValueTest.LukesBase for example.
+        // The compilation will fail anyway because the generated concrete classes won't
+        // implement this alien method.
+        errorReporter()
+            .reportWarning(
+                method, "Abstract methods in @AutoOneOf classes must have no parameters");
+      }
+    }
+    errorReporter().abortIfAnyError();
+  }
+
+  private void defineVarsForType(
+      TypeElement type,
+      AutoOneOfTemplateVars vars,
+      ImmutableMap<ExecutableElement, TypeMirror> propertyMethodsAndTypes,
+      ExecutableElement kindGetter) {
+    vars.props = propertySet(
+        propertyMethodsAndTypes, ImmutableListMultimap.of(), ImmutableListMultimap.of());
+    vars.kindGetter = kindGetter.getSimpleName().toString();
+    vars.kindType = TypeEncoder.encode(kindGetter.getReturnType());
+    TypeElement javaIoSerializable = elementUtils().getTypeElement("java.io.Serializable");
+    vars.serializable =
+        javaIoSerializable != null  // just in case
+        && typeUtils().isAssignable(type.asType(), javaIoSerializable.asType());
+  }
+
+  @Override
+  Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod) {
+    if (nullableAnnotationFor(propertyMethod, propertyMethod.getReturnType()).isPresent()) {
+      errorReporter().reportError(propertyMethod, "@AutoOneOf properties cannot be @Nullable");
+    }
+    return Optional.empty();
+  }
+
+  private static boolean sameType(TypeMirror t1, TypeMirror t2) {
+    return MoreTypes.equivalence().equivalent(t1, t2);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/AutoOneOfTemplateVars.java b/value/src/main/java/com/google/auto/value/processor/AutoOneOfTemplateVars.java
new file mode 100644
index 0000000..1e15771
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AutoOneOfTemplateVars.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.escapevelocity.Template;
+import java.util.Map;
+
+/**
+ * The variables to substitute into the autooneof.vm template.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@SuppressWarnings("unused") // the fields in this class are only read via reflection
+class AutoOneOfTemplateVars extends AutoValueOrOneOfTemplateVars {
+  /**
+   * The properties defined by the parent class's abstract methods. The elements of this set are in
+   * the same order as the original abstract method declarations in the AutoOneOf class.
+   */
+  ImmutableSet<AutoOneOfProcessor.Property> props;
+
+  /** The simple name of the generated class. */
+  String generatedClass;
+
+  /** The encoded name of the "kind" enum class. */
+  String kindType;
+
+  /** The name of the method that gets the kind of the current {@code @AutoOneOf} instance. */
+  String kindGetter;
+
+  /** Maps property names like {@code dog} to enum constants like {@code DOG}. */
+  Map<String, String> propertyToKind;
+
+  /** True if this {@code @AutoOneOf} class is Serializable. */
+  Boolean serializable;
+
+  private static final Template TEMPLATE = parsedTemplateForResource("autooneof.vm");
+
+  @Override
+  Template parsedTemplate() {
+    return TEMPLATE;
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/AutoValueBuilderProcessor.java b/value/src/main/java/com/google/auto/value/processor/AutoValueBuilderProcessor.java
new file mode 100644
index 0000000..62dfeb3
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AutoValueBuilderProcessor.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.auto.value.processor.AutoValueOrOneOfProcessor.hasAnnotationMirror;
+import static com.google.auto.value.processor.ClassNames.AUTO_VALUE_BUILDER_NAME;
+import static com.google.auto.value.processor.ClassNames.AUTO_VALUE_NAME;
+
+import com.google.auto.common.SuperficialValidation;
+import com.google.auto.service.AutoService;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;
+
+/**
+ * Annotation processor that checks that the type that {@code AutoValue.Builder} is applied to is
+ * nested inside an {@code @AutoValue} class. The actual code generation for builders is done in
+ * {@link AutoValueProcessor}.
+ *
+ * @author Éamonn McManus
+ */
+@AutoService(Processor.class)
+@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.ISOLATING)
+@SupportedAnnotationTypes(AUTO_VALUE_BUILDER_NAME)
+public class AutoValueBuilderProcessor extends AbstractProcessor {
+  @Override
+  public SourceVersion getSupportedSourceVersion() {
+    return SourceVersion.latest();
+  }
+
+  @Override
+  public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    TypeElement autoValueBuilder =
+        processingEnv.getElementUtils().getTypeElement(AUTO_VALUE_BUILDER_NAME);
+    Set<? extends Element> builderTypes = roundEnv.getElementsAnnotatedWith(autoValueBuilder);
+    if (!SuperficialValidation.validateElements(builderTypes)) {
+      return false;
+    }
+    for (Element annotatedType : builderTypes) {
+      // Double-check that the annotation is there. Sometimes the compiler gets confused in case of
+      // erroneous source code. SuperficialValidation should protect us against this but it doesn't
+      // cost anything to check again.
+      if (hasAnnotationMirror(annotatedType, AUTO_VALUE_BUILDER_NAME)) {
+        validate(
+            annotatedType,
+            "@AutoValue.Builder can only be applied to a class or interface inside an"
+                + " @AutoValue class");
+      }
+    }
+    return false;
+  }
+
+  private void validate(Element annotatedType, String errorMessage) {
+    Element container = annotatedType.getEnclosingElement();
+    if (!hasAnnotationMirror(container, AUTO_VALUE_NAME)) {
+      processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, errorMessage, annotatedType);
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/AutoValueOrOneOfProcessor.java b/value/src/main/java/com/google/auto/value/processor/AutoValueOrOneOfProcessor.java
new file mode 100644
index 0000000..4214c12
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AutoValueOrOneOfProcessor.java
@@ -0,0 +1,1108 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
+import static com.google.auto.common.GeneratedAnnotations.generatedAnnotation;
+import static com.google.auto.common.MoreElements.getPackage;
+import static com.google.auto.common.MoreElements.isAnnotationPresent;
+import static com.google.auto.value.processor.ClassNames.AUTO_VALUE_PACKAGE_NAME;
+import static com.google.auto.value.processor.ClassNames.COPY_ANNOTATIONS_NAME;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static com.google.common.collect.Sets.union;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toCollection;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.common.Visibility;
+import com.google.auto.value.processor.MissingTypes.MissingTypeException;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.Writer;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.OptionalInt;
+import java.util.Set;
+import java.util.function.Predicate;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.QualifiedNameable;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleAnnotationValueVisitor8;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+/**
+ * Shared code between AutoValueProcessor and AutoOneOfProcessor.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+abstract class AutoValueOrOneOfProcessor extends AbstractProcessor {
+  private final String annotationClassName;
+
+  /**
+   * Qualified names of {@code @AutoValue} or {@code AutoOneOf} classes that we attempted to process
+   * but had to abandon because we needed other types that they referenced and those other types
+   * were missing.
+   */
+  private final List<String> deferredTypeNames = new ArrayList<>();
+
+  AutoValueOrOneOfProcessor(String annotationClassName) {
+    this.annotationClassName = annotationClassName;
+  }
+
+  /** The annotation we are processing, {@code AutoValue} or {@code AutoOneOf}. */
+  private TypeElement annotationType;
+  /** The simple name of {@link #annotationType}. */
+  private String simpleAnnotationName;
+
+  private ErrorReporter errorReporter;
+
+  @Override
+  public synchronized void init(ProcessingEnvironment processingEnv) {
+    super.init(processingEnv);
+    errorReporter = new ErrorReporter(processingEnv);
+  }
+
+  final ErrorReporter errorReporter() {
+    return errorReporter;
+  }
+
+  final Types typeUtils() {
+    return processingEnv.getTypeUtils();
+  }
+
+  final Elements elementUtils() {
+    return processingEnv.getElementUtils();
+  }
+
+  /**
+   * Qualified names of {@code @AutoValue} or {@code AutoOneOf} classes that we attempted to process
+   * but had to abandon because we needed other types that they referenced and those other types
+   * were missing. This is used by tests.
+   */
+  final ImmutableList<String> deferredTypeNames() {
+    return ImmutableList.copyOf(deferredTypeNames);
+  }
+
+  @Override
+  public final SourceVersion getSupportedSourceVersion() {
+    return SourceVersion.latestSupported();
+  }
+
+  /**
+   * A property of an {@code @AutoValue} or {@code @AutoOneOf} class, defined by one of its abstract
+   * methods. An instance of this class is made available to the Velocity template engine for each
+   * property. The public methods of this class define JavaBeans-style properties that are
+   * accessible from templates. For example {@link #getType()} means we can write {@code $p.type}
+   * for a Velocity variable {@code $p} that is a {@code Property}.
+   */
+  public static class Property {
+    private final String name;
+    private final String identifier;
+    private final ExecutableElement method;
+    private final String type;
+    private final ImmutableList<String> fieldAnnotations;
+    private final ImmutableList<String> methodAnnotations;
+    private final Optional<String> nullableAnnotation;
+    private final Optionalish optional;
+
+    Property(
+        String name,
+        String identifier,
+        ExecutableElement method,
+        String type,
+        ImmutableList<String> fieldAnnotations,
+        ImmutableList<String> methodAnnotations,
+        Optional<String> nullableAnnotation) {
+      this.name = name;
+      this.identifier = identifier;
+      this.method = method;
+      this.type = type;
+      this.fieldAnnotations = fieldAnnotations;
+      this.methodAnnotations = methodAnnotations;
+      this.nullableAnnotation = nullableAnnotation;
+      TypeMirror propertyType = method.getReturnType();
+      this.optional = Optionalish.createIfOptional(propertyType);
+    }
+
+    /**
+     * Returns the name of the property as it should be used when declaring identifiers (fields and
+     * parameters). If the original getter method was {@code foo()} then this will be {@code foo}.
+     * If it was {@code getFoo()} then it will be {@code foo}. If it was {@code getPackage()} then
+     * it will be something like {@code package0}, since {@code package} is a reserved word.
+     */
+    @Override
+    public String toString() {
+      return identifier;
+    }
+
+    /**
+     * Returns the name of the property as it should be used in strings visible to users. This is
+     * usually the same as {@code toString()}, except that if we had to use an identifier like
+     * "package0" because "package" is a reserved word, the name here will be the original
+     * "package".
+     */
+    public String getName() {
+      return name;
+    }
+
+    /**
+     * Returns the name of the getter method for this property as defined by the {@code @AutoValue}
+     * class. For property {@code foo}, this will be {@code foo} or {@code getFoo} or {@code isFoo}.
+     */
+    public String getGetter() {
+      return method.getSimpleName().toString();
+    }
+
+    public TypeMirror getTypeMirror() {
+      return method.getReturnType();
+    }
+
+    public String getType() {
+      return type;
+    }
+
+    public TypeKind getKind() {
+      return method.getReturnType().getKind();
+    }
+
+    /**
+     * Returns the annotations (in string form) that should be applied to the property's field
+     * declaration.
+     */
+    public List<String> getFieldAnnotations() {
+      return fieldAnnotations;
+    }
+
+    /**
+     * Returns the annotations (in string form) that should be applied to the property's method
+     * implementation.
+     */
+    public List<String> getMethodAnnotations() {
+      return methodAnnotations;
+    }
+
+    /**
+     * Returns an {@link Optionalish} representing the kind of Optional that this property's type
+     * is, or null if the type is not an Optional of any kind.
+     */
+    public Optionalish getOptional() {
+      return optional;
+    }
+
+    /**
+     * Returns the string to use as a method annotation to indicate the nullability of this
+     * property. It is either the empty string, if the property is not nullable, or an annotation
+     * string with a trailing space, such as {@code "@`javax.annotation.Nullable` "}, where the
+     * {@code ``} is the encoding used by {@link TypeEncoder}. If the property is nullable by virtue
+     * of its <i>type</i> rather than its method being {@code @Nullable}, this method returns the
+     * empty string, because the {@code @Nullable} will appear when the type is spelled out. In this
+     * case, {@link #nullableAnnotation} is present but empty.
+     */
+    public final String getNullableAnnotation() {
+      return nullableAnnotation.orElse("");
+    }
+
+    public boolean isNullable() {
+      return nullableAnnotation.isPresent();
+    }
+
+    public String getAccess() {
+      return SimpleMethod.access(method);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      return obj instanceof Property && ((Property) obj).method.equals(method);
+    }
+
+    @Override
+    public int hashCode() {
+      return method.hashCode();
+    }
+  }
+
+  @Override
+  public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+    annotationType = elementUtils().getTypeElement(annotationClassName);
+    if (annotationType == null) {
+      // This should not happen. If the annotation type is not found, how did the processor get
+      // triggered?
+      processingEnv
+          .getMessager()
+          .printMessage(
+              Diagnostic.Kind.ERROR,
+              "Did not process @"
+                  + annotationClassName
+                  + " because the annotation class was not found");
+      return false;
+    }
+    simpleAnnotationName = annotationType.getSimpleName().toString();
+    List<TypeElement> deferredTypes =
+        deferredTypeNames
+            .stream()
+            .map(name -> elementUtils().getTypeElement(name))
+            .collect(toList());
+    if (roundEnv.processingOver()) {
+      // This means that the previous round didn't generate any new sources, so we can't have found
+      // any new instances of @AutoValue; and we can't have any new types that are the reason a type
+      // was in deferredTypes.
+      for (TypeElement type : deferredTypes) {
+        errorReporter.reportError(
+            type,
+            "Did not generate @%s class for %s because it references undefined types",
+            simpleAnnotationName,
+            type.getQualifiedName());
+      }
+      return false;
+    }
+    Collection<? extends Element> annotatedElements =
+        roundEnv.getElementsAnnotatedWith(annotationType);
+    List<TypeElement> types =
+        new ImmutableList.Builder<TypeElement>()
+            .addAll(deferredTypes)
+            .addAll(ElementFilter.typesIn(annotatedElements))
+            .build();
+    deferredTypeNames.clear();
+    for (TypeElement type : types) {
+      try {
+        processType(type);
+      } catch (AbortProcessingException e) {
+        // We abandoned this type; continue with the next.
+      } catch (MissingTypeException e) {
+        // We abandoned this type, but only because we needed another type that it references and
+        // that other type was missing. It is possible that the missing type will be generated by
+        // further annotation processing, so we will try again on the next round (perhaps failing
+        // again and adding it back to the list). We save the name of the @AutoValue type rather
+        // than its TypeElement because it is not guaranteed that it will be represented by
+        // the same TypeElement on the next round.
+        deferredTypeNames.add(type.getQualifiedName().toString());
+      } catch (RuntimeException e) {
+        String trace = Throwables.getStackTraceAsString(e);
+        errorReporter.reportError(
+            type, "@%s processor threw an exception: %s", simpleAnnotationName, trace);
+        throw e;
+      }
+    }
+    return false; // never claim annotation, because who knows what other processors want?
+  }
+
+  /**
+   * Analyzes a single {@code @AutoValue} or {@code @AutoOneOf} class, and outputs the corresponding
+   * implementation class or classes.
+   *
+   * @param type the class with the {@code @AutoValue} or {@code @AutoOneOf} annotation.
+   */
+  abstract void processType(TypeElement type);
+
+  /**
+   * Returns the appropriate {@code @Nullable} annotation to put on the implementation of the given
+   * property method, and indicates whether the property is in fact nullable. The annotation in
+   * question is on the method, not its return type. If instead the return type is
+   * {@code @Nullable}, this method returns {@code Optional.of("")}, to indicate that the property
+   * is nullable but the <i>method</i> isn't. The {@code @Nullable} annotation will instead appear
+   * when the return type of the method is spelled out in the implementation.
+   */
+  abstract Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod);
+
+  /**
+   * Returns the ordered set of {@link Property} definitions for the given {@code @AutoValue} or
+   * {@code AutoOneOf} type.
+   *
+   * @param annotatedPropertyMethods a map from property methods to the method annotations that
+   *     should go on the implementation of those methods. These annotations are method annotations
+   *     specifically. Type annotations do not appear because they are considered part of the return
+   *     type and will appear when that is spelled out. Annotations that are excluded by {@code
+   *     AutoValue.CopyAnnotations} also do not appear here.
+   */
+  final ImmutableSet<Property> propertySet(
+      ImmutableMap<ExecutableElement, TypeMirror> propertyMethodsAndTypes,
+      ImmutableListMultimap<ExecutableElement, AnnotationMirror> annotatedPropertyFields,
+      ImmutableListMultimap<ExecutableElement, AnnotationMirror> annotatedPropertyMethods) {
+    ImmutableBiMap<ExecutableElement, String> methodToPropertyName =
+        propertyNameToMethodMap(propertyMethodsAndTypes.keySet()).inverse();
+    Map<ExecutableElement, String> methodToIdentifier = new LinkedHashMap<>(methodToPropertyName);
+    fixReservedIdentifiers(methodToIdentifier);
+
+    ImmutableSet.Builder<Property> props = ImmutableSet.builder();
+    propertyMethodsAndTypes.forEach(
+        (propertyMethod, returnType) -> {
+          String propertyType = TypeEncoder.encodeWithAnnotations(
+              returnType, getExcludedAnnotationTypes(propertyMethod));
+          String propertyName = methodToPropertyName.get(propertyMethod);
+          String identifier = methodToIdentifier.get(propertyMethod);
+          ImmutableList<String> fieldAnnotations =
+              annotationStrings(annotatedPropertyFields.get(propertyMethod));
+          ImmutableList<AnnotationMirror> methodAnnotationMirrors =
+              annotatedPropertyMethods.get(propertyMethod);
+          ImmutableList<String> methodAnnotations = annotationStrings(methodAnnotationMirrors);
+          Optional<String> nullableAnnotation = nullableAnnotationForMethod(propertyMethod);
+          Property p =
+              new Property(
+                  propertyName,
+                  identifier,
+                  propertyMethod,
+                  propertyType,
+                  fieldAnnotations,
+                  methodAnnotations,
+                  nullableAnnotation);
+          props.add(p);
+          if (p.isNullable() && returnType.getKind().isPrimitive()) {
+            errorReporter().reportError(propertyMethod, "Primitive types cannot be @Nullable");
+          }
+        });
+    return props.build();
+  }
+
+  /** Defines the template variables that are shared by AutoValue and AutoOneOf. */
+  final void defineSharedVarsForType(
+      TypeElement type,
+      ImmutableSet<ExecutableElement> methods,
+      AutoValueOrOneOfTemplateVars vars) {
+    vars.pkg = TypeSimplifier.packageNameOf(type);
+    vars.origClass = TypeSimplifier.classNameOf(type);
+    vars.simpleClassName = TypeSimplifier.simpleNameOf(vars.origClass);
+    vars.generated =
+        generatedAnnotation(elementUtils(), processingEnv.getSourceVersion())
+            .map(annotation -> TypeEncoder.encode(annotation.asType()))
+            .orElse("");
+    vars.formalTypes = TypeEncoder.formalTypeParametersString(type);
+    vars.actualTypes = TypeSimplifier.actualTypeParametersString(type);
+    vars.wildcardTypes = wildcardTypeParametersString(type);
+    vars.annotations = copiedClassAnnotations(type);
+    Map<ObjectMethod, ExecutableElement> methodsToGenerate =
+        determineObjectMethodsToGenerate(methods);
+    vars.toString = methodsToGenerate.containsKey(ObjectMethod.TO_STRING);
+    vars.equals = methodsToGenerate.containsKey(ObjectMethod.EQUALS);
+    vars.hashCode = methodsToGenerate.containsKey(ObjectMethod.HASH_CODE);
+    vars.equalsParameterType = equalsParameterType(methodsToGenerate);
+  }
+
+  /** Returns the spelling to be used in the generated code for the given list of annotations. */
+  static ImmutableList<String> annotationStrings(List<? extends AnnotationMirror> annotations) {
+    // TODO(b/68008628): use ImmutableList.toImmutableList() when that works.
+    return ImmutableList.copyOf(
+        annotations.stream().map(AnnotationOutput::sourceFormForAnnotation).collect(toList()));
+  }
+
+  /**
+   * Returns the name of the generated {@code @AutoValue} or {@code @AutoOneOf} class, for example
+   * {@code AutoOneOf_TaskResult} or {@code $$AutoValue_SimpleMethod}.
+   *
+   * @param type the name of the type bearing the {@code @AutoValue} or {@code @AutoOneOf}
+   *     annotation.
+   * @param prefix the prefix to use in the generated class. This may start with one or more dollar
+   *     signs, for an {@code @AutoValue} implementation where there are AutoValue extensions.
+   */
+  static String generatedClassName(TypeElement type, String prefix) {
+    String name = type.getSimpleName().toString();
+    while (type.getEnclosingElement() instanceof TypeElement) {
+      type = (TypeElement) type.getEnclosingElement();
+      name = type.getSimpleName() + "_" + name;
+    }
+    String pkg = TypeSimplifier.packageNameOf(type);
+    String dot = pkg.isEmpty() ? "" : ".";
+    return pkg + dot + prefix + name;
+  }
+
+  private static boolean isJavaLangObject(TypeElement type) {
+    return type.getSuperclass().getKind() == TypeKind.NONE && type.getKind() == ElementKind.CLASS;
+  }
+
+  enum ObjectMethod {
+    NONE,
+    TO_STRING,
+    EQUALS,
+    HASH_CODE
+  }
+
+  /**
+   * Determines which of the three public non-final methods from {@code java.lang.Object}, if any,
+   * is overridden by the given method.
+   */
+  static ObjectMethod objectMethodToOverride(ExecutableElement method) {
+    String name = method.getSimpleName().toString();
+    switch (method.getParameters().size()) {
+      case 0:
+        if (name.equals("toString")) {
+          return ObjectMethod.TO_STRING;
+        } else if (name.equals("hashCode")) {
+          return ObjectMethod.HASH_CODE;
+        }
+        break;
+      case 1:
+        if (name.equals("equals")) {
+          TypeMirror param = getOnlyElement(method.getParameters()).asType();
+          if (param.getKind().equals(TypeKind.DECLARED)) {
+            TypeElement paramType = MoreTypes.asTypeElement(param);
+            if (paramType.getQualifiedName().contentEquals("java.lang.Object")) {
+              return ObjectMethod.EQUALS;
+            }
+          }
+        }
+        break;
+      default:
+        // No relevant Object methods have more than one parameter.
+    }
+    return ObjectMethod.NONE;
+  }
+
+  /** Returns a bi-map between property names and the corresponding abstract property methods. */
+  final ImmutableBiMap<String, ExecutableElement> propertyNameToMethodMap(
+      Set<ExecutableElement> propertyMethods) {
+    Map<String, ExecutableElement> map = new LinkedHashMap<>();
+    Set<String> reportedDups = new HashSet<>();
+    boolean allPrefixed = gettersAllPrefixed(propertyMethods);
+    for (ExecutableElement method : propertyMethods) {
+      String methodName = method.getSimpleName().toString();
+      String name = allPrefixed ? nameWithoutPrefix(methodName) : methodName;
+      ExecutableElement old = map.put(name, method);
+      if (old != null) {
+        List<ExecutableElement> contexts = new ArrayList<>(Arrays.asList(method));
+        if (reportedDups.add(name)) {
+          contexts.add(old);
+        }
+        // Report the error for both of the methods. If this is a third or further occurrence,
+        // reportedDups prevents us from reporting more than one error for the same method.
+        for (ExecutableElement context : contexts) {
+          errorReporter.reportError(
+              context, "More than one @%s property called %s", simpleAnnotationName, name);
+        }
+      }
+    }
+    return ImmutableBiMap.copyOf(map);
+  }
+
+  private static boolean gettersAllPrefixed(Set<ExecutableElement> methods) {
+    return prefixedGettersIn(methods).size() == methods.size();
+  }
+
+  /**
+   * Returns an appropriate annotation spelling to indicate the nullability of an element. If the
+   * return value is a non-empty Optional, that indicates that the element is nullable, and the
+   * string should be used to annotate it. If the return value is an empty Optional, the element is
+   * not nullable. The return value can be {@code Optional.of("")}, which indicates that the element
+   * is nullable but that the nullability comes from a type annotation. In this case, the annotation
+   * will appear when the type is written, and must not be specified again. If the Optional contains
+   * a present non-empty string then that string will end with a space.
+   *
+   * @param element the element that might be {@code @Nullable}, either a method or a parameter.
+   * @param elementType the relevant type of the element: the return type for a method, or the
+   *     parameter type for a parameter.
+   */
+  static Optional<String> nullableAnnotationFor(Element element, TypeMirror elementType) {
+    List<? extends AnnotationMirror> typeAnnotations = elementType.getAnnotationMirrors();
+    if (nullableAnnotationIndex(typeAnnotations).isPresent()) {
+      return Optional.of("");
+    }
+    List<? extends AnnotationMirror> elementAnnotations = element.getAnnotationMirrors();
+    OptionalInt nullableAnnotationIndex = nullableAnnotationIndex(elementAnnotations);
+    if (nullableAnnotationIndex.isPresent()) {
+      ImmutableList<String> annotations = annotationStrings(elementAnnotations);
+      return Optional.of(annotations.get(nullableAnnotationIndex.getAsInt()) + " ");
+    } else {
+      return Optional.empty();
+    }
+  }
+
+  private static OptionalInt nullableAnnotationIndex(List<? extends AnnotationMirror> annotations) {
+    for (int i = 0; i < annotations.size(); i++) {
+      if (isNullable(annotations.get(i))) {
+        return OptionalInt.of(i);
+      }
+    }
+    return OptionalInt.empty();
+  }
+
+  private static boolean isNullable(AnnotationMirror annotation) {
+    return annotation.getAnnotationType().asElement().getSimpleName().contentEquals("Nullable");
+  }
+
+  /**
+   * Returns the subset of the given zero-arg methods whose names begin with {@code get}. Also
+   * includes {@code isFoo} methods if they return {@code boolean}. This corresponds to JavaBeans
+   * conventions.
+   */
+  static ImmutableSet<ExecutableElement> prefixedGettersIn(Iterable<ExecutableElement> methods) {
+    ImmutableSet.Builder<ExecutableElement> getters = ImmutableSet.builder();
+    for (ExecutableElement method : methods) {
+      String name = method.getSimpleName().toString();
+      // Note that getfoo() (without a capital) is still a getter.
+      boolean get = name.startsWith("get") && !name.equals("get");
+      boolean is =
+          name.startsWith("is")
+              && !name.equals("is")
+              && method.getReturnType().getKind() == TypeKind.BOOLEAN;
+      if (get || is) {
+        getters.add(method);
+      }
+    }
+    return getters.build();
+  }
+
+  /**
+   * Returns the name of the property defined by the given getter. A getter called {@code getFoo()}
+   * or {@code isFoo()} defines a property called {@code foo}. For consistency with JavaBeans, a
+   * getter called {@code getHTMLPage()} defines a property called {@code HTMLPage}. The <a
+   * href="https://docs.oracle.com/javase/8/docs/api/java/beans/Introspector.html#decapitalize-java.lang.String-">
+   * rule</a> is: the name of the property is the part after {@code get} or {@code is}, with the
+   * first letter lowercased <i>unless</i> the first two letters are uppercase. This works well for
+   * the {@code HTMLPage} example, but in these more enlightened times we use {@code HtmlPage}
+   * anyway, so the special behaviour is not useful, and of course it behaves poorly with examples
+   * like {@code OAuth}.
+   */
+  private static String nameWithoutPrefix(String name) {
+    if (name.startsWith("get")) {
+      name = name.substring(3);
+    } else {
+      assert name.startsWith("is");
+      name = name.substring(2);
+    }
+    return PropertyNames.decapitalizeLikeJavaBeans(name);
+  }
+
+  /**
+   * Checks that, if the given {@code @AutoValue} or {@code @AutoOneOf} class is nested, it is
+   * static and not private. This check is not necessary for correctness, since the generated code
+   * would not compile if the check fails, but it produces better error messages for the user.
+   */
+  final void checkModifiersIfNested(TypeElement type) {
+    ElementKind enclosingKind = type.getEnclosingElement().getKind();
+    if (enclosingKind.isClass() || enclosingKind.isInterface()) {
+      if (type.getModifiers().contains(Modifier.PRIVATE)) {
+        errorReporter.abortWithError(
+            type, "@%s class must not be private", simpleAnnotationName);
+      } else if (Visibility.effectiveVisibilityOfElement(type).equals(Visibility.PRIVATE)) {
+        // The previous case, where the class itself is private, is much commoner so it deserves
+        // its own error message, even though it would be caught by the test here too.
+        errorReporter.abortWithError(
+            type, "@%s class must not be nested in a private class", simpleAnnotationName);
+      }
+      if (!type.getModifiers().contains(Modifier.STATIC)) {
+        errorReporter.abortWithError(
+            type, "Nested @%s class must be static", simpleAnnotationName);
+      }
+    }
+    // In principle type.getEnclosingElement() could be an ExecutableElement (for a class
+    // declared inside a method), but since RoundEnvironment.getElementsAnnotatedWith doesn't
+    // return such classes we won't see them here.
+  }
+
+  /**
+   * Modifies the values of the given map to avoid reserved words. If we have a getter called {@code
+   * getPackage()} then we can't use the identifier {@code package} to represent its value since
+   * that's a reserved word.
+   */
+  static void fixReservedIdentifiers(Map<?, String> methodToIdentifier) {
+    for (Map.Entry<?, String> entry : methodToIdentifier.entrySet()) {
+      String name = entry.getValue();
+      if (SourceVersion.isKeyword(name) || !Character.isJavaIdentifierStart(name.codePointAt(0))) {
+        entry.setValue(disambiguate(name, methodToIdentifier.values()));
+      }
+    }
+  }
+
+  private static String disambiguate(String name, Collection<String> existingNames) {
+    if (!Character.isJavaIdentifierStart(name.codePointAt(0))) {
+      // You've defined a getter called get1st(). What were you thinking?
+      name = "_" + name;
+      if (!existingNames.contains(name)) {
+        return name;
+      }
+    }
+    for (int i = 0; ; i++) {
+      String candidate = name + i;
+      if (!existingNames.contains(candidate)) {
+        return candidate;
+      }
+    }
+  }
+
+  /**
+   * Given a list of all methods defined in or inherited by a class, returns a map indicating which
+   * of equals, hashCode, and toString should be generated. Each value in the map is the method that
+   * will be overridden by the generated method, which might be a method in {@code Object} or an
+   * abstract method in the {@code @AutoValue} class or an ancestor.
+   */
+  private static Map<ObjectMethod, ExecutableElement> determineObjectMethodsToGenerate(
+      Set<ExecutableElement> methods) {
+    Map<ObjectMethod, ExecutableElement> methodsToGenerate = new EnumMap<>(ObjectMethod.class);
+    for (ExecutableElement method : methods) {
+      ObjectMethod override = objectMethodToOverride(method);
+      boolean canGenerate =
+          method.getModifiers().contains(Modifier.ABSTRACT)
+              || isJavaLangObject((TypeElement) method.getEnclosingElement());
+      if (!override.equals(ObjectMethod.NONE) && canGenerate) {
+        methodsToGenerate.put(override, method);
+      }
+    }
+    return methodsToGenerate;
+  }
+
+  /**
+   * Returns the encoded parameter type of the {@code equals(Object)} method that is to be
+   * generated, or an empty string if the method is not being generated. The parameter type includes
+   * any type annotations, for example {@code @Nullable}.
+   */
+  static String equalsParameterType(Map<ObjectMethod, ExecutableElement> methodsToGenerate) {
+    ExecutableElement equals = methodsToGenerate.get(ObjectMethod.EQUALS);
+    if (equals == null) {
+      return ""; // this will not be referenced because no equals method will be generated
+    }
+    TypeMirror parameterType = equals.getParameters().get(0).asType();
+    return TypeEncoder.encodeWithAnnotations(parameterType);
+  }
+
+  /**
+   * Returns the subset of all abstract methods in the given set of methods. A given method
+   * signature is only mentioned once, even if it is inherited on more than one path. If any of the
+   * abstract methods has a return type or parameter type that is not currently defined then this
+   * method will throw an exception that will cause us to defer processing of the current class
+   * until a later annotation-processing round.
+   */
+  static ImmutableSet<ExecutableElement> abstractMethodsIn(Iterable<ExecutableElement> methods) {
+    Set<Name> noArgMethods = new HashSet<>();
+    ImmutableSet.Builder<ExecutableElement> abstracts = ImmutableSet.builder();
+    for (ExecutableElement method : methods) {
+      if (method.getModifiers().contains(Modifier.ABSTRACT)) {
+        MissingTypes.deferIfMissingTypesIn(method);
+        boolean hasArgs = !method.getParameters().isEmpty();
+        if (hasArgs || noArgMethods.add(method.getSimpleName())) {
+          // If an abstract method with the same signature is inherited on more than one path,
+          // we only add it once. At the moment we only do this check for no-arg methods. All
+          // methods that AutoValue will implement are either no-arg methods or equals(Object).
+          // The former is covered by this check and the latter will lead to vars.equals being
+          // set to true, regardless of how many times it appears. So the only case that is
+          // covered imperfectly here is that of a method that is inherited on more than one path
+          // and that will be consumed by an extension. We could check parameters as well, but that
+          // can be a bit tricky if any of the parameters are generic.
+          abstracts.add(method);
+        }
+      }
+    }
+    return abstracts.build();
+  }
+
+  /**
+   * Returns the subset of property methods in the given set of abstract methods, with their actual
+   * return types. A property method has no arguments, is not void, and is not {@code hashCode()} or
+   * {@code toString()}.
+   */
+  ImmutableMap<ExecutableElement, TypeMirror> propertyMethodsIn(
+      Set<ExecutableElement> abstractMethods,
+      TypeElement autoValueOrOneOfType) {
+    DeclaredType declaredType = MoreTypes.asDeclared(autoValueOrOneOfType.asType());
+    ImmutableSet.Builder<ExecutableElement> properties = ImmutableSet.builder();
+    for (ExecutableElement method : abstractMethods) {
+      if (method.getParameters().isEmpty()
+          && (method.getReturnType().getKind() != TypeKind.VOID || propertiesCanBeVoid())
+          && objectMethodToOverride(method) == ObjectMethod.NONE) {
+        properties.add(method);
+      }
+    }
+    return new EclipseHack(processingEnv).methodReturnTypes(properties.build(), declaredType);
+  }
+
+  /** True if void properties are allowed. */
+  boolean propertiesCanBeVoid() {
+    return false;
+  }
+
+  /**
+   * Checks that the return type of the given property method is allowed. Currently, this means that
+   * it cannot be an array, unless it is a primitive array.
+   */
+  final void checkReturnType(TypeElement autoValueClass, ExecutableElement getter) {
+    TypeMirror type = getter.getReturnType();
+    if (type.getKind() == TypeKind.ARRAY) {
+      TypeMirror componentType = ((ArrayType) type).getComponentType();
+      if (componentType.getKind().isPrimitive()) {
+        warnAboutPrimitiveArrays(autoValueClass, getter);
+      } else {
+        errorReporter.reportError(
+            getter,
+            "An @%s class cannot define an array-valued property unless it is a primitive array",
+            simpleAnnotationName);
+      }
+    }
+  }
+
+  private void warnAboutPrimitiveArrays(TypeElement autoValueClass, ExecutableElement getter) {
+    boolean suppressed = false;
+    Optional<AnnotationMirror> maybeAnnotation =
+        getAnnotationMirror(getter, "java.lang.SuppressWarnings");
+    if (maybeAnnotation.isPresent()) {
+      AnnotationValue listValue = getAnnotationValue(maybeAnnotation.get(), "value");
+      suppressed = listValue.accept(new ContainsMutableVisitor(), null);
+    }
+    if (!suppressed) {
+      // If the primitive-array property method is defined directly inside the @AutoValue class,
+      // then our error message should point directly to it. But if it is inherited, we don't
+      // want to try to make the error message point to the inherited definition, since that would
+      // be confusing (there is nothing wrong with the definition itself), and won't work if the
+      // inherited class is not being recompiled. Instead, in this case we point to the @AutoValue
+      // class itself, and we include extra text in the error message that shows the full name of
+      // the inherited method.
+      boolean sameClass = getter.getEnclosingElement().equals(autoValueClass);
+      Element element = sameClass ? getter : autoValueClass;
+      String context = sameClass ? "" : (" Method: " + getter.getEnclosingElement() + "." + getter);
+      errorReporter.reportWarning(
+          element,
+          "An @%s property that is a primitive array returns the original array, which can"
+              + " therefore be modified by the caller. If this is OK, you can suppress this warning"
+              + " with @SuppressWarnings(\"mutable\"). Otherwise, you should replace the property"
+              + " with an immutable type, perhaps a simple wrapper around the original array.%s",
+          simpleAnnotationName,
+          context);
+    }
+  }
+
+  // Detects whether the visited AnnotationValue is an array that contains the string "mutable".
+  // The simpler approach using Element.getAnnotation(SuppressWarnings.class) doesn't work if
+  // the annotation has an undefined reference, like @SuppressWarnings(UNDEFINED).
+  // TODO(emcmanus): replace with a method from auto-common when that is available.
+  private static class ContainsMutableVisitor extends SimpleAnnotationValueVisitor8<Boolean, Void> {
+    @Override
+    public Boolean visitArray(List<? extends AnnotationValue> list, Void p) {
+      return list.stream().map(av -> av.getValue()).anyMatch("mutable"::equals);
+    }
+  }
+
+  /**
+   * Returns a string like {@code "1234L"} if {@code type instanceof Serializable} and defines
+   * {@code serialVersionUID = 1234L}; otherwise {@code ""}.
+   */
+  final String getSerialVersionUID(TypeElement type) {
+    TypeMirror serializable = elementUtils().getTypeElement(Serializable.class.getName()).asType();
+    if (typeUtils().isAssignable(type.asType(), serializable)) {
+      List<VariableElement> fields = ElementFilter.fieldsIn(type.getEnclosedElements());
+      for (VariableElement field : fields) {
+        if (field.getSimpleName().contentEquals("serialVersionUID")) {
+          Object value = field.getConstantValue();
+          if (field.getModifiers().containsAll(Arrays.asList(Modifier.STATIC, Modifier.FINAL))
+              && field.asType().getKind() == TypeKind.LONG
+              && value != null) {
+            return value + "L";
+          } else {
+            errorReporter.reportError(
+                field, "serialVersionUID must be a static final long compile-time constant");
+            break;
+          }
+        }
+      }
+    }
+    return "";
+  }
+
+  /** Implements the semantics of {@code AutoValue.CopyAnnotations}; see its javadoc. */
+  ImmutableList<AnnotationMirror> annotationsToCopy(
+      Element autoValueType, Element typeOrMethod, Set<String> excludedAnnotations) {
+    ImmutableList.Builder<AnnotationMirror> result = ImmutableList.builder();
+    for (AnnotationMirror annotation : typeOrMethod.getAnnotationMirrors()) {
+      String annotationFqName = getAnnotationFqName(annotation);
+      // To be included, the annotation should not be in com.google.auto.value,
+      // and it should not be in the excludedAnnotations set.
+      if (!isInAutoValuePackage(annotationFqName)
+          && !excludedAnnotations.contains(annotationFqName)
+          && annotationVisibleFrom(annotation, autoValueType)) {
+        result.add(annotation);
+      }
+    }
+
+    return result.build();
+  }
+
+  /**
+   * True if the given class name is in the com.google.auto.value package or a subpackage. False if
+   * the class name contains {@code Test}, since many AutoValue tests under com.google.auto.value
+   * define their own annotations.
+   */
+  private boolean isInAutoValuePackage(String className) {
+    return className.startsWith(AUTO_VALUE_PACKAGE_NAME) && !className.contains("Test");
+  }
+
+  ImmutableList<String> copiedClassAnnotations(TypeElement type) {
+    // Only copy annotations from a class if it has @AutoValue.CopyAnnotations.
+    if (hasAnnotationMirror(type, COPY_ANNOTATIONS_NAME)) {
+      Set<String> excludedAnnotations =
+          union(getExcludedAnnotationClassNames(type), getAnnotationsMarkedWithInherited(type));
+
+      return copyAnnotations(type, type, excludedAnnotations);
+    } else {
+      return ImmutableList.of();
+    }
+  }
+
+  /** Implements the semantics of {@code AutoValue.CopyAnnotations}; see its javadoc. */
+  private ImmutableList<String> copyAnnotations(
+      Element autoValueType, Element typeOrMethod, Set<String> excludedAnnotations) {
+    ImmutableList<AnnotationMirror> annotationsToCopy =
+        annotationsToCopy(autoValueType, typeOrMethod, excludedAnnotations);
+    return annotationStrings(annotationsToCopy);
+  }
+
+  /**
+   * Returns the contents of the {@code AutoValue.CopyAnnotations.exclude} element, as a set of
+   * {@code TypeMirror} where each type is an annotation type.
+   */
+  private Set<TypeMirror> getExcludedAnnotationTypes(Element element) {
+    Optional<AnnotationMirror> maybeAnnotation =
+        getAnnotationMirror(element, COPY_ANNOTATIONS_NAME);
+    if (!maybeAnnotation.isPresent()) {
+      return ImmutableSet.of();
+    }
+
+    @SuppressWarnings("unchecked")
+    List<AnnotationValue> excludedClasses =
+        (List<AnnotationValue>) getAnnotationValue(maybeAnnotation.get(), "exclude").getValue();
+    return excludedClasses
+        .stream()
+        .map(annotationValue -> (DeclaredType) annotationValue.getValue())
+        .collect(toCollection(TypeMirrorSet::new));
+  }
+
+  /**
+   * Returns the contents of the {@code AutoValue.CopyAnnotations.exclude} element, as a set of
+   * strings that are fully-qualified class names.
+   */
+  private Set<String> getExcludedAnnotationClassNames(Element element) {
+    return getExcludedAnnotationTypes(element)
+        .stream()
+        .map(MoreTypes::asTypeElement)
+        .map(typeElement -> typeElement.getQualifiedName().toString())
+        .collect(toSet());
+  }
+
+  private static Set<String> getAnnotationsMarkedWithInherited(Element element) {
+    return element
+        .getAnnotationMirrors()
+        .stream()
+        .filter(a -> isAnnotationPresent(a.getAnnotationType().asElement(), Inherited.class))
+        .map(a -> getAnnotationFqName(a))
+        .collect(toSet());
+  }
+
+  /**
+   * Returns the fully-qualified name of an annotation-mirror, e.g.
+   * "com.google.auto.value.AutoValue".
+   */
+  private static String getAnnotationFqName(AnnotationMirror annotation) {
+    return ((QualifiedNameable) annotation.getAnnotationType().asElement())
+        .getQualifiedName()
+        .toString();
+  }
+
+  final ImmutableListMultimap<ExecutableElement, AnnotationMirror> propertyMethodAnnotationMap(
+      TypeElement type, ImmutableSet<ExecutableElement> propertyMethods) {
+    ImmutableListMultimap.Builder<ExecutableElement, AnnotationMirror> builder =
+        ImmutableListMultimap.builder();
+    for (ExecutableElement propertyMethod : propertyMethods) {
+      builder.putAll(propertyMethod, propertyMethodAnnotations(type, propertyMethod));
+    }
+    return builder.build();
+  }
+
+  private ImmutableList<AnnotationMirror> propertyMethodAnnotations(
+      TypeElement type, ExecutableElement method) {
+    ImmutableSet<String> excludedAnnotations =
+        ImmutableSet.<String>builder()
+            .addAll(getExcludedAnnotationClassNames(method))
+            .add(Override.class.getCanonicalName())
+            .build();
+
+    // We need to exclude type annotations from the ones being output on the method, since
+    // they will be output as part of the method's return type.
+    Set<String> returnTypeAnnotations = getReturnTypeAnnotations(method, a -> true);
+    Set<String> excluded = union(excludedAnnotations, returnTypeAnnotations);
+    return annotationsToCopy(type, method, excluded);
+  }
+
+  final ImmutableListMultimap<ExecutableElement, AnnotationMirror> propertyFieldAnnotationMap(
+      TypeElement type, ImmutableSet<ExecutableElement> propertyMethods) {
+    ImmutableListMultimap.Builder<ExecutableElement, AnnotationMirror> builder =
+        ImmutableListMultimap.builder();
+    for (ExecutableElement propertyMethod : propertyMethods) {
+      builder.putAll(propertyMethod, propertyFieldAnnotations(type, propertyMethod));
+    }
+    return builder.build();
+  }
+
+  private ImmutableList<AnnotationMirror> propertyFieldAnnotations(
+      TypeElement type, ExecutableElement method) {
+    if (!hasAnnotationMirror(method, COPY_ANNOTATIONS_NAME)) {
+      return ImmutableList.of();
+    }
+    ImmutableSet<String> excludedAnnotations =
+        ImmutableSet.<String>builder()
+            .addAll(getExcludedAnnotationClassNames(method))
+            .add(Override.class.getCanonicalName())
+            .build();
+
+    // We need to exclude type annotations from the ones being output on the method, since
+    // they will be output as part of the field's type.
+    Set<String> returnTypeAnnotations =
+        getReturnTypeAnnotations(method, this::annotationAppliesToFields);
+    Set<String> nonFieldAnnotations =
+        method
+            .getAnnotationMirrors()
+            .stream()
+            .map(a -> a.getAnnotationType().asElement())
+            .map(MoreElements::asType)
+            .filter(a -> !annotationAppliesToFields(a))
+            .map(e -> e.getQualifiedName().toString())
+            .collect(toSet());
+
+    Set<String> excluded =
+        ImmutableSet.<String>builder()
+            .addAll(excludedAnnotations)
+            .addAll(returnTypeAnnotations)
+            .addAll(nonFieldAnnotations)
+            .build();
+    return annotationsToCopy(type, method, excluded);
+  }
+
+  private Set<String> getReturnTypeAnnotations(
+      ExecutableElement method, Predicate<TypeElement> typeFilter) {
+    return method
+        .getReturnType()
+        .getAnnotationMirrors()
+        .stream()
+        .map(a -> a.getAnnotationType().asElement())
+        .map(MoreElements::asType)
+        .filter(typeFilter)
+        .map(e -> e.getQualifiedName().toString())
+        .collect(toSet());
+  }
+
+  private boolean annotationAppliesToFields(TypeElement annotation) {
+    Target target = annotation.getAnnotation(Target.class);
+    return target == null || Arrays.asList(target.value()).contains(ElementType.FIELD);
+  }
+
+  private boolean annotationVisibleFrom(AnnotationMirror annotation, Element from) {
+    Element annotationElement = annotation.getAnnotationType().asElement();
+    Visibility visibility = Visibility.effectiveVisibilityOfElement(annotationElement);
+    switch (visibility) {
+      case PUBLIC:
+        return true;
+      case PROTECTED:
+        // If the annotation is protected, it must be inside another class, call it C. If our
+        // @AutoValue class is Foo then, for the annotation to be visible, either Foo must be in the
+        // same package as C or Foo must be a subclass of C. If the annotation is visible from Foo
+        // then it is also visible from our generated subclass AutoValue_Foo.
+        // The protected case only applies to method annotations. An annotation on the AutoValue_Foo
+        // class itself can't be protected, even if AutoValue_Foo ultimately inherits from the
+        // class that defines the annotation. The JLS says "Access is permitted only within the
+        // body of a subclass":
+        // https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.2.1
+        // AutoValue_Foo is a top-level class, so an annotation on it cannot be in the body of a
+        // subclass of anything.
+        return getPackage(annotationElement).equals(getPackage(from))
+            || typeUtils()
+                .isSubtype(from.asType(), annotationElement.getEnclosingElement().asType());
+      case DEFAULT:
+        return getPackage(annotationElement).equals(getPackage(from));
+      default:
+        return false;
+    }
+  }
+
+  /**
+   * Returns the {@code @AutoValue} or {@code @AutoOneOf} type parameters, with a ? for every type.
+   * If we have {@code @AutoValue abstract class Foo<T extends Something>} then this method will
+   * return just {@code <?>}.
+   */
+  private static String wildcardTypeParametersString(TypeElement type) {
+    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();
+    if (typeParameters.isEmpty()) {
+      return "";
+    } else {
+      return typeParameters.stream().map(e -> "?").collect(joining(", ", "<", ">"));
+    }
+  }
+
+  // TODO(emcmanus,ronshapiro): move to auto-common
+  static Optional<AnnotationMirror> getAnnotationMirror(Element element, String annotationName) {
+    for (AnnotationMirror annotation : element.getAnnotationMirrors()) {
+      TypeElement annotationElement = MoreTypes.asTypeElement(annotation.getAnnotationType());
+      if (annotationElement.getQualifiedName().contentEquals(annotationName)) {
+        return Optional.of(annotation);
+      }
+    }
+    return Optional.empty();
+  }
+
+  static boolean hasAnnotationMirror(Element element, String annotationName) {
+    return getAnnotationMirror(element, annotationName).isPresent();
+  }
+
+  final void writeSourceFile(String className, String text, TypeElement originatingType) {
+    try {
+      JavaFileObject sourceFile =
+          processingEnv.getFiler().createSourceFile(className, originatingType);
+      try (Writer writer = sourceFile.openWriter()) {
+        writer.write(text);
+      }
+    } catch (IOException e) {
+      // This should really be an error, but we make it a warning in the hope of resisting Eclipse
+      // bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=367599. If that bug manifests, we may get
+      // invoked more than once for the same file, so ignoring the ability to overwrite it is the
+      // right thing to do. If we are unable to write for some other reason, we should get a compile
+      // error later because user code will have a reference to the code we were supposed to
+      // generate (new AutoValue_Foo() or whatever) and that reference will be undefined.
+      errorReporter.reportWarning(
+          originatingType, "Could not write generated class %s: %s", className, e);
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/AutoValueOrOneOfTemplateVars.java b/value/src/main/java/com/google/auto/value/processor/AutoValueOrOneOfTemplateVars.java
new file mode 100644
index 0000000..9fdbea4
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AutoValueOrOneOfTemplateVars.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * The variables to substitute into the autovalue.vm or autooneof.vm template.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@SuppressWarnings("unused") // the fields in this class are only read via reflection
+abstract class AutoValueOrOneOfTemplateVars extends TemplateVars {
+  /** Whether to generate an equals(Object) method. */
+  Boolean equals;
+
+  /** Whether to generate a hashCode() method. */
+  Boolean hashCode;
+
+  /** Whether to generate a toString() method. */
+  Boolean toString;
+
+  /**
+   * A string representing the parameter type declaration of the equals(Object) method, including
+   * any annotations. If {@link #equals} is false, this field is ignored (but it must still be
+   * non-null).
+   */
+  String equalsParameterType;
+
+  /** The encoding of the {@code Generated} class. Empty if the class is not available. */
+  String generated;
+
+  /** The package of the class with the {@code @AutoValue} annotation and its generated subclass. */
+  String pkg;
+
+  /**
+   * The name of the class with the {@code @AutoValue} annotation, including containing classes but
+   * not including the package name.
+   */
+  String origClass;
+
+  /** The simple name of the class with the {@code @AutoValue} annotation. */
+  String simpleClassName;
+
+  /**
+   * The full spelling of any annotations to add to this class, or an empty list if there are none.
+   * A non-empty value might look something like {@code
+   * "@`com.google.common.annotations.GwtCompatible`(serializable = true)"}. The {@code ``} marks
+   * are explained in {@link TypeEncoder}.
+   */
+  ImmutableList<String> annotations;
+
+  /**
+   * The formal generic signature of the class with the {@code @AutoValue} or {@code AutoOneOf}
+   * annotation and any generated subclass. This is empty, or contains type variables with optional
+   * bounds, for example {@code <K, V extends K>}.
+   */
+  String formalTypes;
+
+  /**
+   * The generic signature used by any generated subclass for its superclass reference. This is
+   * empty, or contains only type variables with no bounds, for example {@code <K, V>}.
+   */
+  String actualTypes;
+
+  /**
+   * The generic signature in {@link #actualTypes} where every variable has been replaced by a
+   * wildcard, for example {@code <?, ?>}.
+   */
+  String wildcardTypes;
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/AutoValueProcessor.java b/value/src/main/java/com/google/auto/value/processor/AutoValueProcessor.java
new file mode 100644
index 0000000..f3b396c
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AutoValueProcessor.java
@@ -0,0 +1,498 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;
+import static com.google.auto.value.processor.ClassNames.AUTO_VALUE_NAME;
+import static com.google.common.collect.Sets.difference;
+import static com.google.common.collect.Sets.intersection;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
+
+import com.google.auto.service.AutoService;
+import com.google.auto.value.extension.AutoValueExtension;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Strings;
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableListMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.ServiceConfigurationError;
+import java.util.Set;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;
+
+/**
+ * Javac annotation processor (compiler plugin) for value types; user code never references this
+ * class.
+ *
+ * @see <a href="https://github.com/google/auto/tree/master/value">AutoValue User's Guide</a>
+ * @author Éamonn McManus
+ */
+@AutoService(Processor.class)
+@SupportedAnnotationTypes(AUTO_VALUE_NAME)
+@IncrementalAnnotationProcessor(IncrementalAnnotationProcessorType.DYNAMIC)
+public class AutoValueProcessor extends AutoValueOrOneOfProcessor {
+  private static final String OMIT_IDENTIFIERS_OPTION = "com.google.auto.value.OmitIdentifiers";
+
+  // We moved MemoizeExtension to a different package, which had an unexpected effect:
+  // now if an old version of AutoValue is in the class path, ServiceLoader can pick up both the
+  // old and the new versions of MemoizeExtension. So we exclude the old version if we see it.
+  // The new version will be bundled with this processor so we should always find it.
+  private static final String OLD_MEMOIZE_EXTENSION =
+      "com.google.auto.value.extension.memoized.MemoizeExtension";
+
+  public AutoValueProcessor() {
+    this(AutoValueProcessor.class.getClassLoader());
+  }
+
+  @VisibleForTesting
+  AutoValueProcessor(ClassLoader loaderForExtensions) {
+    super(AUTO_VALUE_NAME);
+    this.extensions = null;
+    this.loaderForExtensions = loaderForExtensions;
+  }
+
+  @VisibleForTesting
+  public AutoValueProcessor(Iterable<? extends AutoValueExtension> extensions) {
+    super(AUTO_VALUE_NAME);
+    this.extensions = ImmutableList.copyOf(extensions);
+    this.loaderForExtensions = null;
+  }
+
+  // Depending on how this AutoValueProcessor was constructed, we might already have a list of
+  // extensions when init() is run, or, if `extensions` is null, we have a ClassLoader that will be
+  // used to get the list using the ServiceLoader API.
+  private ImmutableList<AutoValueExtension> extensions;
+  private final ClassLoader loaderForExtensions;
+
+  @VisibleForTesting
+  static ImmutableList<AutoValueExtension> extensionsFromLoader(ClassLoader loader) {
+    return ImmutableList.copyOf(
+        Iterables.filter(
+            SimpleServiceLoader.load(AutoValueExtension.class, loader),
+            ext -> !ext.getClass().getName().equals(OLD_MEMOIZE_EXTENSION)));
+  }
+
+  @Override
+  public synchronized void init(ProcessingEnvironment processingEnv) {
+    super.init(processingEnv);
+
+    if (extensions == null) {
+      try {
+        extensions = extensionsFromLoader(loaderForExtensions);
+      } catch (RuntimeException | Error e) {
+        String explain =
+            (e instanceof ServiceConfigurationError)
+                ? " This may be due to a corrupt jar file in the compiler's classpath."
+                : "";
+        errorReporter()
+            .reportWarning(
+                null,
+                "An exception occurred while looking for AutoValue extensions."
+                    + " No extensions will function.%s\n%s",
+                explain,
+                Throwables.getStackTraceAsString(e));
+        extensions = ImmutableList.of();
+      }
+    }
+  }
+
+  @Override
+  public Set<String> getSupportedOptions() {
+    ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+    AutoValueExtension.IncrementalExtensionType incrementalType =
+        extensions.stream()
+            .map(e -> e.incrementalType(processingEnv))
+            .min(Comparator.naturalOrder())
+            .orElse(AutoValueExtension.IncrementalExtensionType.ISOLATING);
+    builder.add(OMIT_IDENTIFIERS_OPTION).addAll(optionsFor(incrementalType));
+    for (AutoValueExtension extension : extensions) {
+      builder.addAll(extension.getSupportedOptions());
+    }
+    return builder.build();
+  }
+
+  private static ImmutableSet<String> optionsFor(
+      AutoValueExtension.IncrementalExtensionType incrementalType) {
+    switch (incrementalType) {
+      case ISOLATING:
+        return ImmutableSet.of(IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());
+      case AGGREGATING:
+        return ImmutableSet.of(IncrementalAnnotationProcessorType.AGGREGATING.getProcessorOption());
+      case UNKNOWN:
+        return ImmutableSet.of();
+    }
+    throw new AssertionError(incrementalType);
+  }
+
+  static String generatedSubclassName(TypeElement type, int depth) {
+    return generatedClassName(type, Strings.repeat("$", depth) + "AutoValue_");
+  }
+
+  @Override
+  void processType(TypeElement type) {
+    if (!hasAnnotationMirror(type, AUTO_VALUE_NAME)) {
+      // This shouldn't happen unless the compilation environment is buggy,
+      // but it has happened in the past and can crash the compiler.
+      errorReporter()
+          .abortWithError(
+              type,
+              "annotation processor for @AutoValue was invoked with a type"
+                  + " that does not have that annotation; this is probably a compiler bug");
+    }
+    if (type.getKind() != ElementKind.CLASS) {
+      errorReporter().abortWithError(type, "@AutoValue only applies to classes");
+    }
+    if (ancestorIsAutoValue(type)) {
+      errorReporter().abortWithError(type, "One @AutoValue class may not extend another");
+    }
+    if (implementsAnnotation(type)) {
+      errorReporter()
+          .abortWithError(
+              type, "@AutoValue may not be used to implement an annotation"
+                  + " interface; try using @AutoAnnotation instead");
+    }
+    checkModifiersIfNested(type);
+
+    // We are going to classify the methods of the @AutoValue class into several categories.
+    // This covers the methods in the class itself and the ones it inherits from supertypes.
+    // First, the only concrete (non-abstract) methods we are interested in are overrides of
+    // Object methods (equals, hashCode, toString), which signal that we should not generate
+    // an implementation of those methods.
+    // Then, each abstract method is one of the following:
+    // (1) A property getter, like "abstract String foo()" or "abstract String getFoo()".
+    // (2) A toBuilder() method, which is any abstract no-arg method returning the Builder for
+    //     this @AutoValue class.
+    // (3) An abstract method that will be consumed by an extension, such as
+    //     Parcelable.describeContents() or Parcelable.writeToParcel(Parcel, int).
+    // The describeContents() example shows a quirk here: initially we will identify it as a
+    // property, which means that we need to reconstruct the list of properties after allowing
+    // extensions to consume abstract methods.
+    // If there are abstract methods that don't fit any of the categories above, that is an error
+    // which we signal explicitly to avoid confusion.
+
+    ImmutableSet<ExecutableElement> methods =
+        getLocalAndInheritedMethods(
+            type, processingEnv.getTypeUtils(), processingEnv.getElementUtils());
+    ImmutableSet<ExecutableElement> abstractMethods = abstractMethodsIn(methods);
+
+    BuilderSpec builderSpec = new BuilderSpec(type, processingEnv, errorReporter());
+    Optional<BuilderSpec.Builder> builder = builderSpec.getBuilder();
+    ImmutableSet<ExecutableElement> toBuilderMethods;
+    if (builder.isPresent()) {
+      toBuilderMethods = builder.get().toBuilderMethods(typeUtils(), abstractMethods);
+    } else {
+      toBuilderMethods = ImmutableSet.of();
+    }
+
+    ImmutableMap<ExecutableElement, TypeMirror> propertyMethodsAndTypes =
+        propertyMethodsIn(immutableSetDifference(abstractMethods, toBuilderMethods), type);
+    ImmutableMap<String, ExecutableElement> properties =
+        propertyNameToMethodMap(propertyMethodsAndTypes.keySet());
+
+    ExtensionContext context = new ExtensionContext(
+        processingEnv, type, properties, propertyMethodsAndTypes, abstractMethods);
+    ImmutableList<AutoValueExtension> applicableExtensions = applicableExtensions(type, context);
+    ImmutableSet<ExecutableElement> consumedMethods =
+        methodsConsumedByExtensions(
+            type, applicableExtensions, context, abstractMethods, properties);
+
+    if (!consumedMethods.isEmpty()) {
+      ImmutableSet<ExecutableElement> allAbstractMethods = abstractMethods;
+      abstractMethods = immutableSetDifference(abstractMethods, consumedMethods);
+      toBuilderMethods = immutableSetDifference(toBuilderMethods, consumedMethods);
+      propertyMethodsAndTypes =
+          propertyMethodsIn(immutableSetDifference(abstractMethods, toBuilderMethods), type);
+      properties = propertyNameToMethodMap(propertyMethodsAndTypes.keySet());
+      context = new ExtensionContext(
+          processingEnv, type, properties, propertyMethodsAndTypes, allAbstractMethods);
+    }
+
+    ImmutableSet<ExecutableElement> propertyMethods = propertyMethodsAndTypes.keySet();
+    boolean extensionsPresent = !applicableExtensions.isEmpty();
+    validateMethods(type, abstractMethods, toBuilderMethods, propertyMethods, extensionsPresent);
+
+    String finalSubclass = generatedSubclassName(type, 0);
+    AutoValueTemplateVars vars = new AutoValueTemplateVars();
+    vars.finalSubclass = TypeSimplifier.simpleNameOf(finalSubclass);
+    vars.types = processingEnv.getTypeUtils();
+    vars.identifiers = !processingEnv.getOptions().containsKey(OMIT_IDENTIFIERS_OPTION);
+    defineSharedVarsForType(type, methods, vars);
+    defineVarsForType(type, vars, toBuilderMethods, propertyMethodsAndTypes, builder);
+
+    // If we've encountered problems then we might end up invoking extensions with inconsistent
+    // state. Anyway we probably don't want to generate code which is likely to provoke further
+    // compile errors to add to the ones we've already seen.
+    errorReporter().abortIfAnyError();
+
+    GwtCompatibility gwtCompatibility = new GwtCompatibility(type);
+    vars.gwtCompatibleAnnotation = gwtCompatibility.gwtCompatibleAnnotationString();
+
+    builder.ifPresent(context::setBuilderContext);
+    int subclassDepth = writeExtensions(type, context, applicableExtensions);
+    String subclass = generatedSubclassName(type, subclassDepth);
+    vars.subclass = TypeSimplifier.simpleNameOf(subclass);
+    vars.isFinal = (subclassDepth == 0);
+    vars.modifiers = vars.isFinal ? "final " : "abstract ";
+
+    String text = vars.toText();
+    text = TypeEncoder.decode(text, processingEnv, vars.pkg, type.asType());
+    text = Reformatter.fixup(text);
+    writeSourceFile(subclass, text, type);
+    GwtSerialization gwtSerialization = new GwtSerialization(gwtCompatibility, processingEnv, type);
+    gwtSerialization.maybeWriteGwtSerializer(vars);
+  }
+
+  // Invokes each of the given extensions to generate its subclass, and returns the number of
+  // hierarchy classes that extensions generated. This number is then the number of $ characters
+  // that should precede the name of the AutoValue implementation class.
+  // Assume the @AutoValue class is com.example.Foo.Bar. Then if there are no
+  // extensions the returned value will be 0, so the AutoValue implementation will be
+  // com.example.AutoValue_Foo_Bar. If there is one extension, it will be asked to
+  // generate AutoValue_Foo_Bar with parent $AutoValue_Foo_Bar. If it does so (returns
+  // non-null) then the returned value will be 1, so the AutoValue implementation will be
+  // com.example.$AutoValue_Foo_Bar. Otherwise, the returned value will still be 0. Likewise,
+  // if there is a second extension and both extensions return non-null, the first one will
+  // generate AutoValue_Foo_Bar with parent $AutoValue_Foo_Bar, the second will generate
+  // $AutoValue_Foo_Bar with parent $$AutoValue_Foo_Bar, and the returned value will be 2 for
+  // com.example.$$AutoValue_Foo_Bar.
+  private int writeExtensions(
+      TypeElement type,
+      ExtensionContext context,
+      ImmutableList<AutoValueExtension> applicableExtensions) {
+    int writtenSoFar = 0;
+    for (AutoValueExtension extension : applicableExtensions) {
+      String parentFqName = generatedSubclassName(type, writtenSoFar + 1);
+      String parentSimpleName = TypeSimplifier.simpleNameOf(parentFqName);
+      String classFqName = generatedSubclassName(type, writtenSoFar);
+      String classSimpleName = TypeSimplifier.simpleNameOf(classFqName);
+      boolean isFinal = (writtenSoFar == 0);
+      String source = extension.generateClass(context, classSimpleName, parentSimpleName, isFinal);
+      if (source != null) {
+        source = Reformatter.fixup(source);
+        writeSourceFile(classFqName, source, type);
+        writtenSoFar++;
+      }
+    }
+    return writtenSoFar;
+  }
+
+  private ImmutableList<AutoValueExtension> applicableExtensions(
+      TypeElement type, ExtensionContext context) {
+    List<AutoValueExtension> applicableExtensions = new ArrayList<>();
+    List<AutoValueExtension> finalExtensions = new ArrayList<>();
+    for (AutoValueExtension extension : extensions) {
+      if (extension.applicable(context)) {
+        if (extension.mustBeFinal(context)) {
+          finalExtensions.add(extension);
+        } else {
+          applicableExtensions.add(extension);
+        }
+      }
+    }
+    switch (finalExtensions.size()) {
+      case 0:
+        break;
+      case 1:
+        applicableExtensions.add(0, finalExtensions.get(0));
+        break;
+      default:
+        errorReporter()
+            .reportError(
+                type,
+                "More than one extension wants to generate the final class: %s",
+                finalExtensions.stream().map(this::extensionName).collect(joining(", ")));
+        break;
+    }
+    return ImmutableList.copyOf(applicableExtensions);
+  }
+
+  private ImmutableSet<ExecutableElement> methodsConsumedByExtensions(
+      TypeElement type,
+      ImmutableList<AutoValueExtension> applicableExtensions,
+      ExtensionContext context,
+      ImmutableSet<ExecutableElement> abstractMethods,
+      ImmutableMap<String, ExecutableElement> properties) {
+    Set<ExecutableElement> consumed = new HashSet<>();
+    for (AutoValueExtension extension : applicableExtensions) {
+      Set<ExecutableElement> consumedHere = new HashSet<>();
+      for (String consumedProperty : extension.consumeProperties(context)) {
+        ExecutableElement propertyMethod = properties.get(consumedProperty);
+        if (propertyMethod == null) {
+          errorReporter()
+              .reportError(
+                  type,
+                  "Extension %s wants to consume a property that does not exist: %s",
+                  extensionName(extension),
+                  consumedProperty);
+        } else {
+          consumedHere.add(propertyMethod);
+        }
+      }
+      for (ExecutableElement consumedMethod : extension.consumeMethods(context)) {
+        if (!abstractMethods.contains(consumedMethod)) {
+          errorReporter()
+              .reportError(
+                  type,
+                  "Extension %s wants to consume a method that is not one of the abstract methods"
+                      + " in this class: %s",
+                  extensionName(extension),
+                  consumedMethod);
+        } else {
+          consumedHere.add(consumedMethod);
+        }
+      }
+      for (ExecutableElement repeat : intersection(consumed, consumedHere)) {
+        errorReporter()
+            .reportError(
+                repeat,
+                "Extension %s wants to consume a method that was already consumed by another"
+                    + " extension",
+                extensionName(extension));
+      }
+      consumed.addAll(consumedHere);
+    }
+    return ImmutableSet.copyOf(consumed);
+  }
+
+  private void validateMethods(
+      TypeElement type,
+      ImmutableSet<ExecutableElement> abstractMethods,
+      ImmutableSet<ExecutableElement> toBuilderMethods,
+      ImmutableSet<ExecutableElement> propertyMethods,
+      boolean extensionsPresent) {
+    for (ExecutableElement method : abstractMethods) {
+      if (propertyMethods.contains(method)) {
+        checkReturnType(type, method);
+      } else if (!toBuilderMethods.contains(method)
+          && objectMethodToOverride(method) == ObjectMethod.NONE) {
+        // This could reasonably be an error, were it not for an Eclipse bug in
+        // ElementUtils.override that sometimes fails to recognize that one method overrides
+        // another, and therefore leaves us with both an abstract method and the subclass method
+        // that overrides it. This shows up in AutoValueTest.LukesBase for example.
+        String extensionMessage = extensionsPresent ? ", and no extension consumed it" : "";
+        errorReporter().reportWarning(
+            method,
+            "Abstract method is neither a property getter nor a Builder converter%s",
+            extensionMessage);
+      }
+    }
+    errorReporter().abortIfAnyError();
+  }
+
+  private String extensionName(AutoValueExtension extension) {
+    return extension.getClass().getName();
+  }
+
+  private void defineVarsForType(
+      TypeElement type,
+      AutoValueTemplateVars vars,
+      ImmutableSet<ExecutableElement> toBuilderMethods,
+      ImmutableMap<ExecutableElement, TypeMirror> propertyMethodsAndTypes,
+      Optional<BuilderSpec.Builder> maybeBuilder) {
+    ImmutableSet<ExecutableElement> propertyMethods = propertyMethodsAndTypes.keySet();
+    // We can't use ImmutableList.toImmutableList() for obscure Google-internal reasons.
+    vars.toBuilderMethods =
+        ImmutableList.copyOf(toBuilderMethods.stream().map(SimpleMethod::new).collect(toList()));
+    ImmutableListMultimap<ExecutableElement, AnnotationMirror> annotatedPropertyFields =
+        propertyFieldAnnotationMap(type, propertyMethods);
+    ImmutableListMultimap<ExecutableElement, AnnotationMirror> annotatedPropertyMethods =
+        propertyMethodAnnotationMap(type, propertyMethods);
+    vars.props =
+        propertySet(propertyMethodsAndTypes, annotatedPropertyFields, annotatedPropertyMethods);
+    vars.serialVersionUID = getSerialVersionUID(type);
+    // Check for @AutoValue.Builder and add appropriate variables if it is present.
+    maybeBuilder.ifPresent(
+        builder -> {
+          ImmutableBiMap<ExecutableElement, String> methodToPropertyName =
+              propertyNameToMethodMap(propertyMethods).inverse();
+          builder.defineVars(vars, methodToPropertyName);
+          vars.builderAnnotations = copiedClassAnnotations(builder.builderType());
+        });
+  }
+
+  @Override
+  Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod) {
+    return nullableAnnotationFor(propertyMethod, propertyMethod.getReturnType());
+  }
+
+  static ImmutableSet<ExecutableElement> prefixedGettersIn(Iterable<ExecutableElement> methods) {
+    ImmutableSet.Builder<ExecutableElement> getters = ImmutableSet.builder();
+    for (ExecutableElement method : methods) {
+      String name = method.getSimpleName().toString();
+      // TODO(emcmanus): decide whether getfoo() (without a capital) is a getter. Currently it is.
+      boolean get = name.startsWith("get") && !name.equals("get");
+      boolean is =
+          name.startsWith("is")
+              && !name.equals("is")
+              && method.getReturnType().getKind() == TypeKind.BOOLEAN;
+      if (get || is) {
+        getters.add(method);
+      }
+    }
+    return getters.build();
+  }
+
+  private boolean ancestorIsAutoValue(TypeElement type) {
+    while (true) {
+      TypeMirror parentMirror = type.getSuperclass();
+      if (parentMirror.getKind() == TypeKind.NONE) {
+        return false;
+      }
+      TypeElement parentElement = (TypeElement) typeUtils().asElement(parentMirror);
+      if (hasAnnotationMirror(parentElement, AUTO_VALUE_NAME)) {
+        return true;
+      }
+      type = parentElement;
+    }
+  }
+
+  private boolean implementsAnnotation(TypeElement type) {
+    return typeUtils().isAssignable(type.asType(), getTypeMirror(Annotation.class));
+  }
+
+  private TypeMirror getTypeMirror(Class<?> c) {
+    return processingEnv.getElementUtils().getTypeElement(c.getName()).asType();
+  }
+
+  private static <E> ImmutableSet<E> immutableSetDifference(ImmutableSet<E> a, ImmutableSet<E> b) {
+    if (Collections.disjoint(a, b)) {
+      return a;
+    } else {
+      return ImmutableSet.copyOf(difference(a, b));
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/AutoValueTemplateVars.java b/value/src/main/java/com/google/auto/value/processor/AutoValueTemplateVars.java
new file mode 100644
index 0000000..8f855bd
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/AutoValueTemplateVars.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.escapevelocity.Template;
+import java.util.Optional;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.util.Types;
+
+/**
+ * The variables to substitute into the autovalue.vm template.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@SuppressWarnings("unused") // the fields in this class are only read via reflection
+class AutoValueTemplateVars extends AutoValueOrOneOfTemplateVars {
+  /**
+   * The properties defined by the parent class's abstract methods. The elements of this set are in
+   * the same order as the original abstract method declarations in the AutoValue class.
+   */
+  ImmutableSet<AutoValueOrOneOfProcessor.Property> props;
+
+  /**
+   * Whether to include identifiers in strings in the generated code. If false, exception messages
+   * will not mention properties by name, and {@code toString()} will include neither property names
+   * nor the name of the {@code @AutoValue} class.
+   */
+  Boolean identifiers;
+
+  /** The type utilities returned by {@link ProcessingEnvironment#getTypeUtils()}. */
+  Types types;
+
+  /**
+   * The encoding of the {@code @GwtCompatible} annotation to add to this class, or an empty string
+   * if there is none. A non-empty value will look something like {@code
+   * "@`com.google.common.annotations.GwtCompatible`(serializable = true)"}, where the {@code ``}
+   * represent the encoding used by {@link TypeEncoder}.
+   */
+  String gwtCompatibleAnnotation;
+
+  /** The text of the serialVersionUID constant, or empty if there is none. */
+  String serialVersionUID;
+
+  /** The simple name of the generated subclass. */
+  String subclass;
+  /**
+   * The simple name of the final generated subclass. For {@code @AutoValue public static class Foo
+   * {}} this should always be "AutoValue_Foo".
+   */
+  String finalSubclass;
+
+  /**
+   * True if the generated class should be final (there are no extensions that will generate
+   * subclasses)
+   */
+  Boolean isFinal = false;
+
+  /**
+   * The modifiers (for example {@code final} or {@code abstract}) for the generated subclass,
+   * followed by a space if they are not empty.
+   */
+  String modifiers;
+
+  /**
+   * The name of the builder type as it should appear in source code, or empty if there is no
+   * builder type. If class {@code Address} contains {@code @AutoValue.Builder} class Builder then
+   * this will typically be {@code "Address.Builder"}.
+   */
+  String builderTypeName = "";
+
+  /**
+   * The formal generic signature of the {@code AutoValue.Builder} class. This is empty, or contains
+   * type variables with optional bounds, for example {@code <K, V extends K>}.
+   */
+  String builderFormalTypes = "";
+  /**
+   * The generic signature used by the generated builder subclass for its superclass reference. This
+   * is empty, or contains only type variables with no bounds, for example {@code <K, V>}.
+   */
+  String builderActualTypes = "";
+
+  /** True if the builder being implemented is an interface, false if it is an abstract class. */
+  Boolean builderIsInterface = false;
+
+  /**
+   * The full spelling of any annotations to add to the generated builder subclass, or an empty list
+   * if there are none. A non-empty value might look something like {@code
+   * @`java.lang.SuppressWarnings`("Immutable")}. The {@code ``} marks are explained in
+   * {@link TypeEncoder}.
+   */
+  ImmutableList<String> builderAnnotations = ImmutableList.of();
+
+  /** The builder's build method, often {@code "build"}. */
+  Optional<SimpleMethod> buildMethod = Optional.empty();
+
+  /**
+   * A multimap from property names (like foo) to the corresponding setters. The same property may
+   * be set by more than one setter. For example, an ImmutableList might be set by {@code
+   * setFoo(ImmutableList<String>)} and {@code setFoo(String[])}.
+   */
+  ImmutableMultimap<String, BuilderSpec.PropertySetter> builderSetters = ImmutableMultimap.of();
+
+  /**
+   * A map from property names to information about the associated property builder. A property
+   * called foo (defined by a method foo() or getFoo()) can have a property builder called
+   * fooBuilder(). The type of foo must be a type that has an associated builder following certain
+   * conventions. Guava immutable types such as ImmutableList follow those conventions, as do many
+   * {@code @AutoValue} types.
+   */
+  ImmutableMap<String, PropertyBuilder> builderPropertyBuilders = ImmutableMap.of();
+
+  /**
+   * Properties that are required to be set. A property must be set explicitly except in the
+   * following cases:
+   *
+   * <ul>
+   *   <li>it is {@code @Nullable} (in which case it defaults to null);
+   *   <li>it is {@code Optional} (in which case it defaults to empty);
+   *   <li>it has a property-builder method (in which case it defaults to empty).
+   * </ul>
+   */
+  ImmutableSet<AutoValueProcessor.Property> builderRequiredProperties = ImmutableSet.of();
+
+  /**
+   * A map from property names to information about the associated property getter. A property
+   * called foo (defined by a method foo() or getFoo()) can have a property getter method with the
+   * same name (foo() or getFoo()) and either the same return type or an Optional (or OptionalInt,
+   * etc) wrapping it.
+   */
+  ImmutableMap<String, BuilderSpec.PropertyGetter> builderGetters = ImmutableMap.of();
+
+  /** Any {@code toBuilder()} methods, that is methods that return the builder type. */
+  ImmutableList<SimpleMethod> toBuilderMethods;
+
+  private static final Template TEMPLATE = parsedTemplateForResource("autovalue.vm");
+
+  @Override
+  Template parsedTemplate() {
+    return TEMPLATE;
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/BuilderMethodClassifier.java b/value/src/main/java/com/google/auto/value/processor/BuilderMethodClassifier.java
new file mode 100644
index 0000000..724a322
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/BuilderMethodClassifier.java
@@ -0,0 +1,619 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.auto.value.processor.AutoValueOrOneOfProcessor.nullableAnnotationFor;
+import static com.google.common.collect.Sets.difference;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.processor.BuilderSpec.PropertySetter;
+import com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder;
+import com.google.common.base.Equivalence;
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Multimap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+
+/**
+ * Classifies methods inside builder types, based on their names and parameter and return types.
+ *
+ * @author Éamonn McManus
+ */
+class BuilderMethodClassifier {
+  private static final Equivalence<TypeMirror> TYPE_EQUIVALENCE = MoreTypes.equivalence();
+
+  private final ErrorReporter errorReporter;
+  private final Types typeUtils;
+  private final Elements elementUtils;
+  private final TypeElement autoValueClass;
+  private final TypeElement builderType;
+  private final ImmutableBiMap<ExecutableElement, String> getterToPropertyName;
+  private final ImmutableMap<ExecutableElement, TypeMirror> getterToPropertyType;
+  private final ImmutableMap<String, ExecutableElement> getterNameToGetter;
+
+  private final Set<ExecutableElement> buildMethods = new LinkedHashSet<>();
+  private final Map<String, BuilderSpec.PropertyGetter> builderGetters = new LinkedHashMap<>();
+  private final Map<String, PropertyBuilder> propertyNameToPropertyBuilder = new LinkedHashMap<>();
+  private final Multimap<String, PropertySetter> propertyNameToPrefixedSetters =
+      LinkedListMultimap.create();
+  private final Multimap<String, PropertySetter> propertyNameToUnprefixedSetters =
+      LinkedListMultimap.create();
+  private final EclipseHack eclipseHack;
+
+  private boolean settersPrefixed;
+
+  private BuilderMethodClassifier(
+      ErrorReporter errorReporter,
+      ProcessingEnvironment processingEnv,
+      TypeElement autoValueClass,
+      TypeElement builderType,
+      ImmutableBiMap<ExecutableElement, String> getterToPropertyName,
+      ImmutableMap<ExecutableElement, TypeMirror> getterToPropertyType) {
+    this.errorReporter = errorReporter;
+    this.typeUtils = processingEnv.getTypeUtils();
+    this.elementUtils = processingEnv.getElementUtils();
+    this.autoValueClass = autoValueClass;
+    this.builderType = builderType;
+    this.getterToPropertyName = getterToPropertyName;
+    this.getterToPropertyType = getterToPropertyType;
+    ImmutableMap.Builder<String, ExecutableElement> getterToPropertyNameBuilder =
+        ImmutableMap.builder();
+    for (ExecutableElement getter : getterToPropertyName.keySet()) {
+      getterToPropertyNameBuilder.put(getter.getSimpleName().toString(), getter);
+    }
+    this.getterNameToGetter = getterToPropertyNameBuilder.build();
+    this.eclipseHack = new EclipseHack(processingEnv);
+  }
+
+  /**
+   * Classifies the given methods from a builder type and its ancestors.
+   *
+   * @param methods the abstract methods in {@code builderType} and its ancestors.
+   * @param errorReporter where to report errors.
+   * @param processingEnv the ProcessingEnvironment for annotation processing.
+   * @param autoValueClass the {@code AutoValue} class containing the builder.
+   * @param builderType the builder class or interface within {@code autoValueClass}.
+   * @param getterToPropertyName a map from getter methods to the properties they get.
+   * @param getterToPropertyType a map from getter methods to their return types. The return types
+   *     here use type parameters from the builder class (if any) rather than from the {@code
+   *     AutoValue} class, even though the getter methods are in the latter.
+   * @param autoValueHasToBuilder true if the containing {@code @AutoValue} class has a {@code
+   *     toBuilder()} method.
+   * @return an {@code Optional} that contains the results of the classification if it was
+   *     successful or nothing if it was not.
+   */
+  static Optional<BuilderMethodClassifier> classify(
+      Iterable<ExecutableElement> methods,
+      ErrorReporter errorReporter,
+      ProcessingEnvironment processingEnv,
+      TypeElement autoValueClass,
+      TypeElement builderType,
+      ImmutableBiMap<ExecutableElement, String> getterToPropertyName,
+      ImmutableMap<ExecutableElement, TypeMirror> getterToPropertyType,
+      boolean autoValueHasToBuilder) {
+    BuilderMethodClassifier classifier =
+        new BuilderMethodClassifier(
+            errorReporter,
+            processingEnv,
+            autoValueClass,
+            builderType,
+            getterToPropertyName,
+            getterToPropertyType);
+    if (classifier.classifyMethods(methods, autoValueHasToBuilder)) {
+      return Optional.of(classifier);
+    } else {
+      return Optional.empty();
+    }
+  }
+
+  /**
+   * Returns a multimap from the name of a property to the methods that set it. If the property is
+   * defined by an abstract method in the {@code @AutoValue} class called {@code foo()} or {@code
+   * getFoo()} then the name of the property is {@code foo} and there will be an entry in the map
+   * where the key is {@code "foo"} and the value describes a method in the builder called
+   * {@code foo} or {@code setFoo}.
+   */
+  ImmutableMultimap<String, PropertySetter> propertyNameToSetters() {
+    return ImmutableMultimap.copyOf(
+        settersPrefixed ? propertyNameToPrefixedSetters : propertyNameToUnprefixedSetters);
+  }
+
+  Map<String, PropertyBuilder> propertyNameToPropertyBuilder() {
+    return propertyNameToPropertyBuilder;
+  }
+
+  /**
+   * Returns the set of properties that have getters in the builder. If a property is defined by an
+   * abstract method in the {@code @AutoValue} class called {@code foo()} or {@code getFoo()} then
+   * the name of the property is {@code foo}, If the builder also has a method of the same name
+   * ({@code foo()} or {@code getFoo()}) then the set returned here will contain {@code foo}.
+   */
+  ImmutableMap<String, BuilderSpec.PropertyGetter> builderGetters() {
+    return ImmutableMap.copyOf(builderGetters);
+  }
+
+  /**
+   * Returns the methods that were identified as {@code build()} methods. These are methods that
+   * have no parameters and return the {@code @AutoValue} type, conventionally called {@code
+   * build()}.
+   */
+  Set<ExecutableElement> buildMethods() {
+    return ImmutableSet.copyOf(buildMethods);
+  }
+
+  /** Classifies the given methods and sets the state of this object based on what is found. */
+  private boolean classifyMethods(
+      Iterable<ExecutableElement> methods, boolean autoValueHasToBuilder) {
+    int startErrorCount = errorReporter.errorCount();
+    for (ExecutableElement method : methods) {
+      classifyMethod(method);
+    }
+    if (errorReporter.errorCount() > startErrorCount) {
+      return false;
+    }
+    Multimap<String, PropertySetter> propertyNameToSetter;
+    if (propertyNameToPrefixedSetters.isEmpty()) {
+      propertyNameToSetter = propertyNameToUnprefixedSetters;
+      this.settersPrefixed = false;
+    } else if (propertyNameToUnprefixedSetters.isEmpty()) {
+      propertyNameToSetter = propertyNameToPrefixedSetters;
+      this.settersPrefixed = true;
+    } else {
+      errorReporter.reportError(
+          propertyNameToUnprefixedSetters.values().iterator().next().getSetter(),
+          "If any setter methods use the setFoo convention then all must");
+      return false;
+    }
+    getterToPropertyName.forEach(
+        (getter, property) -> {
+          TypeMirror propertyType = getterToPropertyType.get(getter);
+          boolean hasSetter = propertyNameToSetter.containsKey(property);
+          PropertyBuilder propertyBuilder = propertyNameToPropertyBuilder.get(property);
+          boolean hasBuilder = propertyBuilder != null;
+          if (hasBuilder) {
+            // If property bar of type Bar has a barBuilder() that returns BarBuilder, then it must
+            // be possible to make a BarBuilder from a Bar if either (1) the @AutoValue class has a
+            // toBuilder() or (2) there is also a setBar(Bar). Making BarBuilder from Bar is
+            // possible if Bar either has a toBuilder() method or BarBuilder has an addAll or putAll
+            // method that accepts a Bar argument.
+            boolean canMakeBarBuilder =
+                (propertyBuilder.getBuiltToBuilder() != null
+                    || propertyBuilder.getCopyAll() != null);
+            boolean needToMakeBarBuilder = (autoValueHasToBuilder || hasSetter);
+            if (needToMakeBarBuilder && !canMakeBarBuilder) {
+              errorReporter.reportError(
+                  propertyBuilder.getPropertyBuilderMethod(),
+                  "Property builder method returns %1$s but there is no way to make that type"
+                      + " from %2$s: %2$s does not have a non-static toBuilder() method that"
+                      + " returns %1$s, and %1$s does not have a method addAll or"
+                      + " putAll that accepts an argument of type %2$s",
+                  propertyBuilder.getBuilderTypeMirror(),
+                  propertyType);
+            }
+          } else if (!hasSetter) {
+            // We have neither barBuilder() nor setBar(Bar), so we should complain.
+            String setterName = settersPrefixed ? prefixWithSet(property) : property;
+            errorReporter.reportError(
+                builderType,
+                "Expected a method with this signature: %s%s %s(%s), or a %sBuilder() method",
+                builderType, typeParamsString(), setterName, propertyType, property);
+          }
+        });
+    return errorReporter.errorCount() == startErrorCount;
+  }
+
+  /** Classifies a method and update the state of this object based on what is found. */
+  private void classifyMethod(ExecutableElement method) {
+    switch (method.getParameters().size()) {
+      case 0:
+        classifyMethodNoArgs(method);
+        break;
+      case 1:
+        classifyMethodOneArg(method);
+        break;
+      default:
+        errorReporter.reportError(method, "Builder methods must have 0 or 1 parameters");
+    }
+  }
+
+  /**
+   * Classifies a method given that it has no arguments. Currently a method with no arguments can be
+   * a {@code build()} method, meaning that its return type must be the {@code @AutoValue} class; it
+   * can be a getter, with the same signature as one of the property getters in the
+   * {@code @AutoValue} class; or it can be a property builder, like {@code
+   * ImmutableList.Builder<String> foosBuilder()} for the property defined by {@code
+   * ImmutableList<String> foos()} or {@code getFoos()}.
+   */
+  private void classifyMethodNoArgs(ExecutableElement method) {
+    String methodName = method.getSimpleName().toString();
+    TypeMirror returnType = builderMethodReturnType(method);
+
+    ExecutableElement getter = getterNameToGetter.get(methodName);
+    if (getter != null) {
+      classifyGetter(method, getter);
+      return;
+    }
+
+    if (methodName.endsWith("Builder")) {
+      String property = methodName.substring(0, methodName.length() - "Builder".length());
+      if (getterToPropertyName.containsValue(property)) {
+        PropertyBuilderClassifier propertyBuilderClassifier =
+            new PropertyBuilderClassifier(
+                errorReporter,
+                typeUtils,
+                elementUtils,
+                this,
+                getterToPropertyName,
+                getterToPropertyType,
+                eclipseHack);
+        Optional<PropertyBuilder> propertyBuilder =
+            propertyBuilderClassifier.makePropertyBuilder(method, property);
+        if (propertyBuilder.isPresent()) {
+          propertyNameToPropertyBuilder.put(property, propertyBuilder.get());
+        }
+        return;
+      }
+    }
+
+    if (TYPE_EQUIVALENCE.equivalent(returnType, autoValueClass.asType())) {
+      buildMethods.add(method);
+    } else {
+      errorReporter.reportError(
+          method,
+          "Method without arguments should be a build method returning %1$s%2$s,"
+              + " or a getter method with the same name and type as a getter method of %1$s,"
+              + " or fooBuilder() where foo() or getFoo() is a getter method of %1$s",
+          autoValueClass, typeParamsString());
+    }
+  }
+
+  private void classifyGetter(ExecutableElement builderGetter, ExecutableElement originalGetter) {
+    String propertyName = getterToPropertyName.get(originalGetter);
+    TypeMirror originalGetterType = getterToPropertyType.get(originalGetter);
+    TypeMirror builderGetterType = builderMethodReturnType(builderGetter);
+    String builderGetterTypeString = TypeEncoder.encodeWithAnnotations(builderGetterType);
+    if (TYPE_EQUIVALENCE.equivalent(builderGetterType, originalGetterType)) {
+      builderGetters.put(
+          propertyName,
+          new BuilderSpec.PropertyGetter(builderGetter, builderGetterTypeString, null));
+      return;
+    }
+    Optionalish optional = Optionalish.createIfOptional(builderGetterType);
+    if (optional != null) {
+      TypeMirror containedType = optional.getContainedType(typeUtils);
+      // If the original method is int getFoo() then we allow Optional<Integer> here.
+      // boxedOriginalType is Integer, and containedType is also Integer.
+      // We don't need any special code for OptionalInt because containedType will be int then.
+      TypeMirror boxedOriginalType =
+          originalGetterType.getKind().isPrimitive()
+              ? typeUtils.boxedClass(MoreTypes.asPrimitiveType(originalGetterType)).asType()
+              : null;
+      if (TYPE_EQUIVALENCE.equivalent(containedType, originalGetterType)
+          || TYPE_EQUIVALENCE.equivalent(containedType, boxedOriginalType)) {
+        builderGetters.put(
+            propertyName,
+            new BuilderSpec.PropertyGetter(builderGetter, builderGetterTypeString, optional));
+        return;
+      }
+    }
+    errorReporter.reportError(
+        builderGetter,
+        "Method matches a property of %1$s but has return type %2$s instead of %3$s "
+            + "or an Optional wrapping of %3$s",
+        autoValueClass, builderGetterType, originalGetterType);
+  }
+
+  /**
+   * Classifies a method given that it has one argument. Currently, a method with one argument can
+   * only be a setter, meaning that it must look like {@code foo(T)} or {@code setFoo(T)}, where the
+   * {@code AutoValue} class has a property called {@code foo} of type {@code T}.
+   */
+  private void classifyMethodOneArg(ExecutableElement method) {
+    String methodName = method.getSimpleName().toString();
+    Map<String, ExecutableElement> propertyNameToGetter = getterToPropertyName.inverse();
+    String propertyName = null;
+    ExecutableElement valueGetter = propertyNameToGetter.get(methodName);
+    Multimap<String, PropertySetter> propertyNameToSetters = null;
+    if (valueGetter != null) {
+      propertyNameToSetters = propertyNameToUnprefixedSetters;
+      propertyName = methodName;
+    } else if (valueGetter == null && methodName.startsWith("set") && methodName.length() > 3) {
+      propertyNameToSetters = propertyNameToPrefixedSetters;
+      propertyName = PropertyNames.decapitalizeLikeJavaBeans(methodName.substring(3));
+      valueGetter = propertyNameToGetter.get(propertyName);
+      if (valueGetter == null) {
+        // If our property is defined by a getter called getOAuth() then it is called "OAuth"
+        // because of Introspector.decapitalize. Therefore we want Introspector.decapitalize to
+        // be used for the setter too, so that you can write setOAuth(x). Meanwhile if the property
+        // is defined by a getter called oAuth() then it is called "oAuth", but you would still
+        // expect to be able to set it using setOAuth(x). Hence the second try using a decapitalize
+        // method without the quirky two-leading-capitals rule.
+        propertyName = PropertyNames.decapitalizeNormally(methodName.substring(3));
+        valueGetter = propertyNameToGetter.get(propertyName);
+      }
+    }
+    if (valueGetter == null || propertyNameToSetters == null) {
+      // The second disjunct isn't needed but convinces control-flow checkers that
+      // propertyNameToSetters can't be null when we call put on it below.
+      errorReporter.reportError(
+          method, "Method does not correspond to a property of %s", autoValueClass);
+      checkForFailedJavaBean(method);
+      return;
+    }
+    Optional<Function<String, String>> function = getSetterFunction(valueGetter, method);
+    if (function.isPresent()) {
+      DeclaredType builderTypeMirror = MoreTypes.asDeclared(builderType.asType());
+      ExecutableType methodMirror =
+          MoreTypes.asExecutable(typeUtils.asMemberOf(builderTypeMirror, method));
+      if (TYPE_EQUIVALENCE.equivalent(methodMirror.getReturnType(), builderType.asType())) {
+        TypeMirror parameterType = Iterables.getOnlyElement(methodMirror.getParameterTypes());
+        propertyNameToSetters.put(
+            propertyName, new PropertySetter(method, parameterType, function.get()));
+      } else {
+        errorReporter.reportError(
+            method, "Setter methods must return %s%s", builderType, typeParamsString());
+      }
+    }
+  }
+
+  // A frequent source of problems is where the JavaBeans conventions have been followed for
+  // most but not all getters. Then AutoValue considers that they haven't been followed at all,
+  // so you might have a property called getFoo where you thought it was called just foo, and
+  // you might not understand why your setter called setFoo is rejected (it would have to be called
+  // setGetFoo).
+  private void checkForFailedJavaBean(ExecutableElement rejectedSetter) {
+    ImmutableSet<ExecutableElement> allGetters = getterToPropertyName.keySet();
+    ImmutableSet<ExecutableElement> prefixedGetters =
+        AutoValueProcessor.prefixedGettersIn(allGetters);
+    if (prefixedGetters.size() < allGetters.size()
+        && prefixedGetters.size() >= allGetters.size() / 2) {
+      errorReporter.reportNote(
+          rejectedSetter,
+          "This might be because you are using the getFoo() convention"
+              + " for some but not all methods. These methods don't follow the convention: %s",
+          difference(allGetters, prefixedGetters));
+    }
+  }
+
+  /**
+   * Returns an {@code Optional} describing how to convert a value from the setter's parameter type
+   * to the getter's return type, or {@code Optional.empty()} if the conversion isn't possible. An
+   * error will have been reported in the latter case. We can convert if they are already the same
+   * type, when the returned function will be the identity; or if the setter type can be copied
+   * using a method like {@code ImmutableList.copyOf} or {@code Optional.of}, when the returned
+   * function will be something like {@code s -> "Optional.of(" + s + ")"}.
+   */
+  private Optional<Function<String, String>> getSetterFunction(
+      ExecutableElement valueGetter, ExecutableElement setter) {
+    VariableElement parameterElement = Iterables.getOnlyElement(setter.getParameters());
+    boolean nullableParameter =
+        nullableAnnotationFor(parameterElement, parameterElement.asType()).isPresent();
+    TypeMirror targetType = getterToPropertyType.get(valueGetter);
+    ExecutableType finalSetter =
+        MoreTypes.asExecutable(
+            typeUtils.asMemberOf(MoreTypes.asDeclared(builderType.asType()), setter));
+    TypeMirror parameterType = finalSetter.getParameterTypes().get(0);
+    // Two types are assignable to each other if they are the same type, or if one is primitive and
+    // the other is the corresponding boxed type. There might be other cases where this is true, but
+    // we're likely to want to accept those too.
+    if (typeUtils.isAssignable(parameterType, targetType)
+        && typeUtils.isAssignable(targetType, parameterType)) {
+      if (nullableParameter) {
+        boolean nullableProperty =
+            nullableAnnotationFor(valueGetter, valueGetter.getReturnType()).isPresent();
+        if (!nullableProperty) {
+          errorReporter.reportError(
+              setter,
+              "Parameter of setter method is @Nullable but property method %s.%s() is not",
+              autoValueClass, valueGetter.getSimpleName());
+          return Optional.empty();
+        }
+      }
+      return Optional.of(s -> s);
+    }
+
+    // Parameter type is not equal to property type, but might be convertible with copyOf.
+    ImmutableList<ExecutableElement> copyOfMethods = copyOfMethods(targetType, nullableParameter);
+    if (!copyOfMethods.isEmpty()) {
+      return getConvertingSetterFunction(copyOfMethods, valueGetter, setter, parameterType);
+    }
+    errorReporter.reportError(
+        setter,
+        "Parameter type %s of setter method should be %s to match getter %s.%s",
+        parameterType, targetType, autoValueClass, valueGetter.getSimpleName());
+    return Optional.empty();
+  }
+
+  /**
+   * Returns an {@code Optional} describing how to convert a value from the setter's parameter type
+   * to the getter's return type using one of the given methods, or {@code Optional.empty()} if the
+   * conversion isn't possible. An error will have been reported in the latter case.
+   */
+  private Optional<Function<String, String>> getConvertingSetterFunction(
+      ImmutableList<ExecutableElement> copyOfMethods,
+      ExecutableElement valueGetter,
+      ExecutableElement setter,
+      TypeMirror parameterType) {
+    DeclaredType targetType = MoreTypes.asDeclared(getterToPropertyType.get(valueGetter));
+    for (ExecutableElement copyOfMethod : copyOfMethods) {
+      Optional<Function<String, String>> function =
+          getConvertingSetterFunction(copyOfMethod, targetType, parameterType);
+      if (function.isPresent()) {
+        return function;
+      }
+    }
+    String targetTypeSimpleName = targetType.asElement().getSimpleName().toString();
+    errorReporter.reportError(
+        setter,
+        "Parameter type %s of setter method should be %s to match getter %s.%s,"
+            + " or it should be a type that can be passed to %s.%s to produce %s",
+        parameterType,
+        targetType,
+        autoValueClass,
+        valueGetter.getSimpleName(),
+        targetTypeSimpleName,
+        copyOfMethods.get(0).getSimpleName(),
+        targetType);
+    return Optional.empty();
+  }
+
+  /**
+   * Returns an {@code Optional} containing a function to use {@code copyOfMethod} to copy the
+   * {@code parameterType} to the {@code targetType}, or {@code Optional.empty()} if the method
+   * can't be used. For example, we might have a property of type {@code ImmutableSet<T>} and our
+   * setter has a parameter of type {@code Set<? extends T>}. Can we use {@code ImmutableSet<E>
+   * ImmutableSet.copyOf(Collection<? extends E>)} to set the property? What about {@code
+   * ImmutableSet<E> ImmutableSet.copyOf(E[])}?
+   *
+   * <p>The example here is deliberately complicated, in that it has a type parameter of its own,
+   * presumably because the {@code @AutoValue} class is {@code Foo<T>}. One subtle point is that the
+   * builder will then be {@code Builder<T>} where this {@code T} is a <i>different</i> type
+   * variable. However, we've used {@link TypeVariables} to ensure that the {@code T} in {@code
+   * ImmutableSet<T>} is actually the one from {@code Builder<T>} instead of the original one from
+   * {@code Foo<T>}.}
+   *
+   * @param copyOfMethod the candidate method to do the copy, {@code
+   *     ImmutableSet.copyOf(Collection<? extends E>)} or {@code ImmutableSet.copyOf(E[])} in the
+   *     examples.
+   * @param targetType the type of the property to be set, {@code ImmutableSet<T>} in the example.
+   * @param parameterType the type of the setter parameter, {@code Set<? extends T>} in the example.
+   * @return a function that maps a string parameter to a method call using that parameter. For
+   *     example it might map {@code foo} to {@code ImmutableList.copyOf(foo)}.
+   */
+  private Optional<Function<String, String>> getConvertingSetterFunction(
+      ExecutableElement copyOfMethod, DeclaredType targetType, TypeMirror parameterType) {
+    // We have a parameter type, for example Set<? extends T>, and we want to know if it can be
+    // passed to the given copyOf method, which might for example be one of these methods from
+    // ImmutableSet:
+    //    public static <E> ImmutableSet<E> copyOf(Collection<? extends E> elements)
+    //    public static <E> ImmutableSet<E> copyOf(E[] elements)
+    // Additionally, if it can indeed be passed to the method, we want to know whether the result
+    // (here ImmutableSet<? extends T>) is compatible with the property to be set.
+    // We can't use Types.asMemberOf to do the substitution for us, because the methods in question
+    // are static. So even if our target type is ImmutableSet<String>, if we ask what the type of
+    // copyOf is in ImmutableSet<String> it will still tell us <T> Optional<T> (T).
+    // Instead, we do the variable substitutions ourselves.
+    if (TypeVariables.canAssignStaticMethodResult(
+        copyOfMethod, parameterType, targetType, typeUtils)) {
+      String method = TypeEncoder.encodeRaw(targetType) + "." + copyOfMethod.getSimpleName();
+      return Optional.of(s -> method + "(" + s + ")");
+    }
+    return Optional.empty();
+  }
+
+  /**
+   * Returns {@code copyOf} methods from the given type. These are static methods with a single
+   * parameter, called {@code copyOf} or {@code copyOfSorted} for Guava collection types, and called
+   * {@code of} or {@code ofNullable} for {@code Optional}. All of Guava's concrete immutable
+   * collection types have at least one such method, but we will also accept other classes with an
+   * appropriate {@code copyOf} method, such as {@link java.util.EnumSet}.
+   */
+  private ImmutableList<ExecutableElement> copyOfMethods(
+      TypeMirror targetType, boolean nullableParameter) {
+    if (!targetType.getKind().equals(TypeKind.DECLARED)) {
+      return ImmutableList.of();
+    }
+    ImmutableSet<String> copyOfNames;
+    Optionalish optionalish = Optionalish.createIfOptional(targetType);
+    if (optionalish == null) {
+      copyOfNames = ImmutableSet.of("copyOfSorted", "copyOf");
+    } else {
+      copyOfNames = ImmutableSet.of(nullableParameter ? optionalish.ofNullable() : "of");
+    }
+    TypeElement targetTypeElement = MoreElements.asType(typeUtils.asElement(targetType));
+    ImmutableList.Builder<ExecutableElement> copyOfMethods = ImmutableList.builder();
+    for (String copyOfName : copyOfNames) {
+      for (ExecutableElement method :
+          ElementFilter.methodsIn(targetTypeElement.getEnclosedElements())) {
+        if (method.getSimpleName().contentEquals(copyOfName)
+            && method.getParameters().size() == 1
+            && method.getModifiers().contains(Modifier.STATIC)) {
+          copyOfMethods.add(method);
+        }
+      }
+    }
+    return copyOfMethods.build();
+  }
+
+  /**
+   * Returns the return type of the given method from the builder. This should be the final type of
+   * the method when any bound type variables are substituted. Consider this example:
+   *
+   * <pre>{@code
+   * abstract static class ParentBuilder<B extends ParentBuilder> {
+   *   B setFoo(String s);
+   * }
+   * abstract static class ChildBuilder extends ParentBuilder<ChildBuilder> {
+   *   ...
+   * }
+   * }</pre>
+   *
+   * If the builder is {@code ChildBuilder} then the return type of {@code setFoo} is also {@code
+   * ChildBuilder}, and not {@code B} as its {@code getReturnType()} method would claim.
+   *
+   * <p>If the caller is in a version of Eclipse with <a
+   * href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=382590">this bug</a> then the {@code
+   * asMemberOf} call will fail if the method is inherited from an interface. We work around that
+   * for methods in the {@code @AutoValue} class using {@link EclipseHack#methodReturnTypes} but we
+   * don't try to do so here because it should be much less likely. You might need to change {@code
+   * ParentBuilder} from an interface to an abstract class to make it work, but you'll often need to
+   * do that anyway.
+   */
+  TypeMirror builderMethodReturnType(ExecutableElement builderMethod) {
+    DeclaredType builderTypeMirror = MoreTypes.asDeclared(builderType.asType());
+    TypeMirror methodMirror;
+    try {
+      methodMirror = typeUtils.asMemberOf(builderTypeMirror, builderMethod);
+    } catch (IllegalArgumentException e) {
+      // Presumably we've hit the Eclipse bug cited.
+      return builderMethod.getReturnType();
+    }
+    return MoreTypes.asExecutable(methodMirror).getReturnType();
+  }
+
+  private static String prefixWithSet(String propertyName) {
+    // This is not internationalizationally correct, but it corresponds to what
+    // Introspector.decapitalize does.
+    return "set" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
+  }
+
+  private String typeParamsString() {
+    return TypeSimplifier.actualTypeParametersString(autoValueClass);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/BuilderSpec.java b/value/src/main/java/com/google/auto/value/processor/BuilderSpec.java
new file mode 100644
index 0000000..613d545
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/BuilderSpec.java
@@ -0,0 +1,504 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.auto.common.MoreElements.getLocalAndInheritedMethods;
+import static com.google.auto.value.processor.AutoValueOrOneOfProcessor.hasAnnotationMirror;
+import static com.google.auto.value.processor.AutoValueOrOneOfProcessor.nullableAnnotationFor;
+import static com.google.auto.value.processor.ClassNames.AUTO_VALUE_BUILDER_NAME;
+import static com.google.common.collect.Sets.immutableEnumSet;
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+import static javax.lang.model.util.ElementFilter.typesIn;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.extension.AutoValueExtension;
+import com.google.auto.value.processor.AutoValueOrOneOfProcessor.Property;
+import com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder;
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Maps;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
+
+/**
+ * Support for AutoValue builders.
+ *
+ * @author Éamonn McManus
+ */
+class BuilderSpec {
+  private final TypeElement autoValueClass;
+  private final ProcessingEnvironment processingEnv;
+  private final ErrorReporter errorReporter;
+
+  BuilderSpec(
+      TypeElement autoValueClass,
+      ProcessingEnvironment processingEnv,
+      ErrorReporter errorReporter) {
+    this.autoValueClass = autoValueClass;
+    this.processingEnv = processingEnv;
+    this.errorReporter = errorReporter;
+  }
+
+  private static final ImmutableSet<ElementKind> CLASS_OR_INTERFACE =
+      immutableEnumSet(ElementKind.CLASS, ElementKind.INTERFACE);
+
+  /**
+   * Determines if the {@code @AutoValue} class for this instance has a correct nested
+   * {@code @AutoValue.Builder} class or interface and return a representation of it in an {@code
+   * Optional} if so.
+   */
+  Optional<Builder> getBuilder() {
+    Optional<TypeElement> builderTypeElement = Optional.empty();
+    for (TypeElement containedClass : typesIn(autoValueClass.getEnclosedElements())) {
+      if (hasAnnotationMirror(containedClass, AUTO_VALUE_BUILDER_NAME)) {
+        if (!CLASS_OR_INTERFACE.contains(containedClass.getKind())) {
+          errorReporter.reportError(
+              containedClass, "@AutoValue.Builder can only apply to a class or an interface");
+        } else if (!containedClass.getModifiers().contains(Modifier.STATIC)) {
+          errorReporter.reportError(
+              containedClass, "@AutoValue.Builder cannot be applied to a non-static class");
+        } else if (builderTypeElement.isPresent()) {
+          errorReporter.reportError(
+              containedClass,
+              "%s already has a Builder: %s",
+              autoValueClass,
+              builderTypeElement.get());
+        } else {
+          builderTypeElement = Optional.of(containedClass);
+        }
+      }
+    }
+
+    if (builderTypeElement.isPresent()) {
+      return builderFrom(builderTypeElement.get());
+    } else {
+      return Optional.empty();
+    }
+  }
+
+  /** Representation of an {@code AutoValue.Builder} class or interface. */
+  class Builder implements AutoValueExtension.BuilderContext {
+    private final TypeElement builderTypeElement;
+    private ImmutableSet<ExecutableElement> toBuilderMethods;
+    private ExecutableElement buildMethod;
+    private BuilderMethodClassifier classifier;
+
+    Builder(TypeElement builderTypeElement) {
+      this.builderTypeElement = builderTypeElement;
+    }
+
+    @Override
+    public TypeElement builderType() {
+      return builderTypeElement;
+    }
+
+    @Override
+    public Set<ExecutableElement> builderMethods() {
+      return methodsIn(autoValueClass.getEnclosedElements()).stream()
+          .filter(
+              m ->
+                  m.getParameters().isEmpty()
+                      && m.getModifiers().contains(Modifier.STATIC)
+                      && !m.getModifiers().contains(Modifier.PRIVATE)
+                      && erasedTypeIs(m.getReturnType(), builderTypeElement))
+          .collect(toSet());
+    }
+
+    @Override
+    public Optional<ExecutableElement> buildMethod() {
+      return methodsIn(builderTypeElement.getEnclosedElements()).stream()
+          .filter(
+              m ->
+                  m.getSimpleName().contentEquals("build")
+                      && !m.getModifiers().contains(Modifier.PRIVATE)
+                      && !m.getModifiers().contains(Modifier.STATIC)
+                      && m.getParameters().isEmpty()
+                      && erasedTypeIs(m.getReturnType(), autoValueClass))
+          .findFirst();
+    }
+
+    @Override
+    public ExecutableElement autoBuildMethod() {
+      return buildMethod;
+    }
+
+    @Override
+    public Map<String, Set<ExecutableElement>> setters() {
+      return Maps.transformValues(
+          classifier.propertyNameToSetters().asMap(),
+          propertySetters ->
+              propertySetters.stream().map(PropertySetter::getSetter).collect(toSet()));
+    }
+
+    @Override
+    public Map<String, ExecutableElement> propertyBuilders() {
+      return Maps.transformValues(
+          classifier.propertyNameToPropertyBuilder(), PropertyBuilder::getPropertyBuilderMethod);
+    }
+
+    private boolean erasedTypeIs(TypeMirror type, TypeElement baseType) {
+      return type.getKind().equals(TypeKind.DECLARED)
+          && MoreTypes.asDeclared(type).asElement().equals(baseType);
+    }
+
+    @Override
+    public Set<ExecutableElement> toBuilderMethods() {
+      return toBuilderMethods;
+    }
+
+    /**
+     * Finds any methods in the set that return the builder type. If the builder has type parameters
+     * {@code <A, B>}, then the return type of the method must be {@code Builder<A, B>} with the
+     * same parameter names. We enforce elsewhere that the names and bounds of the builder
+     * parameters must be the same as those of the @AutoValue class. Here's a correct example:
+     *
+     * <pre>
+     * {@code @AutoValue abstract class Foo<A extends Number, B> {
+     *   abstract int someProperty();
+     *
+     *   abstract Builder<A, B> toBuilder();
+     *
+     *   interface Builder<A extends Number, B> {...}
+     * }}
+     * </pre>
+     *
+     * <p>We currently impose that there cannot be more than one such method.
+     */
+    ImmutableSet<ExecutableElement> toBuilderMethods(
+        Types typeUtils, Set<ExecutableElement> abstractMethods) {
+
+      List<String> builderTypeParamNames =
+          builderTypeElement.getTypeParameters().stream()
+              .map(e -> e.getSimpleName().toString())
+              .collect(toList());
+
+      ImmutableSet.Builder<ExecutableElement> methods = ImmutableSet.builder();
+      for (ExecutableElement method : abstractMethods) {
+        if (builderTypeElement.equals(typeUtils.asElement(method.getReturnType()))) {
+          methods.add(method);
+          DeclaredType returnType = MoreTypes.asDeclared(method.getReturnType());
+          List<String> typeArguments =
+              returnType.getTypeArguments().stream()
+                  .filter(t -> t.getKind().equals(TypeKind.TYPEVAR))
+                  .map(t -> typeUtils.asElement(t).getSimpleName().toString())
+                  .collect(toList());
+          if (!builderTypeParamNames.equals(typeArguments)) {
+            errorReporter.reportError(
+                method,
+                "Builder converter method should return %s%s",
+                builderTypeElement,
+                TypeSimplifier.actualTypeParametersString(builderTypeElement));
+          }
+        }
+      }
+      ImmutableSet<ExecutableElement> builderMethods = methods.build();
+      if (builderMethods.size() > 1) {
+        errorReporter.reportError(
+            builderMethods.iterator().next(), "There can be at most one builder converter method");
+      }
+      this.toBuilderMethods = builderMethods;
+      return builderMethods;
+    }
+
+    void defineVars(
+        AutoValueTemplateVars vars,
+        ImmutableBiMap<ExecutableElement, String> getterToPropertyName) {
+      Iterable<ExecutableElement> builderMethods = abstractMethods(builderTypeElement);
+      boolean autoValueHasToBuilder = !toBuilderMethods.isEmpty();
+      ImmutableMap<ExecutableElement, TypeMirror> getterToPropertyType =
+          TypeVariables.rewriteReturnTypes(
+              processingEnv.getElementUtils(),
+              processingEnv.getTypeUtils(),
+              getterToPropertyName.keySet(),
+              autoValueClass,
+              builderTypeElement);
+      Optional<BuilderMethodClassifier> optionalClassifier =
+          BuilderMethodClassifier.classify(
+              builderMethods,
+              errorReporter,
+              processingEnv,
+              autoValueClass,
+              builderTypeElement,
+              getterToPropertyName,
+              getterToPropertyType,
+              autoValueHasToBuilder);
+      if (!optionalClassifier.isPresent()) {
+        return;
+      }
+      for (ExecutableElement method : methodsIn(builderTypeElement.getEnclosedElements())) {
+        if (method.getSimpleName().contentEquals("builder")
+                && method.getModifiers().contains(Modifier.STATIC)
+                && method.getAnnotationMirrors().isEmpty()) {
+          // For now we ignore methods with annotations, because for example we do want to allow
+          // Jackson's @JsonCreator.
+          errorReporter.reportWarning(
+              method, "Static builder() method should be in the containing class");
+        }
+      }
+      this.classifier = optionalClassifier.get();
+      Set<ExecutableElement> buildMethods = classifier.buildMethods();
+      if (buildMethods.size() != 1) {
+        Set<? extends Element> errorElements =
+            buildMethods.isEmpty() ? ImmutableSet.of(builderTypeElement) : buildMethods;
+        for (Element buildMethod : errorElements) {
+          errorReporter.reportError(
+              buildMethod,
+              "Builder must have a single no-argument method returning %s%s",
+              autoValueClass,
+              typeParamsString());
+        }
+        return;
+      }
+      this.buildMethod = Iterables.getOnlyElement(buildMethods);
+      vars.builderIsInterface = builderTypeElement.getKind() == ElementKind.INTERFACE;
+      vars.builderTypeName = TypeSimplifier.classNameOf(builderTypeElement);
+      vars.builderFormalTypes = TypeEncoder.formalTypeParametersString(builderTypeElement);
+      vars.builderActualTypes = TypeSimplifier.actualTypeParametersString(builderTypeElement);
+      vars.buildMethod = Optional.of(new SimpleMethod(buildMethod));
+      vars.builderGetters = classifier.builderGetters();
+      vars.builderSetters = classifier.propertyNameToSetters();
+
+      vars.builderPropertyBuilders =
+          ImmutableMap.copyOf(classifier.propertyNameToPropertyBuilder());
+
+      Set<Property> required = new LinkedHashSet<>(vars.props);
+      for (Property property : vars.props) {
+        if (property.isNullable()
+            || property.getOptional() != null
+            || vars.builderPropertyBuilders.containsKey(property.getName())) {
+          required.remove(property);
+        }
+      }
+      vars.builderRequiredProperties = ImmutableSet.copyOf(required);
+    }
+  }
+
+  /**
+   * Information about a builder property getter, referenced from the autovalue.vm template. A
+   * property called foo (defined by a method {@code T foo()} or {@code T getFoo()}) can have a
+   * getter method in the builder with the same name ({@code foo()} or {@code getFoo()}) and a
+   * return type of either {@code T} or {@code Optional<T>}. The {@code Optional<T>} form can be
+   * used to tell whether the property has been set. Here, {@code Optional<T>} can be either {@code
+   * java.util.Optional} or {@code com.google.common.base.Optional}. If {@code T} is {@code int},
+   * {@code long}, or {@code double}, then instead of {@code Optional<T>} we can have {@code
+   * OptionalInt} etc. If {@code T} is a primitive type (including these ones but also the other
+   * five) then {@code Optional<T>} can be the corresponding boxed type.
+   */
+  public static class PropertyGetter {
+    private final String access;
+    private final String type;
+    private final Optionalish optional;
+
+    /**
+     * Makes a new {@code PropertyGetter} instance.
+     *
+     * @param method the source method which this getter is implementing.
+     * @param type the type that the getter returns. This is written to take imports into account,
+     *     so it might be {@code List<String>} for example. It is either identical to the type of
+     *     the corresponding getter in the {@code @AutoValue} class, or it is an optional wrapper,
+     *     like {@code Optional<List<String>>}.
+     * @param optional a representation of the {@code Optional} type that the getter returns, if
+     *     this is an optional getter, or null otherwise. An optional getter is one that returns
+     *     {@code Optional<T>} rather than {@code T}, as explained above.
+     */
+    PropertyGetter(ExecutableElement method, String type, Optionalish optional) {
+      this.access = SimpleMethod.access(method);
+      this.type = type;
+      this.optional = optional;
+    }
+
+    public String getAccess() {
+      return access;
+    }
+
+    public String getType() {
+      return type;
+    }
+
+    public Optionalish getOptional() {
+      return optional;
+    }
+  }
+
+  /**
+   * Information about a property setter, referenced from the autovalue.vm template. A property
+   * called foo (defined by a method {@code T foo()} or {@code T getFoo()}) can have a setter method
+   * {@code foo(T)} or {@code setFoo(T)} that returns the builder type. Additionally, it can have a
+   * setter with a type that can be copied to {@code T} through a {@code copyOf} method; for example
+   * a property {@code foo} of type {@code ImmutableSet<String>} can be set with a method {@code
+   * setFoo(Collection<String> foos)}. And, if {@code T} is {@code Optional}, it can have a setter
+   * with a type that can be copied to {@code T} through {@code Optional.of}.
+   */
+  public static class PropertySetter {
+    private final ExecutableElement setter;
+    private final String access;
+    private final String name;
+    private final String parameterTypeString;
+    private final boolean primitiveParameter;
+    private final String nullableAnnotation;
+    private final Function<String, String> copyFunction;
+
+    PropertySetter(
+        ExecutableElement setter, TypeMirror parameterType, Function<String, String> copyFunction) {
+      this.setter = setter;
+      this.copyFunction = copyFunction;
+      this.access = SimpleMethod.access(setter);
+      this.name = setter.getSimpleName().toString();
+      primitiveParameter = parameterType.getKind().isPrimitive();
+      this.parameterTypeString = parameterTypeString(setter, parameterType);
+      VariableElement parameterElement = Iterables.getOnlyElement(setter.getParameters());
+      Optional<String> maybeNullable = nullableAnnotationFor(parameterElement, parameterType);
+      this.nullableAnnotation = maybeNullable.orElse("");
+    }
+
+    ExecutableElement getSetter() {
+      return setter;
+    }
+
+    private static String parameterTypeString(ExecutableElement setter, TypeMirror parameterType) {
+      if (setter.isVarArgs()) {
+        TypeMirror componentType = MoreTypes.asArray(parameterType).getComponentType();
+        // This is a bit ugly. It's OK to annotate just the component type, because if it is
+        // say `@Nullable String` then we will end up with `@Nullable String...`. Unlike the
+        // normal array case, we can't have the situation where the array itself is annotated;
+        // you can write `String @Nullable []` to mean that, but you can't write
+        // `String @Nullable ...`.
+        return TypeEncoder.encodeWithAnnotations(componentType) + "...";
+      } else {
+        return TypeEncoder.encodeWithAnnotations(parameterType);
+      }
+    }
+
+    public String getAccess() {
+      return access;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public String getParameterType() {
+      return parameterTypeString;
+    }
+
+    public boolean getPrimitiveParameter() {
+      return primitiveParameter;
+    }
+
+    public String getNullableAnnotation() {
+      return nullableAnnotation;
+    }
+
+    public String copy(AutoValueProcessor.Property property) {
+      String copy = copyFunction.apply(property.toString());
+
+      // Add a null guard only in cases where we are using copyOf and the property is @Nullable.
+      if (property.isNullable() && !copy.equals(property.toString())) {
+        copy = String.format("(%s == null ? null : %s)", property, copy);
+      }
+
+      return copy;
+    }
+  }
+
+  /**
+   * Returns a representation of the given {@code @AutoValue.Builder} class or interface. If the
+   * class or interface has abstract methods that could not be part of any builder, emits error
+   * messages and returns Optional.empty().
+   */
+  private Optional<Builder> builderFrom(TypeElement builderTypeElement) {
+
+    // We require the builder to have the same type parameters as the @AutoValue class, meaning the
+    // same names and bounds. In principle the type parameters could have different names, but that
+    // would be confusing, and our code would reject it anyway because it wouldn't consider that
+    // the return type of Foo<U> build() was really the same as the declaration of Foo<T>. This
+    // check produces a better error message in that case and similar ones.
+
+    if (!sameTypeParameters(autoValueClass, builderTypeElement)) {
+      errorReporter.reportError(
+          builderTypeElement,
+          "Type parameters of %s must have same names and bounds as type parameters of %s",
+          builderTypeElement,
+          autoValueClass);
+      return Optional.empty();
+    }
+    return Optional.of(new Builder(builderTypeElement));
+  }
+
+  private static boolean sameTypeParameters(TypeElement a, TypeElement b) {
+    int nTypeParameters = a.getTypeParameters().size();
+    if (nTypeParameters != b.getTypeParameters().size()) {
+      return false;
+    }
+    for (int i = 0; i < nTypeParameters; i++) {
+      TypeParameterElement aParam = a.getTypeParameters().get(i);
+      TypeParameterElement bParam = b.getTypeParameters().get(i);
+      if (!aParam.getSimpleName().equals(bParam.getSimpleName())) {
+        return false;
+      }
+      Set<TypeMirror> autoValueBounds = new TypeMirrorSet(aParam.getBounds());
+      Set<TypeMirror> builderBounds = new TypeMirrorSet(bParam.getBounds());
+      if (!autoValueBounds.equals(builderBounds)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Returns a set of all abstract methods in the given TypeElement or inherited from ancestors. If
+   * any of the abstract methods has a return type or parameter type that is not currently defined
+   * then this method will throw an exception that will cause us to defer processing of the current
+   * class until a later annotation-processing round.
+   */
+  private ImmutableSet<ExecutableElement> abstractMethods(TypeElement typeElement) {
+    Set<ExecutableElement> methods =
+        getLocalAndInheritedMethods(
+            typeElement, processingEnv.getTypeUtils(), processingEnv.getElementUtils());
+    ImmutableSet.Builder<ExecutableElement> abstractMethods = ImmutableSet.builder();
+    for (ExecutableElement method : methods) {
+      if (method.getModifiers().contains(Modifier.ABSTRACT)) {
+        MissingTypes.deferIfMissingTypesIn(method);
+        abstractMethods.add(method);
+      }
+    }
+    return abstractMethods.build();
+  }
+
+  private String typeParamsString() {
+    return TypeSimplifier.actualTypeParametersString(autoValueClass);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/ClassNames.java b/value/src/main/java/com/google/auto/value/processor/ClassNames.java
new file mode 100644
index 0000000..d23cfd2
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/ClassNames.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+/**
+ * Names of classes that are referenced in the processors.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+final class ClassNames {
+  private ClassNames() {}
+
+  static final String AUTO_VALUE_PACKAGE_NAME = "com.google.auto.value.";
+  static final String AUTO_ANNOTATION_NAME = AUTO_VALUE_PACKAGE_NAME + "AutoAnnotation";
+  static final String AUTO_ONE_OF_NAME = AUTO_VALUE_PACKAGE_NAME + "AutoOneOf";
+  static final String AUTO_VALUE_NAME = AUTO_VALUE_PACKAGE_NAME + "AutoValue";
+  static final String AUTO_VALUE_BUILDER_NAME = AUTO_VALUE_NAME + ".Builder";
+  static final String COPY_ANNOTATIONS_NAME = AUTO_VALUE_NAME + ".CopyAnnotations";
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/EclipseHack.java b/value/src/main/java/com/google/auto/value/processor/EclipseHack.java
new file mode 100644
index 0000000..727e328
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/EclipseHack.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static java.util.stream.Collectors.toList;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+
+/**
+ * Hacks needed to work around various bugs and incompatibilities in Eclipse's implementation of
+ * annotation processing.
+ *
+ * @author Éamonn McManus
+ */
+class EclipseHack {
+  private final Elements elementUtils;
+  private final Types typeUtils;
+
+  EclipseHack(ProcessingEnvironment processingEnv) {
+    this(processingEnv.getElementUtils(), processingEnv.getTypeUtils());
+  }
+
+  EclipseHack(Elements elementUtils, Types typeUtils) {
+    this.elementUtils = elementUtils;
+    this.typeUtils = typeUtils;
+  }
+
+  /**
+   * Returns the enclosing type of {@code type}, if {@code type} is an inner class. Otherwise
+   * returns a {@code NoType}. This is what {@link DeclaredType#getEnclosingType()} is supposed to
+   * do. However, some versions of Eclipse have a bug where, for example, asking for the enclosing
+   * type of {@code PrimitiveIterator.OfInt} will return {@code PrimitiveIterator<T, T_CONS>} rather
+   * than plain {@code PrimitiveIterator}, as if {@code OfInt} were an inner class rather than a
+   * static one. This would lead us to write a reference to {@code OfInt} as {@code
+   * PrimitiveIterator<T, T_CONS>.OfInt}, which would obviously break. We attempt to avert this by
+   * detecting that:
+   *
+   * <ul>
+   *   <li>there is an enclosing type that is a {@code DeclaredType}, which should mean that {@code
+   *       type} is an inner class;
+   *   <li>we are in the Eclipse compiler;
+   *   <li>the type arguments of the purported enclosing type are all type variables with the same
+   *       names as the corresponding type parameters.
+   * </ul>
+   *
+   * <p>If all these conditions are met, we assume we're hitting the Eclipse bug, and we return no
+   * enclosing type instead. That does mean that in the unlikely event where we really do have an
+   * inner class of an instantiation of the outer class with type arguments that happen to be type
+   * variables with the same names as the corresponding parameters, we will do the wrong thing on
+   * Eclipse. But doing the wrong thing in that case is better than doing the wrong thing in the
+   * usual case.
+   */
+  static TypeMirror getEnclosingType(DeclaredType type) {
+    TypeMirror enclosing = type.getEnclosingType();
+    if (!enclosing.getKind().equals(TypeKind.DECLARED)
+        || !enclosing.getClass().getName().contains("eclipse")) {
+      // If the class representing the enclosing type comes from the Eclipse compiler, it will be
+      // something like org.eclipse.jdt.internal.compiler.apt.model.DeclaredTypeImpl. If we're not
+      // in the Eclipse compiler then we don't expect to see "eclipse" in the name of this
+      // implementation class.
+      return enclosing;
+    }
+    DeclaredType declared = MoreTypes.asDeclared(enclosing);
+    List<? extends TypeMirror> arguments = declared.getTypeArguments();
+    if (!arguments.isEmpty()) {
+      boolean allVariables = arguments.stream().allMatch(t -> t.getKind().equals(TypeKind.TYPEVAR));
+      if (allVariables) {
+        List<Name> argumentNames =
+            arguments.stream()
+                .map(t -> MoreTypes.asTypeVariable(t).asElement().getSimpleName())
+                .collect(toList());
+        TypeElement enclosingElement = MoreTypes.asTypeElement(declared);
+        List<Name> parameterNames =
+            enclosingElement.getTypeParameters().stream()
+                .map(Element::getSimpleName)
+                .collect(toList());
+        if (argumentNames.equals(parameterNames)) {
+          // We're going to return a NoType. We don't have a Types to hand so we can't call
+          // Types.getNoType(). Instead, just keep going through outer types until we get to
+          // the outside, which will be a NoType.
+          while (enclosing.getKind().equals(TypeKind.DECLARED)) {
+            enclosing = MoreTypes.asDeclared(enclosing).getEnclosingType();
+          }
+          return enclosing;
+        }
+      }
+    }
+    return declared;
+  }
+
+  TypeMirror methodReturnType(ExecutableElement method, DeclaredType in) {
+    try {
+      TypeMirror methodMirror = typeUtils.asMemberOf(in, method);
+      return MoreTypes.asExecutable(methodMirror).getReturnType();
+    } catch (IllegalArgumentException e) {
+      return methodReturnTypes(ImmutableSet.of(method), in).get(method);
+    }
+  }
+
+  /**
+   * Returns a map containing the real return types of the given methods, knowing that they appear
+   * in the given type. This means that if the given type is say {@code StringIterator implements
+   * Iterator<String>} then we want the {@code next()} method to map to String, rather than the
+   * {@code T} that it returns as inherited from {@code Iterator<T>}. This method is in EclipseHack
+   * because if it weren't for <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=382590">this
+   * Eclipse bug</a> it would be trivial. Unfortunately, versions of Eclipse up to at least 4.5 have
+   * a bug where the {@link Types#asMemberOf} method throws IllegalArgumentException if given a
+   * method that is inherited from an interface. Fortunately, Eclipse's implementation of {@link
+   * Elements#getAllMembers} does the type substitution that {@code asMemberOf} would have done. But
+   * javac's implementation doesn't. So we try the way that would work if Eclipse weren't buggy, and
+   * only if we get IllegalArgumentException do we use {@code getAllMembers}.
+   */
+  ImmutableMap<ExecutableElement, TypeMirror> methodReturnTypes(
+      Set<ExecutableElement> methods, DeclaredType in) {
+    ImmutableMap.Builder<ExecutableElement, TypeMirror> map = ImmutableMap.builder();
+    Map<Name, ExecutableElement> noArgMethods = null;
+    for (ExecutableElement method : methods) {
+      TypeMirror returnType = null;
+      try {
+        TypeMirror methodMirror = typeUtils.asMemberOf(in, method);
+        returnType = MoreTypes.asExecutable(methodMirror).getReturnType();
+      } catch (IllegalArgumentException e) {
+        if (method.getParameters().isEmpty()) {
+          if (noArgMethods == null) {
+            noArgMethods = noArgMethodsIn(in);
+          }
+          returnType = noArgMethods.get(method.getSimpleName()).getReturnType();
+        }
+      }
+      if (returnType == null) {
+        returnType = method.getReturnType();
+      }
+      map.put(method, returnType);
+    }
+    return map.build();
+  }
+
+  /**
+   * Constructs a map from name to method of the no-argument methods in the given type. We need this
+   * because an ExecutableElement returned by {@link Elements#getAllMembers} will not compare equal
+   * to the original ExecutableElement if {@code getAllMembers} substituted type parameters, as it
+   * does in Eclipse.
+   */
+  private Map<Name, ExecutableElement> noArgMethodsIn(DeclaredType in) {
+    TypeElement autoValueType = MoreElements.asType(typeUtils.asElement(in));
+    List<ExecutableElement> allMethods =
+        ElementFilter.methodsIn(elementUtils.getAllMembers(autoValueType));
+    Map<Name, ExecutableElement> map = new LinkedHashMap<Name, ExecutableElement>();
+    for (ExecutableElement method : allMethods) {
+      if (method.getParameters().isEmpty()) {
+        map.put(method.getSimpleName(), method);
+      }
+    }
+    return map;
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/ErrorReporter.java b/value/src/main/java/com/google/auto/value/processor/ErrorReporter.java
new file mode 100644
index 0000000..e2a3d83
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/ErrorReporter.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.errorprone.annotations.FormatMethod;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.tools.Diagnostic;
+
+/**
+ * Handle error reporting for an annotation processor.
+ *
+ * @author Éamonn McManus
+ */
+class ErrorReporter {
+  private final Messager messager;
+  private int errorCount;
+
+  ErrorReporter(ProcessingEnvironment processingEnv) {
+    this.messager = processingEnv.getMessager();
+  }
+
+  /**
+   * Issue a compilation note.
+   *
+   * @param e the element to which it pertains
+   * @param format the format string for the text of the note
+   * @param args arguments for the format string
+   */
+  @FormatMethod
+  void reportNote(Element e, String format, Object... args) {
+    messager.printMessage(Diagnostic.Kind.NOTE, String.format(format, args), e);
+  }
+
+  /**
+   * Issue a compilation warning.
+   *
+   * @param e the element to which it pertains
+   * @param format the format string for the text of the warning
+   * @param args arguments for the format string
+   */
+  @FormatMethod
+  void reportWarning(Element e, String format, Object... args) {
+    messager.printMessage(Diagnostic.Kind.WARNING, String.format(format, args), e);
+  }
+
+  /**
+   * Issue a compilation error. This method does not throw an exception, since we want to continue
+   * processing and perhaps report other errors. It is a good idea to introduce a test case in
+   * CompilationTest for any new call to reportError(...) to ensure that we continue correctly after
+   * an error.
+   *
+   * @param e the element to which it pertains
+   * @param format the format string for the text of the warning
+   * @param args arguments for the format string
+   */
+  @FormatMethod
+  void reportError(Element e, String format, Object... args) {
+    messager.printMessage(Diagnostic.Kind.ERROR, String.format(format, args), e);
+    errorCount++;
+  }
+
+  /**
+   * Issue a compilation error and abandon the processing of this class. This does not prevent the
+   * processing of other classes.
+   *
+   * @param e the element to which it pertains
+   * @param format the format string for the text of the error
+   * @param args arguments for the format string
+   */
+  @FormatMethod
+  void abortWithError(Element e, String format, Object... args) {
+    reportError(e, format, args);
+    throw new AbortProcessingException();
+  }
+
+  /** The number of errors that have been output by calls to {@link #reportError}. */
+  int errorCount() {
+    return errorCount;
+  }
+
+  /** Abandon the processing of this class if any errors have been output. */
+  void abortIfAnyError() {
+    if (errorCount > 0) {
+      throw new AbortProcessingException();
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/ExtensionContext.java b/value/src/main/java/com/google/auto/value/processor/ExtensionContext.java
new file mode 100644
index 0000000..da844b0
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/ExtensionContext.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.auto.value.extension.AutoValueExtension;
+import com.google.auto.value.extension.AutoValueExtension.BuilderContext;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+
+class ExtensionContext implements AutoValueExtension.Context {
+
+  private final ProcessingEnvironment processingEnvironment;
+  private final TypeElement autoValueClass;
+  private final ImmutableMap<String, ExecutableElement> properties;
+  private final ImmutableMap<String, TypeMirror> propertyTypes;
+  private final ImmutableSet<ExecutableElement> abstractMethods;
+  private Optional<BuilderContext> builderContext = Optional.empty();
+
+  ExtensionContext(
+      ProcessingEnvironment processingEnvironment,
+      TypeElement autoValueClass,
+      ImmutableMap<String, ExecutableElement> properties,
+      ImmutableMap<ExecutableElement, TypeMirror> propertyMethodsAndTypes,
+      ImmutableSet<ExecutableElement> abstractMethods) {
+    this.processingEnvironment = processingEnvironment;
+    this.autoValueClass = autoValueClass;
+    this.properties = properties;
+    this.propertyTypes =
+        ImmutableMap.copyOf(Maps.transformValues(properties, propertyMethodsAndTypes::get));
+    this.abstractMethods = abstractMethods;
+  }
+
+  void setBuilderContext(BuilderContext builderContext) {
+    this.builderContext = Optional.of(builderContext);
+  }
+
+  @Override
+  public ProcessingEnvironment processingEnvironment() {
+    return processingEnvironment;
+  }
+
+  @Override
+  public String packageName() {
+    return TypeSimplifier.packageNameOf(autoValueClass);
+  }
+
+  @Override
+  public TypeElement autoValueClass() {
+    return autoValueClass;
+  }
+
+  @Override
+  public String finalAutoValueClassName() {
+    return AutoValueProcessor.generatedSubclassName(autoValueClass, 0);
+  }
+
+  @Override
+  public Map<String, ExecutableElement> properties() {
+    return properties;
+  }
+
+  @Override
+  public Map<String, TypeMirror> propertyTypes() {
+    return propertyTypes;
+  }
+
+  @Override
+  public Set<ExecutableElement> abstractMethods() {
+    return abstractMethods;
+  }
+
+  @Override
+  public Optional<BuilderContext> builder() {
+    return builderContext;
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/GwtCompatibility.java b/value/src/main/java/com/google/auto/value/processor/GwtCompatibility.java
new file mode 100644
index 0000000..7220754
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/GwtCompatibility.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static java.util.stream.Collectors.joining;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+
+class GwtCompatibility {
+  private final Optional<AnnotationMirror> gwtCompatibleAnnotation;
+
+  GwtCompatibility(TypeElement type) {
+    Optional<AnnotationMirror> gwtCompatibleAnnotation = Optional.empty();
+    List<? extends AnnotationMirror> annotations = type.getAnnotationMirrors();
+    for (AnnotationMirror annotation : annotations) {
+      Name name = annotation.getAnnotationType().asElement().getSimpleName();
+      if (name.contentEquals("GwtCompatible")) {
+        gwtCompatibleAnnotation = Optional.of(annotation);
+      }
+    }
+    this.gwtCompatibleAnnotation = gwtCompatibleAnnotation;
+  }
+
+  Optional<AnnotationMirror> gwtCompatibleAnnotation() {
+    return gwtCompatibleAnnotation;
+  }
+
+  // Get rid of the misconceived <? extends ExecutableElement, ? extends AnnotationValue>
+  // in the return type of getElementValues().
+  static Map<ExecutableElement, AnnotationValue> getElementValues(AnnotationMirror annotation) {
+    return Collections.<ExecutableElement, AnnotationValue>unmodifiableMap(
+        annotation.getElementValues());
+  }
+
+  String gwtCompatibleAnnotationString() {
+    if (gwtCompatibleAnnotation.isPresent()) {
+      AnnotationMirror annotation = gwtCompatibleAnnotation.get();
+      TypeElement annotationElement = (TypeElement) annotation.getAnnotationType().asElement();
+      String annotationArguments;
+      if (annotation.getElementValues().isEmpty()) {
+        annotationArguments = "";
+      } else {
+        annotationArguments =
+            getElementValues(annotation)
+                .entrySet()
+                .stream()
+                .map(e -> e.getKey().getSimpleName() + " = " + e.getValue())
+                .collect(joining(", ", "(", ")"));
+      }
+      return "@" + annotationElement.getQualifiedName() + annotationArguments;
+    } else {
+      return "";
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/GwtSerialization.java b/value/src/main/java/com/google/auto/value/processor/GwtSerialization.java
new file mode 100644
index 0000000..cf928d5
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/GwtSerialization.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.stream.Collectors.toList;
+
+import com.google.auto.value.processor.PropertyBuilderClassifier.PropertyBuilder;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Multimap;
+import com.google.escapevelocity.Template;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.zip.CRC32;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+
+/**
+ * Generates GWT serialization code for {@code @AutoValue} classes also marked
+ * {@code @GwtCompatible(serializable = true)}.
+ *
+ * @author Éamonn McManus
+ */
+class GwtSerialization {
+  private final GwtCompatibility gwtCompatibility;
+  private final ProcessingEnvironment processingEnv;
+  private final TypeElement type;
+
+  GwtSerialization(
+      GwtCompatibility gwtCompatibility, ProcessingEnvironment processingEnv, TypeElement type) {
+    this.gwtCompatibility = gwtCompatibility;
+    this.processingEnv = processingEnv;
+    this.type = type;
+  }
+
+  private boolean shouldWriteGwtSerializer() {
+    Optional<AnnotationMirror> optionalGwtCompatible = gwtCompatibility.gwtCompatibleAnnotation();
+    if (optionalGwtCompatible.isPresent()) {
+      AnnotationMirror gwtCompatible = optionalGwtCompatible.get();
+      for (Map.Entry<ExecutableElement, AnnotationValue> entry :
+          GwtCompatibility.getElementValues(gwtCompatible).entrySet()) {
+        if (entry.getKey().getSimpleName().contentEquals("serializable")
+            && entry.getValue().getValue().equals(true)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Writes the GWT serializer for the given type, if appropriate. An {@code @AutoValue} class gets
+   * a GWT serializer if it is annotated with {@code @GwtCompatible(serializable = true)}, where the
+   * {@code @GwtCompatible} annotation can come from any package.
+   *
+   * <p>If the type is com.example.Foo then the generated AutoValue subclass is
+   * com.example.AutoValue_Foo and the GWT serializer is
+   * com.example.AutoValue_Foo_CustomFieldSerializer.
+   *
+   * @param autoVars the template variables defined for this type.
+   */
+  void maybeWriteGwtSerializer(AutoValueTemplateVars autoVars) {
+    if (shouldWriteGwtSerializer()) {
+      GwtTemplateVars vars = new GwtTemplateVars();
+      vars.pkg = autoVars.pkg;
+      vars.subclass = autoVars.finalSubclass;
+      vars.formalTypes = autoVars.formalTypes;
+      vars.actualTypes = autoVars.actualTypes;
+      vars.useBuilder = !autoVars.builderTypeName.isEmpty();
+      vars.builderSetters = autoVars.builderSetters;
+      vars.builderPropertyBuilders = autoVars.builderPropertyBuilders;
+      vars.generated = autoVars.generated;
+      String className =
+          (vars.pkg.isEmpty() ? "" : vars.pkg + ".") + vars.subclass + "_CustomFieldSerializer";
+      vars.serializerClass = TypeSimplifier.simpleNameOf(className);
+      vars.props = autoVars.props.stream().map(Property::new).collect(toList());
+      vars.classHashString = computeClassHash(autoVars.props, vars.pkg);
+      String text = vars.toText();
+      text = TypeEncoder.decode(text, processingEnv, vars.pkg, type.asType());
+      writeSourceFile(className, text, type);
+    }
+  }
+
+  public static class Property {
+    private final AutoValueProcessor.Property property;
+    private final boolean isCastingUnchecked;
+
+    Property(AutoValueProcessor.Property property) {
+      this.property = property;
+      this.isCastingUnchecked = TypeSimplifier.isCastingUnchecked(property.getTypeMirror());
+    }
+
+    @Override
+    public String toString() {
+      return property.toString();
+    }
+
+    public String getGetter() {
+      return property.getGetter();
+    }
+
+    public String getType() {
+      return property.getType();
+    }
+
+    public String getName() {
+      return property.getName();
+    }
+
+    /**
+     * Returns the suffix in serializer method names for values of the given type. For example, if
+     * the type is "int" then the returned value will be "Int" because the serializer methods are
+     * called readInt and writeInt. There are methods for all primitive types and String; every
+     * other type uses readObject and writeObject.
+     */
+    public String getGwtType() {
+      TypeMirror typeMirror = property.getTypeMirror();
+      String type = typeMirror.toString();
+      if (property.getKind().isPrimitive()) {
+        return Character.toUpperCase(type.charAt(0)) + type.substring(1);
+      } else if (type.equals("java.lang.String")) {
+        return "String";
+      } else {
+        return "Object";
+      }
+    }
+
+    /**
+     * Returns a string to be inserted before the call to the readFoo() call so that the expression
+     * can be assigned to the given type. For primitive types and String, the readInt() etc methods
+     * already return the right type so the string is empty. For other types, the string is a cast
+     * like "(Foo) ".
+     */
+    public String getGwtCast() {
+      if (property.getKind().isPrimitive() || getType().equals("String")) {
+        return "";
+      } else {
+        return "(" + getType() + ") ";
+      }
+    }
+
+    public boolean isCastingUnchecked() {
+      return isCastingUnchecked;
+    }
+  }
+
+  @SuppressWarnings("unused") // some fields are only read through reflection
+  static class GwtTemplateVars extends TemplateVars {
+    /** The properties defined by the parent class's abstract methods. */
+    List<Property> props;
+
+    /**
+     * The package of the class with the {@code @AutoValue} annotation and its generated subclass.
+     */
+    String pkg;
+
+    /** The simple name of the generated subclass. */
+    String subclass;
+
+    /**
+     * The formal generic signature of the class with the {@code @AutoValue} annotation and its
+     * generated subclass. This is empty, or contains type variables with optional bounds, for
+     * example {@code <K, V extends K>}.
+     */
+    String formalTypes;
+    /**
+     * The generic signature used by the generated subclass for its superclass reference. This is
+     * empty, or contains only type variables with no bounds, for example {@code <K, V>}.
+     */
+    String actualTypes;
+
+    /** True if the {@code @AutoValue} class is constructed using a generated builder. */
+    Boolean useBuilder;
+
+    /**
+     * A multimap from property names (like foo) to the corresponding setter methods (foo or
+     * setFoo).
+     */
+    Multimap<String, BuilderSpec.PropertySetter> builderSetters;
+
+    /**
+     * A map from property names to information about the associated property builder. A property
+     * called foo (defined by a method foo() or getFoo()) can have a property builder called
+     * fooBuilder(). The type of foo must be a type that has an associated builder following certain
+     * conventions. Guava immutable types such as ImmutableList follow those conventions, as do many
+     * {@code @AutoValue} types.
+     */
+    ImmutableMap<String, PropertyBuilder> builderPropertyBuilders = ImmutableMap.of();
+
+    /** The simple name of the generated GWT serializer class. */
+    String serializerClass;
+
+    /**
+     * The encoding of the {@code Generated} class. Empty if no {@code Generated} class is
+     * available.
+     */
+    String generated;
+
+    /** A string that should change if any salient details of the serialized class change. */
+    String classHashString;
+
+    private static final Template TEMPLATE = parsedTemplateForResource("gwtserializer.vm");
+
+    @Override
+    Template parsedTemplate() {
+      return TEMPLATE;
+    }
+  }
+
+  private void writeSourceFile(String className, String text, TypeElement originatingType) {
+    try {
+      JavaFileObject sourceFile =
+          processingEnv.getFiler().createSourceFile(className, originatingType);
+      try (Writer writer = sourceFile.openWriter()) {
+        writer.write(text);
+      }
+    } catch (IOException e) {
+      processingEnv
+          .getMessager()
+          .printMessage(
+              Diagnostic.Kind.WARNING, "Could not write generated class " + className + ": " + e);
+      // A warning rather than an error for the reason explained in
+      // AutoValueOrOneOfProcessor.writeSourceFile.
+    }
+  }
+
+  // Compute a hash that is guaranteed to change if the names, types, or order of the fields
+  // change. We use TypeEncoder so that we can get a defined string for types, since
+  // TypeMirror.toString() isn't guaranteed to remain the same.
+  private String computeClassHash(Iterable<AutoValueProcessor.Property> props, String pkg) {
+    CRC32 crc = new CRC32();
+    String encodedType = TypeEncoder.encode(type.asType()) + ":";
+    String decodedType = TypeEncoder.decode(encodedType, processingEnv, "", null);
+    if (!decodedType.startsWith(pkg)) {
+      // This is for compatibility with the way an earlier version did things. Preserving hash
+      // codes probably isn't vital, since client and server should be in sync.
+      decodedType = pkg + "." + decodedType;
+    }
+    crc.update(decodedType.getBytes(UTF_8));
+    for (AutoValueProcessor.Property prop : props) {
+      String encodedProp = prop + ":" + TypeEncoder.encode(prop.getTypeMirror()) + ";";
+      String decodedProp = TypeEncoder.decode(encodedProp, processingEnv, pkg, null);
+      crc.update(decodedProp.getBytes(UTF_8));
+    }
+    return String.format("%08x", crc.getValue());
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/JavaScanner.java b/value/src/main/java/com/google/auto/value/processor/JavaScanner.java
new file mode 100644
index 0000000..1a32180
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/JavaScanner.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+/**
+ * A simplistic Java scanner. This scanner returns a sequence of tokens that can be used to
+ * reconstruct the source code. Since the source code is coming from a string, the scanner in fact
+ * just returns token boundaries rather than the tokens themselves.
+ *
+ * <p>We are not dealing with arbitrary user code so we can assume there are no exotic things like
+ * tabs or Unicode escapes that resolve into quotes. The purpose of the scanner here is to return a
+ * sequence of offsets that split the string up in a way that allows us to work with spaces without
+ * having to worry whether they are inside strings or comments. The particular properties we use are
+ * that every string and character literal and every comment is a single token; every newline plus
+ * all following indentation is a single token; and every other string of consecutive spaces outside
+ * a comment or literal is a single token. That means that we can safely compress a token that
+ * starts with a space into a single space, without falsely removing indentation or changing the
+ * contents of strings.
+ *
+ * <p>In addition to real Java syntax, this scanner recognizes tokens of the form {@code `text`},
+ * which are used in the templates to wrap fully-qualified type names, so that they can be extracted
+ * and replaced by imported names if possible.
+ *
+ * @author Éamonn McManus
+ */
+class JavaScanner {
+  private final String s;
+
+  JavaScanner(String s) {
+    this.s = s.endsWith("\n") ? s : (s + '\n');
+    // This allows us to avoid checking for the end of the string in most cases.
+  }
+
+  /**
+   * Returns the string being scanned, which is either the original input string or that string plus
+   * a newline.
+   */
+  String string() {
+    return s;
+  }
+
+  /** Returns the position at which this token ends and the next token begins. */
+  int tokenEnd(int start) {
+    if (start >= s.length()) {
+      return s.length();
+    }
+    switch (s.charAt(start)) {
+      case ' ':
+      case '\n':
+        return spaceEnd(start);
+      case '/':
+        if (s.charAt(start + 1) == '*') {
+          return blockCommentEnd(start);
+        } else if (s.charAt(start + 1) == '/') {
+          return lineCommentEnd(start);
+        } else {
+          return start + 1;
+        }
+      case '\'':
+      case '"':
+      case '`':
+        return quoteEnd(start);
+      default:
+        // Every other character is considered to be its own token.
+        return start + 1;
+    }
+  }
+
+  private int spaceEnd(int start) {
+    assert s.charAt(start) == ' ' || s.charAt(start) == '\n';
+    int i;
+    for (i = start + 1; i < s.length() && s.charAt(i) == ' '; i++) {}
+    return i;
+  }
+
+  private int blockCommentEnd(int start) {
+    assert s.charAt(start) == '/' && s.charAt(start + 1) == '*';
+    int i;
+    for (i = start + 2; s.charAt(i) != '*' || s.charAt(i + 1) != '/'; i++) {}
+    return i + 2;
+  }
+
+  private int lineCommentEnd(int start) {
+    assert s.charAt(start) == '/' && s.charAt(start + 1) == '/';
+    int end = s.indexOf('\n', start + 2);
+    assert end > 0;
+    return end;
+  }
+
+  private int quoteEnd(int start) {
+    char quote = s.charAt(start);
+    assert quote == '\'' || quote == '"' || quote == '`';
+    int i;
+    for (i = start + 1; s.charAt(i) != quote; i++) {
+      if (s.charAt(i) == '\\') {
+        i++;
+      }
+    }
+    return i + 1;
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/MissingTypes.java b/value/src/main/java/com/google/auto/value/processor/MissingTypes.java
new file mode 100644
index 0000000..ea8126b
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/MissingTypes.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import java.util.List;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ErrorType;
+import javax.lang.model.type.IntersectionType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.SimpleTypeVisitor8;
+
+/**
+ * Handling of undefined types. When we see an undefined type, it might genuinely be undefined, or
+ * it might be a type whose source code will be generated later on as part of the same compilation.
+ * If we encounter an undefined type in a place where we need to know the type, we throw {@link
+ * MissingTypeException}. We then catch that and defer processing for the current class until the
+ * next annotation-processing "round". If the missing class has been generated in the meanwhile, we
+ * may now be able to complete processing. After a round has completed without generating any new
+ * source code, if there are still missing types then we report an error.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+final class MissingTypes {
+  private MissingTypes() {}
+
+  /**
+   * Exception thrown in the specific case where processing of a class was abandoned because it
+   * required types that the class references to be present and they were not. This case is handled
+   * specially because it is possible that those types might be generated later during annotation
+   * processing, so we should reattempt the processing of the class in a later annotation processing
+   * round.
+   */
+  @SuppressWarnings("serial")
+  static class MissingTypeException extends RuntimeException {
+    MissingTypeException(ErrorType missingType) {
+      // Although it is not specified as such, in practice ErrorType.toString() is the type name
+      // that appeared in the source code. Showing it here can help in debugging issues with
+      // deferral.
+      super(missingType == null ? null : missingType.toString());
+    }
+  }
+
+  /**
+   * Check that the return type and parameter types of the given method are all defined, and arrange
+   * to defer processing until the next round if not.
+   *
+   * @throws MissingTypeException if the return type or a parameter type of the given method is
+   *     undefined
+   */
+  static void deferIfMissingTypesIn(ExecutableElement method) {
+    MISSING_TYPE_VISITOR.check(method.getReturnType());
+    for (VariableElement param : method.getParameters()) {
+      MISSING_TYPE_VISITOR.check(param.asType());
+    }
+  }
+
+  private static final MissingTypeVisitor MISSING_TYPE_VISITOR = new MissingTypeVisitor();
+
+  private static class MissingTypeVisitor extends SimpleTypeVisitor8<Void, TypeMirrorSet> {
+    // Avoid infinite recursion for a type like `Enum<E extends Enum<E>>` by remembering types that
+    // we have already seen on this visit. Recursion has to go through a declared type, such as Enum
+    // in this example, so in principle it should be enough to check only in visitDeclared. However
+    // Eclipse has a quirk where the second E in `Enum<E extends Enum<E>>` is not the same as the
+    // first, and if you ask for its bounds you will get another `Enum<E>` with a third E. So we
+    // also check in visitTypeVariable. TypeMirrorSet does consider that all these E variables are
+    // the same so infinite recursion is avoided.
+    void check(TypeMirror type) {
+      type.accept(this, new TypeMirrorSet());
+    }
+
+    @Override
+    public Void visitError(ErrorType t, TypeMirrorSet visiting) {
+      throw new MissingTypeException(t);
+    }
+
+    @Override
+    public Void visitArray(ArrayType t, TypeMirrorSet visiting) {
+      return t.getComponentType().accept(this, visiting);
+    }
+
+    @Override
+    public Void visitDeclared(DeclaredType t, TypeMirrorSet visiting) {
+      if (visiting.add(t)) {
+        visitAll(t.getTypeArguments(), visiting);
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitTypeVariable(TypeVariable t, TypeMirrorSet visiting) {
+      if (visiting.add(t)) {
+        t.getLowerBound().accept(this, visiting);
+        t.getUpperBound().accept(this, visiting);
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitWildcard(WildcardType t, TypeMirrorSet visiting) {
+      if (t.getSuperBound() != null) {
+        t.getSuperBound().accept(this, visiting);
+      }
+      if (t.getExtendsBound() != null) {
+        t.getExtendsBound().accept(this, visiting);
+      }
+      return null;
+    }
+
+    @Override
+    public Void visitIntersection(IntersectionType t, TypeMirrorSet visiting) {
+      return visitAll(t.getBounds(), visiting);
+    }
+
+    private Void visitAll(List<? extends TypeMirror> types, TypeMirrorSet visiting) {
+      for (TypeMirror type : types) {
+        type.accept(this, visiting);
+      }
+      return null;
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/Optionalish.java b/value/src/main/java/com/google/auto/value/processor/Optionalish.java
new file mode 100644
index 0000000..e4a24e8
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/Optionalish.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Verify;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.List;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
+
+/**
+ * A wrapper for properties of Optional-like classes. This can be com.google.common.base.Optional,
+ * or any of Optional, OptionalDouble, OptionalInt, OptionalLong in java.util.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+public class Optionalish {
+  private static final ImmutableSet<String> OPTIONAL_CLASS_NAMES =
+      ImmutableSet.of(
+          "com.".concat("google.common.base.Optional"), // subterfuge to foil shading
+          "java.util.Optional",
+          "java.util.OptionalDouble",
+          "java.util.OptionalInt",
+          "java.util.OptionalLong");
+
+  private final DeclaredType optionalType;
+  private final String className;
+
+  private Optionalish(DeclaredType optionalType) {
+    this.optionalType = optionalType;
+    this.className = MoreElements.asType(optionalType.asElement()).getQualifiedName().toString();
+  }
+
+  /**
+   * Returns an instance wrapping the given TypeMirror, or null if it is not any kind of Optional.
+   *
+   * @param type the TypeMirror for the original optional type, for example {@code
+   *     Optional<String>}.
+   */
+  static Optionalish createIfOptional(TypeMirror type) {
+    if (isOptional(type)) {
+      return new Optionalish(MoreTypes.asDeclared(type));
+    } else {
+      return null;
+    }
+  }
+
+  static boolean isOptional(TypeMirror type) {
+    if (type.getKind() != TypeKind.DECLARED) {
+      return false;
+    }
+    DeclaredType declaredType = MoreTypes.asDeclared(type);
+    TypeElement typeElement = MoreElements.asType(declaredType.asElement());
+    return OPTIONAL_CLASS_NAMES.contains(typeElement.getQualifiedName().toString())
+        && typeElement.getTypeParameters().size() == declaredType.getTypeArguments().size();
+  }
+
+  /**
+   * Returns a string representing the raw type of this Optional. This will typically be just {@code
+   * "Optional"}, but it might be {@code "OptionalInt"} or {@code "java.util.Optional"} for example.
+   */
+  public String getRawType() {
+    return TypeEncoder.encodeRaw(optionalType);
+  }
+
+  /**
+   * Returns a string representing the method call to obtain the empty version of this Optional.
+   * This will be something like {@code "Optional.empty()"} or possibly {@code
+   * "java.util.Optional.empty()"}. It does not have a final semicolon.
+   *
+   * <p>This method is public so that it can be referenced as {@code p.optional.empty} from
+   * templates.
+   */
+  public String getEmpty() {
+    String empty = className.startsWith("java.util.") ? ".empty()" : ".absent()";
+    return TypeEncoder.encodeRaw(optionalType) + empty;
+  }
+
+  TypeMirror getContainedType(Types typeUtils) {
+    List<? extends TypeMirror> typeArguments = optionalType.getTypeArguments();
+    switch (typeArguments.size()) {
+      case 1:
+        return typeArguments.get(0);
+      case 0:
+        return getContainedPrimitiveType(typeUtils);
+      default:
+        throw new AssertionError("Wrong number of type arguments: " + optionalType);
+    }
+  }
+
+  String ofNullable() {
+    return className.equals("java.util.Optional") ? "ofNullable" : "fromNullable";
+  }
+
+  private static final ImmutableMap<String, TypeKind> PRIMITIVE_TYPE_KINDS =
+      ImmutableMap.of(
+          "OptionalDouble", TypeKind.DOUBLE,
+          "OptionalInt", TypeKind.INT,
+          "OptionalLong", TypeKind.LONG);
+
+  private TypeMirror getContainedPrimitiveType(Types typeUtils) {
+    String simpleName = optionalType.asElement().getSimpleName().toString();
+    TypeKind typeKind = PRIMITIVE_TYPE_KINDS.get(simpleName);
+    Verify.verifyNotNull(typeKind, "Could not get contained type of %s", optionalType);
+    return typeUtils.getPrimitiveType(typeKind);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/PropertyBuilderClassifier.java b/value/src/main/java/com/google/auto/value/processor/PropertyBuilderClassifier.java
new file mode 100644
index 0000000..dafb582
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/PropertyBuilderClassifier.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.collect.ImmutableBiMap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ExecutableType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+
+/**
+ * Classifies methods inside builder types that return builders for properties. For example, if
+ * {@code @AutoValue} class Foo has a method {@code ImmutableList<String> bar()} then Foo.Builder
+ * can have a method {@code ImmutableList.Builder<String> barBuilder()}. This class checks that a
+ * method like {@code barBuilder()} follows the rules, and if so constructs a {@link
+ * PropertyBuilder} instance with information about {@code barBuilder}.
+ *
+ * @author Éamonn McManus
+ */
+class PropertyBuilderClassifier {
+  private final ErrorReporter errorReporter;
+  private final Types typeUtils;
+  private final Elements elementUtils;
+  private final BuilderMethodClassifier builderMethodClassifier;
+  private final ImmutableBiMap<ExecutableElement, String> getterToPropertyName;
+  private final ImmutableMap<ExecutableElement, TypeMirror> getterToPropertyType;
+  private final EclipseHack eclipseHack;
+
+  PropertyBuilderClassifier(
+      ErrorReporter errorReporter,
+      Types typeUtils,
+      Elements elementUtils,
+      BuilderMethodClassifier builderMethodClassifier,
+      ImmutableBiMap<ExecutableElement, String> getterToPropertyName,
+      ImmutableMap<ExecutableElement, TypeMirror> getterToPropertyType,
+      EclipseHack eclipseHack) {
+    this.errorReporter = errorReporter;
+    this.typeUtils = typeUtils;
+    this.elementUtils = elementUtils;
+    this.builderMethodClassifier = builderMethodClassifier;
+    this.getterToPropertyName = getterToPropertyName;
+    this.getterToPropertyType = getterToPropertyType;
+    this.eclipseHack = eclipseHack;
+  }
+
+  /**
+   * Information about a property builder, referenced from the autovalue.vm template. A property
+   * called bar (defined by a method bar() or getBar()) can have a property builder called
+   * barBuilder(). For example, if {@code bar()} returns {@code ImmutableSet<String>} then {@code
+   * barBuilder()} might return {@code ImmutableSet.Builder<String>}.
+   */
+  public static class PropertyBuilder {
+    private final ExecutableElement propertyBuilderMethod;
+    private final String name;
+    private final String builderType;
+    private final TypeMirror builderTypeMirror;
+    private final String initializer;
+    private final String beforeInitDefault;
+    private final String initDefault;
+    private final String builtToBuilder;
+    private final String copyAll;
+
+    PropertyBuilder(
+        ExecutableElement propertyBuilderMethod,
+        String builderType,
+        TypeMirror builderTypeMirror,
+        String initializer,
+        String beforeInitDefault,
+        String initDefault,
+        String builtToBuilder,
+        String copyAll) {
+      this.propertyBuilderMethod = propertyBuilderMethod;
+      this.name = propertyBuilderMethod.getSimpleName() + "$";
+      this.builderType = builderType;
+      this.builderTypeMirror = builderTypeMirror;
+      this.initializer = initializer;
+      this.beforeInitDefault = beforeInitDefault;
+      this.initDefault = initDefault;
+      this.builtToBuilder = builtToBuilder;
+      this.copyAll = copyAll;
+    }
+
+    /** The property builder method, for example {@code barBuilder()}. */
+    public ExecutableElement getPropertyBuilderMethod() {
+      return propertyBuilderMethod;
+    }
+
+    public String getAccess() {
+      return SimpleMethod.access(propertyBuilderMethod);
+    }
+
+    /** The name of the field to hold this builder. */
+    public String getName() {
+      return name;
+    }
+
+    /** The type of the builder, for example {@code ImmutableSet.Builder<String>}. */
+    public String getBuilderType() {
+      return builderType;
+    }
+
+    TypeMirror getBuilderTypeMirror() {
+      return builderTypeMirror;
+    }
+
+    /** An initializer for the builder field, for example {@code ImmutableSet.builder()}. */
+    public String getInitializer() {
+      return initializer;
+    }
+
+    /**
+     * An empty string, or a complete statement to be included before the expression returned by
+     * {@link #getInitDefault()}.
+     */
+    public String getBeforeInitDefault() {
+      return beforeInitDefault;
+    }
+
+    /**
+     * An expression to return a default instance of the type that this builder builds. For example,
+     * if this is an {@code ImmutableList<String>} then the method {@code ImmutableList.of()} will
+     * correctly return an empty {@code ImmutableList<String>}, assuming the appropriate context for
+     * type inference. The expression here can assume that the statement from {@link
+     * #getBeforeInitDefault} has preceded it.
+     */
+    public String getInitDefault() {
+      return initDefault;
+    }
+
+    /**
+     * A method to convert the built type back into a builder. Unfortunately Guava collections don't
+     * have this (you can't say {@code myImmutableMap.toBuilder()}), but for other types such as
+     * {@code @AutoValue} types this is {@code toBuilder()}.
+     */
+    public String getBuiltToBuilder() {
+      return builtToBuilder;
+    }
+
+    /**
+     * The method to copy another collection into this builder. It is {@code addAll} for
+     * one-dimensional collections like {@code ImmutableList} and {@code ImmutableSet}, and it is
+     * {@code putAll} for two-dimensional collections like {@code ImmutableMap} and {@code
+     * ImmutableTable}.
+     */
+    public String getCopyAll() {
+      return copyAll;
+    }
+  }
+
+  // Our @AutoValue class `Foo` has a property `Bar bar()` or `Bar getBar()` and we've encountered
+  // a builder method like `BarBuilder barBuilder()`. Here `BarBuilder` can have any name (its name
+  // doesn't have to be the name of `Bar` with `Builder` stuck on the end), but `barBuilder()` does
+  // have to be the name of the property with `Builder` stuck on the end. The requirements for the
+  // `BarBuilder` type are:
+  // (1) It must have an instance method called `build()` that returns `Bar`. If the type of
+  //     `bar()` is `Bar<String>` then the type of `build()` must be `Bar<String>`.
+  // (2) `BarBuilder` must have a public no-arg constructor, or `Bar` must have a static method
+  //     `naturalOrder(), `builder()`, or `newBuilder()` that returns `BarBuilder`. The
+  //     `naturalOrder()` case is specifically for ImmutableSortedSet and ImmutableSortedMap.
+  // (3) If `Foo` has a `toBuilder()` method, or if we have both `barBuilder()` and `setBar(Bar)`
+  //     methods, then `Bar` must have an instance method `BarBuilder toBuilder()`, or `BarBuilder`
+  //     must have an `addAll` or `putAll` method that accepts an argument of type `Bar`.
+  //
+  // This method outputs an error and returns Optional.empty() if the barBuilder() method has a
+  // problem.
+  Optional<PropertyBuilder> makePropertyBuilder(ExecutableElement method, String property) {
+    TypeMirror barBuilderTypeMirror = builderMethodClassifier.builderMethodReturnType(method);
+    if (barBuilderTypeMirror.getKind() != TypeKind.DECLARED) {
+      errorReporter.reportError(
+          method,
+          "Method looks like a property builder, but its return type is not a class or interface");
+      return Optional.empty();
+    }
+    DeclaredType barBuilderDeclaredType = MoreTypes.asDeclared(barBuilderTypeMirror);
+    TypeElement barBuilderTypeElement = MoreTypes.asTypeElement(barBuilderTypeMirror);
+    Map<String, ExecutableElement> barBuilderNoArgMethods = noArgMethodsOf(barBuilderTypeElement);
+
+    ExecutableElement barGetter = getterToPropertyName.inverse().get(property);
+    TypeMirror barTypeMirror = getterToPropertyType.get(barGetter);
+    if (barTypeMirror.getKind() != TypeKind.DECLARED) {
+      errorReporter.reportError(
+          method,
+          "Method looks like a property builder, but the type of property %s is not a class or"
+              + " interface",
+          property);
+      return Optional.empty();
+    }
+    if (isNullable(barGetter)) {
+      errorReporter.reportError(
+          barGetter,
+          "Property %s has a property builder so it cannot be @Nullable",
+          property);
+    }
+    TypeElement barTypeElement = MoreTypes.asTypeElement(barTypeMirror);
+    Map<String, ExecutableElement> barNoArgMethods = noArgMethodsOf(barTypeElement);
+
+    // Condition (1), must have build() method returning Bar.
+    ExecutableElement build = barBuilderNoArgMethods.get("build");
+    if (build == null || build.getModifiers().contains(Modifier.STATIC)) {
+      errorReporter.reportError(
+          method,
+          "Method looks like a property builder, but it returns %s which does not have a"
+              + " non-static build() method",
+          barBuilderTypeElement);
+      return Optional.empty();
+    }
+
+    // We've determined that `BarBuilder` has a method `build()`. But it must return `Bar`.
+    // And if the type of `bar()` is Bar<String> then `BarBuilder.build()` must return Bar<String>.
+    TypeMirror buildType = eclipseHack.methodReturnType(build, barBuilderDeclaredType);
+    if (!MoreTypes.equivalence().equivalent(barTypeMirror, buildType)) {
+      errorReporter.reportError(
+          method,
+          "Property builder for %s has type %s whose build() method returns %s instead of %s",
+          property,
+          barBuilderTypeElement,
+          buildType,
+          barTypeMirror);
+      return Optional.empty();
+    }
+
+    Optional<ExecutableElement> maybeBuilderMaker =
+        builderMaker(barNoArgMethods, barBuilderTypeElement);
+    if (!maybeBuilderMaker.isPresent()) {
+      errorReporter.reportError(
+          method,
+          "Method looks like a property builder, but its type %s does not have a public"
+              + " constructor and %s does not have a static builder() or newBuilder() method that"
+              + " returns %s",
+          barBuilderTypeElement,
+          barTypeElement,
+          barBuilderTypeElement);
+      return Optional.empty();
+    }
+    ExecutableElement builderMaker = maybeBuilderMaker.get();
+
+    String barBuilderType = TypeEncoder.encodeWithAnnotations(barBuilderTypeMirror);
+    String rawBarType = TypeEncoder.encodeRaw(barTypeMirror);
+    String initializer =
+        (builderMaker.getKind() == ElementKind.CONSTRUCTOR)
+            ? "new " + barBuilderType + "()"
+            : rawBarType + "." + builderMaker.getSimpleName() + "()";
+    String builtToBuilder = null;
+    String copyAll = null;
+    ExecutableElement toBuilder = barNoArgMethods.get("toBuilder");
+    if (toBuilder != null
+        && !toBuilder.getModifiers().contains(Modifier.STATIC)
+        && typeUtils.isAssignable(
+            typeUtils.erasure(toBuilder.getReturnType()),
+            typeUtils.erasure(barBuilderTypeMirror))) {
+      builtToBuilder = toBuilder.getSimpleName().toString();
+    } else {
+      Optional<ExecutableElement> maybeCopyAll =
+          addAllPutAll(barBuilderTypeElement, barBuilderDeclaredType, barTypeMirror);
+      if (maybeCopyAll.isPresent()) {
+        copyAll = maybeCopyAll.get().getSimpleName().toString();
+      }
+    }
+    ExecutableElement barOf = barNoArgMethods.get("of");
+    boolean hasOf = (barOf != null && barOf.getModifiers().contains(Modifier.STATIC));
+    // An expression (initDefault) to make a default one of these, plus optionally a statement
+    // (beforeInitDefault) that prepares the expression. For a collection, beforeInitDefault is
+    // empty and initDefault is (e.g.) `ImmutableList.of()`. For a nested value type,
+    // beforeInitDefault is (e.g.)
+    //   `NestedAutoValueType.Builder foo$builder = NestedAutoValueType.builder();`
+    // and initDefault is `foo$builder.build();`. The reason for the separate statement is to
+    // exploit type inference rather than having to write `NestedAutoValueType.<Bar>build();`.
+    String beforeInitDefault;
+    String initDefault;
+    if (hasOf) {
+      beforeInitDefault = "";
+      initDefault = rawBarType + ".of()";
+    } else {
+      String localBuilder = property + "$builder";
+      beforeInitDefault = barBuilderType + " " + localBuilder + " = " + initializer + ";";
+      initDefault = localBuilder + ".build()";
+    }
+
+    PropertyBuilder propertyBuilder =
+        new PropertyBuilder(
+            method,
+            barBuilderType,
+            barBuilderTypeMirror,
+            initializer,
+            beforeInitDefault,
+            initDefault,
+            builtToBuilder,
+            copyAll);
+    return Optional.of(propertyBuilder);
+  }
+
+  private static final ImmutableSet<String> BUILDER_METHOD_NAMES =
+      ImmutableSet.of("naturalOrder", "builder", "newBuilder");
+
+  // (2) `BarBuilder must have a public no-arg constructor, or `Bar` must have a visible static
+  //      method `naturalOrder(), `builder()`, or `newBuilder()` that returns `BarBuilder`.
+  private Optional<ExecutableElement> builderMaker(
+      Map<String, ExecutableElement> barNoArgMethods, TypeElement barBuilderTypeElement) {
+    for (String builderMethodName : BUILDER_METHOD_NAMES) {
+      ExecutableElement method = barNoArgMethods.get(builderMethodName);
+      if (method != null
+          && method.getModifiers().contains(Modifier.STATIC)
+          && typeUtils.isSameType(
+              typeUtils.erasure(method.getReturnType()),
+              typeUtils.erasure(barBuilderTypeElement.asType()))) {
+        // TODO(emcmanus): check visibility. We don't want to require public for @AutoValue
+        // builders. By not checking visibility we risk accepting something as a builder maker
+        // and then failing when the generated code tries to call Bar.builder(). But the risk
+        // seems small.
+        return Optional.of(method);
+      }
+    }
+    return ElementFilter.constructorsIn(barBuilderTypeElement.getEnclosedElements())
+        .stream()
+        .filter(c -> c.getParameters().isEmpty())
+        .filter(c -> c.getModifiers().contains(Modifier.PUBLIC))
+        .findFirst();
+  }
+
+  private Map<String, ExecutableElement> noArgMethodsOf(TypeElement type) {
+    // Can't easily use ImmutableMap here because getAllMembers could return more than one method
+    // with the same name.
+    Map<String, ExecutableElement> methods = new LinkedHashMap<>();
+    for (ExecutableElement method : ElementFilter.methodsIn(elementUtils.getAllMembers(type))) {
+      if (method.getParameters().isEmpty() && !isStaticInterfaceMethodNotIn(method, type)) {
+        methods.put(method.getSimpleName().toString(), method);
+      }
+    }
+    return methods;
+  }
+
+  // Work around an Eclipse compiler bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=547185
+  // The result of Elements.getAllMembers includes static methods declared in superinterfaces.
+  // That's wrong because those aren't inherited. So this method checks whether the given method is
+  // a static interface method not in the given type.
+  private static boolean isStaticInterfaceMethodNotIn(ExecutableElement method, TypeElement type) {
+    return method.getModifiers().contains(Modifier.STATIC)
+        && !method.getEnclosingElement().equals(type)
+        && method.getEnclosingElement().getKind().equals(ElementKind.INTERFACE);
+  }
+
+  private static final ImmutableSet<String> ADD_ALL_PUT_ALL = ImmutableSet.of("addAll", "putAll");
+
+  // We have `Bar bar()` and `Foo.Builder toBuilder()` in the @AutoValue type Foo, and we have
+  // `BarBuilder barBuilder()` in Foo.Builder. That means that we need to be able to make a
+  // `BarBuilder` from a `Bar` as part of the implementation of `Foo.toBuilder()`. We can do that
+  // if `Bar` has a method `BarBuilder toBuilder()`, but what if it doesn't? For example, Guava's
+  // `ImmutableList` doesn't have a method `ImmutableList.Builder toBuilder()`. So we also allow it
+  // to work if `BarBuilder` has a method `addAll(T)` or `putAll(T)`, where `Bar` is assignable to
+  // `T`. `ImmutableList.Builder<E>` does have a method `addAll(Iterable<? extends E>)` and
+  // `ImmutableList<E>` is assignable to `Iterable<? extends E>`, so that works.
+  private Optional<ExecutableElement> addAllPutAll(
+      TypeElement barBuilderTypeElement,
+      DeclaredType barBuilderDeclaredType,
+      TypeMirror barTypeMirror) {
+    return MoreElements.getLocalAndInheritedMethods(barBuilderTypeElement, typeUtils, elementUtils)
+        .stream()
+        .filter(
+            method ->
+                ADD_ALL_PUT_ALL.contains(method.getSimpleName().toString())
+                    && method.getParameters().size() == 1)
+        .filter(
+            method -> {
+              ExecutableType methodMirror =
+                  MoreTypes.asExecutable(typeUtils.asMemberOf(barBuilderDeclaredType, method));
+              return typeUtils.isAssignable(barTypeMirror, methodMirror.getParameterTypes().get(0));
+            })
+        .findFirst();
+  }
+
+  private static boolean isNullable(ExecutableElement getter) {
+    List<List<? extends AnnotationMirror>> annotationLists =
+        ImmutableList.of(
+            getter.getAnnotationMirrors(), getter.getReturnType().getAnnotationMirrors());
+    for (List<? extends AnnotationMirror> annotations : annotationLists) {
+      for (AnnotationMirror annotation : annotations) {
+        if (annotation.getAnnotationType().asElement().getSimpleName().contentEquals("Nullable")) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/PropertyNames.java b/value/src/main/java/com/google/auto/value/processor/PropertyNames.java
new file mode 100644
index 0000000..62892d2
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/PropertyNames.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.common.base.Strings;
+
+/** Helper methods to create property names. */
+class PropertyNames {
+  /**
+   * Returns the {@code propertyName} with its first character in lower case, but leaves it intact
+   * if it starts with two capitals.
+   *
+   * <p>For consistency with JavaBeans, a getter called {@code getHTMLPage()} defines a property
+   * called {@code HTMLPage}. The <a
+   * href="https://docs.oracle.com/javase/8/docs/api/java/beans/Introspector.html#decapitalize-java.lang.String-">
+   * rule</a> is: the name of the property is the part after {@code get} or {@code
+   * is}, with the first letter lowercased <i>unless</i> the first two letters are uppercase. This
+   * works well for the {@code HTMLPage} example, but in these more enlightened times we use {@code
+   * HtmlPage} anyway, so the special behaviour is not useful, and of course it behaves poorly with
+   * examples like {@code OAuth}. Nevertheless, we preserve it for compatibility.
+   */
+  static String decapitalizeLikeJavaBeans(String propertyName) {
+    if (propertyName != null
+        && propertyName.length() >= 2
+        && Character.isUpperCase(propertyName.charAt(0))
+        && Character.isUpperCase(propertyName.charAt(1))) {
+      return propertyName;
+    }
+    return decapitalizeNormally(propertyName);
+  }
+
+  /**
+   * Returns the {@code propertyName} with its first character in lower case.
+   */
+  static String decapitalizeNormally(String propertyName) {
+    if (Strings.isNullOrEmpty(propertyName)) {
+      return propertyName;
+    }
+    return Character.toLowerCase(propertyName.charAt(0)) + propertyName.substring(1);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/Reformatter.java b/value/src/main/java/com/google/auto/value/processor/Reformatter.java
new file mode 100644
index 0000000..6926517
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/Reformatter.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+/**
+ * Postprocessor that runs over the output of the template engine in order to make it look nicer.
+ * Mostly, this involves removing surplus horizontal and vertical space.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+class Reformatter {
+  static String fixup(String s) {
+    StringBuilder out = new StringBuilder();
+    JavaScanner scanner = new JavaScanner(s);
+    s = scanner.string();
+    int len = s.length();
+    for (int start = 0, previous = 0, braces = 0, parens = 0, end = 0;
+        start < len;
+        previous = start, start = end) {
+      end = scanner.tokenEnd(start);
+      // The tokenized string always ends with \n so we can usually look at s.charAt(end) without
+      // worrying about going past the end of the string.
+      switch (s.charAt(start)) {
+        case '(':
+          parens++;
+          break;
+        case ')':
+          parens--;
+          break;
+        case '{':
+          braces++;
+          break;
+        case '}':
+          braces--;
+          break;
+        case ' ':
+          // This token is a string of consecutive spaces that is not at the start of a line.
+          // Consecutive spaces at the start of a line are attached to the previous newline, and
+          // we don't expect the first line to start with spaces. So we are going to compress this
+          // into just one space, and we are going to delete it entirely if it follows '(' or
+          // precedes a newline or one of the punctuation characters here.
+          if (s.charAt(previous) != '(' && "\n.,;)".indexOf(s.charAt(end)) < 0) {
+            out.append(' ');
+          }
+          continue;
+        case '\n':
+          // This token is a newline plus any following spaces (the indentation of the next line).
+          // If it is followed by something other than a newline then we will output it. Otherwise,
+          // it is part of a sequence of newlines but it is not the last one. If this is a context
+          // where we delete blank lines, or if this is not the first new line in the sequence, or
+          // if we are at the start of the file, we will delete this one. Otherwise we will output a
+          // single newline with no following indentation. Contexts where we delete blank lines are
+          // inside parentheses or inside more than one set of braces.
+          if (end < len && s.charAt(end) != '\n') {
+            if (out.length() == 0) {
+              // Omit newlines at the very start of the file.
+              start++;
+            }
+            break; // Output the newline and its following indentation.
+          }
+          if (parens == 0 && braces < 2 && s.charAt(previous) != '\n' && out.length() > 0) {
+            out.append('\n');
+          }
+          continue;
+        default:
+          break;
+      }
+      out.append(s, start, end);
+    }
+    return out.toString();
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/SimpleMethod.java b/value/src/main/java/com/google/auto/value/processor/SimpleMethod.java
new file mode 100644
index 0000000..0351023
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/SimpleMethod.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import java.util.Set;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+
+/**
+ * A method on an {@code @AutoValue} or {@code AutoOneOf} class that has no specific attached
+ * information, such as a {@code toBuilder()} method, or a {@code build()} method, where only the
+ * name and access type is needed in context.
+ *
+ * <p>It implements JavaBean-style getters which means it can be referenced from templates, for
+ * example {@code $method.access}. This template access means that the class and its getters must be
+ * public.
+ */
+public final class SimpleMethod {
+  private final String access;
+  private final String name;
+
+  SimpleMethod(ExecutableElement method) {
+    this.access = access(method);
+    this.name = method.getSimpleName().toString();
+  }
+
+  public String getAccess() {
+    return access;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  /**
+   * Returns an appropriate string to be used in code for the access specification of the given
+   * method. This will be {@code public} or {@code protected} followed by a space, or the empty
+   * string for default access.
+   */
+  static String access(ExecutableElement method) {
+    Set<Modifier> mods = method.getModifiers();
+    if (mods.contains(Modifier.PUBLIC)) {
+      return "public ";
+    } else if (mods.contains(Modifier.PROTECTED)) {
+      return "protected ";
+    } else {
+      return "";
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/SimpleServiceLoader.java b/value/src/main/java/com/google/auto/value/processor/SimpleServiceLoader.java
new file mode 100644
index 0000000..55f9ae4
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/SimpleServiceLoader.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static java.util.stream.Collectors.toList;
+
+import com.google.common.collect.ImmutableList;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.ServiceConfigurationError;
+
+/**
+ * A replacement for {@link java.util.ServiceLoader} that avoids certain long-standing bugs. This
+ * simpler implementation does not bother with lazy loading but returns all the service
+ * implementations in one list. It makes sure that {@link URLConnection#setUseCaches} is called to
+ * turn off jar caching, since that tends to lead to problems in versions before JDK 9.
+ *
+ * @see <a href="https://github.com/google/auto/issues/718">Issue #718</a>
+ * @see <a href="https://bugs.openjdk.java.net/browse/JDK-8156014">JDK-8156014</a>
+ */
+public final class SimpleServiceLoader {
+  private SimpleServiceLoader() {}
+
+  public static <T> ImmutableList<T> load(Class<? extends T> service, ClassLoader loader) {
+    String resourceName = "META-INF/services/" + service.getName();
+    List<URL> resourceUrls;
+    try {
+      resourceUrls = Collections.list(loader.getResources(resourceName));
+    } catch (IOException e) {
+      throw new ServiceConfigurationError("Could not look up " + resourceName, e);
+    }
+    ImmutableList.Builder<T> providers = ImmutableList.builder();
+    for (URL resourceUrl : resourceUrls) {
+      try {
+        providers.addAll(providersFromUrl(resourceUrl, service, loader));
+      } catch (IOException e) {
+        throw new ServiceConfigurationError("Could not read " + resourceUrl, e);
+      }
+    }
+    return providers.build();
+  }
+
+  private static <T> ImmutableList<T> providersFromUrl(
+      URL resourceUrl, Class<T> service, ClassLoader loader) throws IOException {
+    ImmutableList.Builder<T> providers = ImmutableList.builder();
+    URLConnection urlConnection = resourceUrl.openConnection();
+    urlConnection.setUseCaches(false);
+    try (InputStream in = urlConnection.getInputStream();
+        BufferedReader reader =
+            new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
+      for (String line : reader.lines().collect(toList())) {
+        Optional<String> maybeClassName = parseClassName(line);
+        if (maybeClassName.isPresent()) {
+          String className = maybeClassName.get();
+          Class<?> c;
+          try {
+            c = Class.forName(className, false, loader);
+          } catch (ClassNotFoundException e) {
+            throw new ServiceConfigurationError("Could not load " + className, e);
+          }
+          if (!service.isAssignableFrom(c)) {
+            throw new ServiceConfigurationError(
+                "Class " + className + " is not assignable to " + service.getName());
+          }
+          try {
+            Object provider = c.getConstructor().newInstance();
+            providers.add(service.cast(provider));
+          } catch (ReflectiveOperationException e) {
+            throw new ServiceConfigurationError("Could not construct " + className, e);
+          }
+        }
+      }
+      return providers.build();
+    }
+  }
+
+  private static Optional<String> parseClassName(String line) {
+    int hash = line.indexOf('#');
+    if (hash >= 0) {
+      line = line.substring(0, hash);
+    }
+    line = line.trim();
+    return line.isEmpty() ? Optional.empty() : Optional.of(line);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/TemplateVars.java b/value/src/main/java/com/google/auto/value/processor/TemplateVars.java
new file mode 100644
index 0000000..235f0ad
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/TemplateVars.java
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.escapevelocity.Template;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * A template and a set of variables to be substituted into that template. A concrete subclass of
+ * this class defines a set of fields that are template variables, and an implementation of the
+ * {@link #parsedTemplate()} method which is the template to substitute them into. Once the values
+ * of the fields have been assigned, the {@link #toText()} method returns the result of substituting
+ * them into the template.
+ *
+ * <p>The subclass may be a direct subclass of this class or a more distant descendant. Every field
+ * in the starting class and its ancestors up to this class will be included. Fields cannot be
+ * static unless they are also final. They cannot be private, though they can be package-private if
+ * the class is in the same package as this class. They cannot be primitive or null, so that there
+ * is a clear indication when a field has not been set.
+ *
+ * @author Éamonn McManus
+ */
+abstract class TemplateVars {
+  abstract Template parsedTemplate();
+
+  private final ImmutableList<Field> fields;
+
+  TemplateVars() {
+    this.fields = getFields(getClass());
+  }
+
+  private static ImmutableList<Field> getFields(Class<?> c) {
+    ImmutableList.Builder<Field> fieldsBuilder = ImmutableList.builder();
+    while (c != TemplateVars.class) {
+      addFields(fieldsBuilder, c.getDeclaredFields());
+      c = c.getSuperclass();
+    }
+    return fieldsBuilder.build();
+  }
+
+  private static void addFields(
+      ImmutableList.Builder<Field> fieldsBuilder, Field[] declaredFields) {
+    for (Field field : declaredFields) {
+      if (field.isSynthetic() || isStaticFinal(field)) {
+        continue;
+      }
+      if (Modifier.isPrivate(field.getModifiers())) {
+        throw new IllegalArgumentException("Field cannot be private: " + field);
+      }
+      if (Modifier.isStatic(field.getModifiers())) {
+        throw new IllegalArgumentException("Field cannot be static unless also final: " + field);
+      }
+      if (field.getType().isPrimitive()) {
+        throw new IllegalArgumentException("Field cannot be primitive: " + field);
+      }
+      fieldsBuilder.add(field);
+    }
+  }
+
+  /**
+   * Returns the result of substituting the variables defined by the fields of this class (a
+   * concrete subclass of TemplateVars) into the template returned by {@link #parsedTemplate()}.
+   */
+  String toText() {
+    Map<String, Object> vars = toVars();
+    return parsedTemplate().evaluate(vars);
+  }
+
+  private Map<String, Object> toVars() {
+    Map<String, Object> vars = new TreeMap<>();
+    for (Field field : fields) {
+      Object value = fieldValue(field, this);
+      if (value == null) {
+        throw new IllegalArgumentException("Field cannot be null (was it set?): " + field);
+      }
+      Object old = vars.put(field.getName(), value);
+      if (old != null) {
+        throw new IllegalArgumentException("Two fields called " + field.getName() + "?!");
+      }
+    }
+    return ImmutableMap.copyOf(vars);
+  }
+
+  static Template parsedTemplateForResource(String resourceName) {
+    try {
+      return Template.parseFrom(resourceName, TemplateVars::readerFromResource);
+    } catch (UnsupportedEncodingException e) {
+      throw new AssertionError(e);
+    } catch (IOException | NullPointerException | IllegalStateException e) {
+      // https://github.com/google/auto/pull/439 says that we can get NullPointerException.
+      // https://github.com/google/auto/issues/715 says that we can get IllegalStateException
+      return retryParseAfterException(resourceName, e);
+    }
+  }
+
+  private static Template retryParseAfterException(String resourceName, Exception exception) {
+    try {
+      return Template.parseFrom(resourceName, TemplateVars::readerFromUrl);
+    } catch (IOException t) {
+      // Chain the original exception so we can see both problems.
+      Throwables.getRootCause(exception).initCause(t);
+      throw new AssertionError(exception);
+    }
+  }
+
+  private static Reader readerFromResource(String resourceName) {
+    InputStream in = TemplateVars.class.getResourceAsStream(resourceName);
+    if (in == null) {
+      throw new IllegalArgumentException("Could not find resource: " + resourceName);
+    }
+    return new InputStreamReader(in, StandardCharsets.UTF_8);
+  }
+
+  // This is an ugly workaround for https://bugs.openjdk.java.net/browse/JDK-6947916, as
+  // reported in https://github.com/google/auto/issues/365.
+  // The issue is that sometimes the InputStream returned by JarURLCollection.getInputStream()
+  // can be closed prematurely, which leads to an IOException saying "Stream closed".
+  // We catch all IOExceptions, and fall back on logic that opens the jar file directly and
+  // loads the resource from it. Since that doesn't use JarURLConnection, it shouldn't be
+  // susceptible to the same bug. We only use this as fallback logic rather than doing it always,
+  // because jars are memory-mapped by URLClassLoader, so loading a resource in the usual way
+  // through the getResourceAsStream should be a lot more efficient than reopening the jar.
+  private static Reader readerFromUrl(String resourceName) throws IOException {
+    URL resourceUrl = TemplateVars.class.getResource(resourceName);
+    if (resourceUrl == null) {
+      // This is unlikely, since getResourceAsStream has already succeeded for the same resource.
+      throw new IllegalArgumentException("Could not find resource: " + resourceName);
+    }
+    InputStream in;
+    try {
+      if (resourceUrl.getProtocol().equalsIgnoreCase("file")) {
+        in = inputStreamFromFile(resourceUrl);
+      } else if (resourceUrl.getProtocol().equalsIgnoreCase("jar")) {
+        in = inputStreamFromJar(resourceUrl);
+      } else {
+        throw new AssertionError("Template fallback logic fails for: " + resourceUrl);
+      }
+    } catch (URISyntaxException e) {
+      throw new IOException(e);
+    }
+    return new InputStreamReader(in, StandardCharsets.UTF_8);
+  }
+
+  private static InputStream inputStreamFromJar(URL resourceUrl)
+      throws URISyntaxException, IOException {
+    // Jar URLs look like this: jar:file:/path/to/file.jar!/entry/within/jar
+    // So take apart the URL to open the jar /path/to/file.jar and read the entry
+    // entry/within/jar from it.
+    String resourceUrlString = resourceUrl.toString().substring("jar:".length());
+    int bang = resourceUrlString.lastIndexOf('!');
+    String entryName = resourceUrlString.substring(bang + 1);
+    if (entryName.startsWith("/")) {
+      entryName = entryName.substring(1);
+    }
+    URI jarUri = new URI(resourceUrlString.substring(0, bang));
+    JarFile jar = new JarFile(new File(jarUri));
+    JarEntry entry = jar.getJarEntry(entryName);
+    InputStream in = jar.getInputStream(entry);
+    // We have to be careful not to close the JarFile before the stream has been read, because
+    // that would also close the stream. So we defer closing the JarFile until the stream is closed.
+    return new FilterInputStream(in) {
+      @Override
+      public void close() throws IOException {
+        super.close();
+        jar.close();
+      }
+    };
+  }
+
+  // We don't really expect this case to arise, since the bug we're working around concerns jars
+  // not individual files. However, when running the test for this workaround from Maven, we do
+  // have files. That does mean the test is basically useless there, but Google's internal build
+  // system does run it using a jar, so we do have coverage.
+  private static InputStream inputStreamFromFile(URL resourceUrl)
+      throws IOException, URISyntaxException {
+    File resourceFile = new File(resourceUrl.toURI());
+    return new FileInputStream(resourceFile);
+  }
+
+  private static Object fieldValue(Field field, Object container) {
+    try {
+      return field.get(container);
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  private static boolean isStaticFinal(Field field) {
+    int modifiers = field.getModifiers();
+    return Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/TypeEncoder.java b/value/src/main/java/com/google/auto/value/processor/TypeEncoder.java
new file mode 100644
index 0000000..d1bbbab
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/TypeEncoder.java
@@ -0,0 +1,511 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.stream.Collectors.toList;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.processor.MissingTypes.MissingTypeException;
+import com.google.common.collect.ImmutableSet;
+import java.util.List;
+import java.util.OptionalInt;
+import java.util.Set;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ErrorType;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor8;
+import javax.lang.model.util.Types;
+
+/**
+ * Encodes types so they can later be decoded to incorporate imports.
+ *
+ * <p>The idea is that types that appear in generated source code use {@link #encode}, which will
+ * spell out a type like {@code java.util.List<? extends java.lang.Number>}, except that wherever a
+ * class name appears it is replaced by a special token. So the spelling might actually be {@code
+ * `java.util.List`<? extends `java.lang.Number`>}. Then once the entire class has been generated,
+ * {@code #decode} scans for these tokens to determine what classes need to be imported, and
+ * replaces the tokens with the correct spelling given the imports. So here, {@code java.util.List}
+ * would be imported, and the final spelling would be {@code List<? extends Number>} (knowing that
+ * {@code Number} is implicitly imported). The special token {@code `import`} marks where the
+ * imports should be, and {@link #decode} replaces it with the correct list of imports.
+ *
+ * <p>The funky syntax for type annotations on qualified type names requires an adjustment to this
+ * scheme. {@code `«java.util.Map`} stands for {@code java.util.} and {@code `»java.util.Map`}
+ * stands for {@code Map}. If {@code java.util.Map} is imported, then {@code `«java.util.Map`} will
+ * eventually be empty, but if {@code java.util.Map} is not imported (perhaps because there is
+ * another {@code Map} in scope) then {@code `«java.util.Map`} will be {@code java.util.}. The end
+ * result is that the code can contain {@code `«java.util.Map`@`javax.annotation.Nullable`
+ * `»java.util.Map`}. That might decode to {@code @Nullable Map} or to {@code java.util.@Nullable
+ * Map} or even to {@code java.util.@javax.annotation.Nullable Map}.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+final class TypeEncoder {
+  private TypeEncoder() {} // There are no instances of this class.
+
+  private static final EncodingTypeVisitor ENCODING_TYPE_VISITOR = new EncodingTypeVisitor();
+  private static final RawEncodingTypeVisitor RAW_ENCODING_TYPE_VISITOR =
+      new RawEncodingTypeVisitor();
+
+  /**
+   * Returns the encoding for the given type, where class names are marked by special tokens. The
+   * encoding for {@code int} will be {@code int}, but the encoding for {@code
+   * java.util.List<java.lang.Integer>} will be {@code `java.util.List`<`java.lang.Integer`>}.
+   */
+  static String encode(TypeMirror type) {
+    StringBuilder sb = new StringBuilder();
+    return type.accept(ENCODING_TYPE_VISITOR, sb).toString();
+  }
+
+  /**
+   * Like {@link #encode}, except that only the raw type is encoded. So if the given type is {@code
+   * java.util.List<java.lang.Integer>} the result will be {@code `java.util.List`}.
+   */
+  static String encodeRaw(TypeMirror type) {
+    StringBuilder sb = new StringBuilder();
+    return type.accept(RAW_ENCODING_TYPE_VISITOR, sb).toString();
+  }
+
+  /**
+   * Encodes the given type and its type annotations. The class comment for {@link TypeEncoder}
+   * covers the details of annotation encoding.
+   */
+  static String encodeWithAnnotations(TypeMirror type) {
+    return encodeWithAnnotations(type, ImmutableSet.of());
+  }
+
+  /**
+   * Encodes the given type and its type annotations. The class comment for {@link TypeEncoder}
+   * covers the details of annotation encoding.
+   *
+   * @param excludedAnnotationTypes annotations not to include in the encoding. For example, if
+   *     {@code com.example.Nullable} is in this set then the encoding will not include this
+   *     {@code @Nullable} annotation.
+   */
+  static String encodeWithAnnotations(TypeMirror type, Set<TypeMirror> excludedAnnotationTypes) {
+    StringBuilder sb = new StringBuilder();
+    return new AnnotatedEncodingTypeVisitor(excludedAnnotationTypes).visit2(type, sb).toString();
+  }
+
+  /**
+   * Decodes the given string, respelling class names appropriately. The text is scanned for tokens
+   * like {@code `java.util.Locale`} or {@code `«java.util.Locale`} to determine which classes are
+   * referenced. An appropriate set of imports is computed based on the set of those types. If the
+   * special token {@code `import`} appears in {@code text} then it will be replaced by this set of
+   * import statements. Then all of the tokens are replaced by the class names they represent,
+   * spelled appropriately given the import statements.
+   *
+   * @param text the text to be decoded.
+   * @param packageName the package of the generated class. Other classes in the same package do not
+   *     need to be imported.
+   * @param baseType a class or interface that the generated class inherits from. Nested classes in
+   *     that type do not need to be imported, and if another class has the same name as one of
+   *     those nested classes then it will need to be qualified.
+   */
+  static String decode(
+      String text, ProcessingEnvironment processingEnv, String packageName, TypeMirror baseType) {
+    return decode(
+        text, processingEnv.getElementUtils(), processingEnv.getTypeUtils(), packageName, baseType);
+  }
+
+  static String decode(
+      String text, Elements elementUtils, Types typeUtils, String pkg, TypeMirror baseType) {
+    TypeRewriter typeRewriter = new TypeRewriter(text, elementUtils, typeUtils, pkg, baseType);
+    return typeRewriter.rewrite();
+  }
+
+  private static String className(DeclaredType declaredType) {
+    return MoreElements.asType(declaredType.asElement()).getQualifiedName().toString();
+  }
+
+  /**
+   * Returns the formal type parameters of the given type. If we have {@code @AutoValue abstract
+   * class Foo<T extends SomeClass>} then this method will return an encoding of {@code <T extends
+   * SomeClass>} for {@code Foo}. Likewise it will return an encoding of the angle-bracket part of:
+   * <br>
+   * {@code Foo<SomeClass>}<br>
+   * {@code Foo<T extends Number>}<br>
+   * {@code Foo<E extends Enum<E>>}<br>
+   * {@code Foo<K, V extends Comparable<? extends K>>}.
+   *
+   * <p>The encoding is simply that classes in the "extends" part are marked, so the examples will
+   * actually look something like this:<br>
+   * {@code <`bar.baz.SomeClass`>}<br>
+   * {@code <T extends `java.lang.Number`>}<br>
+   * {@code <E extends `java.lang.Enum`<E>>}<br>
+   * {@code <K, V extends `java.lang.Comparable`<? extends K>>}.
+   */
+  static String formalTypeParametersString(TypeElement type) {
+    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();
+    if (typeParameters.isEmpty()) {
+      return "";
+    } else {
+      StringBuilder sb = new StringBuilder("<");
+      String sep = "";
+      for (TypeParameterElement typeParameter : typeParameters) {
+        sb.append(sep);
+        sep = ", ";
+        appendTypeParameterWithBounds(typeParameter, sb);
+      }
+      return sb.append(">").toString();
+    }
+  }
+
+  private static void appendTypeParameterWithBounds(
+      TypeParameterElement typeParameter, StringBuilder sb) {
+    appendAnnotations(typeParameter.getAnnotationMirrors(), sb);
+    sb.append(typeParameter.getSimpleName());
+    String sep = " extends ";
+    for (TypeMirror bound : typeParameter.getBounds()) {
+      if (!isUnannotatedJavaLangObject(bound)) {
+        sb.append(sep);
+        sep = " & ";
+        sb.append(encodeWithAnnotations(bound));
+      }
+    }
+  }
+
+  // We can omit "extends Object" from a type bound, but not "extends @NullableType Object".
+  private static boolean isUnannotatedJavaLangObject(TypeMirror type) {
+    return type.getKind().equals(TypeKind.DECLARED)
+        && type.getAnnotationMirrors().isEmpty()
+        && MoreTypes.asTypeElement(type).getQualifiedName().contentEquals("java.lang.Object");
+  }
+
+  private static void appendAnnotations(
+      List<? extends AnnotationMirror> annotationMirrors, StringBuilder sb) {
+    for (AnnotationMirror annotationMirror : annotationMirrors) {
+      sb.append(AnnotationOutput.sourceFormForAnnotation(annotationMirror)).append(" ");
+    }
+  }
+
+  /**
+   * Converts a type into a string, using standard Java syntax, except that every class name is
+   * wrapped in backquotes, like {@code `java.util.List`}.
+   */
+  private static class EncodingTypeVisitor
+      extends SimpleTypeVisitor8<StringBuilder, StringBuilder> {
+    /**
+     * Equivalent to {@code visit(type, sb)} or {@code type.accept(sb)}, except that it fixes a bug
+     * with javac versions up to JDK 8, whereby if the type is a {@code DeclaredType} then the
+     * visitor is called with a version of the type where any annotations have been lost. We can't
+     * override {@code visit} because it is final.
+     */
+    StringBuilder visit2(TypeMirror type, StringBuilder sb) {
+      if (type.getKind().equals(TypeKind.DECLARED)) {
+        // There's no point in using MoreTypes.asDeclared here, and in fact we can't, because it
+        // uses a visitor, so it would trigger the bug we're working around.
+        return visitDeclared((DeclaredType) type, sb);
+      } else {
+        return visit(type, sb);
+      }
+    }
+
+    @Override
+    protected StringBuilder defaultAction(TypeMirror type, StringBuilder sb) {
+      return sb.append(type);
+    }
+
+    @Override
+    public StringBuilder visitArray(ArrayType type, StringBuilder sb) {
+      return visit2(type.getComponentType(), sb).append("[]");
+    }
+
+    @Override
+    public StringBuilder visitDeclared(DeclaredType type, StringBuilder sb) {
+      appendTypeName(type, sb);
+      appendTypeArguments(type, sb);
+      return sb;
+    }
+
+    void appendTypeName(DeclaredType type, StringBuilder sb) {
+      TypeMirror enclosing = EclipseHack.getEnclosingType(type);
+      if (enclosing.getKind().equals(TypeKind.DECLARED)) {
+        // We might have something like com.example.Outer<Double>.Inner. We need to encode
+        // com.example.Outer<Double> first, producing `com.example.Outer`<`java.lang.Double`>.
+        // Then we can simply add .Inner after that. If Inner has its own type arguments, we'll
+        // add them with appendTypeArguments below. Of course, it's more usual for the outer class
+        // not to have type arguments, but we'll still follow this path if the nested class is an
+        // inner (not static) class.
+        visit2(enclosing, sb);
+        sb.append(".").append(type.asElement().getSimpleName());
+      } else {
+        sb.append('`').append(className(type)).append('`');
+      }
+    }
+
+    void appendTypeArguments(DeclaredType type, StringBuilder sb) {
+      List<? extends TypeMirror> arguments = type.getTypeArguments();
+      if (!arguments.isEmpty()) {
+        sb.append("<");
+        String sep = "";
+        for (TypeMirror argument : arguments) {
+          sb.append(sep);
+          sep = ", ";
+          visit2(argument, sb);
+        }
+        sb.append(">");
+      }
+    }
+
+    @Override
+    public StringBuilder visitWildcard(WildcardType type, StringBuilder sb) {
+      sb.append("?");
+      TypeMirror extendsBound = type.getExtendsBound();
+      TypeMirror superBound = type.getSuperBound();
+      if (superBound != null) {
+        sb.append(" super ");
+        visit2(superBound, sb);
+      } else if (extendsBound != null) {
+        sb.append(" extends ");
+        visit2(extendsBound, sb);
+      }
+      return sb;
+    }
+
+    @Override
+    public StringBuilder visitError(ErrorType t, StringBuilder p) {
+      throw new MissingTypeException(t);
+    }
+  }
+
+  /** Like {@link EncodingTypeVisitor} except that type parameters are omitted from the result. */
+  private static class RawEncodingTypeVisitor extends EncodingTypeVisitor {
+    @Override
+    void appendTypeArguments(DeclaredType type, StringBuilder sb) {}
+  }
+
+  /**
+   * Like {@link EncodingTypeVisitor} except that annotations on the visited type are also included
+   * in the resultant string. Class names in those annotations are also encoded using the {@code
+   * `java.util.List`} form.
+   */
+  private static class AnnotatedEncodingTypeVisitor extends EncodingTypeVisitor {
+    private final Set<TypeMirror> excludedAnnotationTypes;
+
+    AnnotatedEncodingTypeVisitor(Set<TypeMirror> excludedAnnotationTypes) {
+      this.excludedAnnotationTypes = excludedAnnotationTypes;
+    }
+
+    private void appendAnnotationsWithExclusions(
+        List<? extends AnnotationMirror> annotations, StringBuilder sb) {
+      // Optimization for the very common cases where there are no annotations or there are no
+      // exclusions.
+      if (annotations.isEmpty() || excludedAnnotationTypes.isEmpty()) {
+        appendAnnotations(annotations, sb);
+        return;
+      }
+      List<AnnotationMirror> includedAnnotations =
+          annotations.stream()
+              .filter(a -> !excludedAnnotationTypes.contains(a.getAnnotationType()))
+              .collect(toList());
+      appendAnnotations(includedAnnotations, sb);
+    }
+
+    @Override
+    public StringBuilder visitPrimitive(PrimitiveType type, StringBuilder sb) {
+      appendAnnotationsWithExclusions(type.getAnnotationMirrors(), sb);
+      // We can't just append type.toString(), because that will also have the annotation, but
+      // without encoding.
+      return sb.append(type.getKind().toString().toLowerCase());
+    }
+
+    @Override
+    public StringBuilder visitTypeVariable(TypeVariable type, StringBuilder sb) {
+      appendAnnotationsWithExclusions(type.getAnnotationMirrors(), sb);
+      return sb.append(type.asElement().getSimpleName());
+    }
+
+    /**
+     * {@inheritDoc} The result respects the Java syntax, whereby {@code Foo @Bar []} is an
+     * annotation on the array type itself, while {@code @Bar Foo[]} would be an annotation on the
+     * component type.
+     */
+    @Override
+    public StringBuilder visitArray(ArrayType type, StringBuilder sb) {
+      visit2(type.getComponentType(), sb);
+      List<? extends AnnotationMirror> annotationMirrors = type.getAnnotationMirrors();
+      if (!annotationMirrors.isEmpty()) {
+        sb.append(" ");
+        appendAnnotationsWithExclusions(annotationMirrors, sb);
+      }
+      return sb.append("[]");
+    }
+
+    @Override
+    public StringBuilder visitDeclared(DeclaredType type, StringBuilder sb) {
+      List<? extends AnnotationMirror> annotationMirrors = type.getAnnotationMirrors();
+      if (annotationMirrors.isEmpty()) {
+        super.visitDeclared(type, sb);
+      } else {
+        TypeMirror enclosing = EclipseHack.getEnclosingType(type);
+        if (enclosing.getKind().equals(TypeKind.DECLARED)) {
+          // We have something like com.example.Outer<Double>.@Annot Inner.
+          // We'll recursively encode com.example.Outer<Double> first,
+          // which if it is also annotated might result in a mouthful like
+          // `«com.example.Outer`@`org.annots.Nullable``»com.example.Outer`<`java.lang.Double`> .
+          // That annotation will have been added by a recursive call to this method.
+          // Then we'll add the annotation on the .Inner class, which we know is there because
+          // annotationMirrors is not empty. That means we'll append .@`org.annots.Annot` Inner .
+          visit2(enclosing, sb);
+          sb.append(".");
+          appendAnnotationsWithExclusions(annotationMirrors, sb);
+          sb.append(type.asElement().getSimpleName());
+        } else {
+          // This isn't an inner class, so we have the simpler (but still complicated) case of
+          // needing to place the annotation correctly in cases like java.util.@Nullable Map .
+          // See the class doc comment for an explanation of « and » here.
+          String className = className(type);
+          sb.append("`«").append(className).append("`");
+          appendAnnotationsWithExclusions(annotationMirrors, sb);
+          sb.append("`»").append(className).append("`");
+        }
+        appendTypeArguments(type, sb);
+      }
+      return sb;
+    }
+  }
+
+  private static class TypeRewriter {
+    private final String text;
+    private final int textLength;
+    private final JavaScanner scanner;
+    private final Elements elementUtils;
+    private final Types typeUtils;
+    private final String packageName;
+    private final TypeMirror baseType;
+
+    TypeRewriter(
+        String text, Elements elementUtils, Types typeUtils, String pkg, TypeMirror baseType) {
+      this.text = text;
+      this.textLength = text.length();
+      this.scanner = new JavaScanner(text);
+      this.elementUtils = elementUtils;
+      this.typeUtils = typeUtils;
+      this.packageName = pkg;
+      this.baseType = baseType;
+    }
+
+    String rewrite() {
+      // Scan the text to determine what classes are referenced.
+      Set<TypeMirror> referencedClasses = findReferencedClasses();
+      // Make a type simplifier based on these referenced types.
+      TypeSimplifier typeSimplifier =
+          new TypeSimplifier(elementUtils, typeUtils, packageName, referencedClasses, baseType);
+
+      StringBuilder output = new StringBuilder();
+      int copyStart;
+
+      // Replace the `import` token with the import statements, if it is present.
+      OptionalInt importMarker = findImportMarker();
+      if (importMarker.isPresent()) {
+        output.append(text, 0, importMarker.getAsInt());
+        for (String toImport : typeSimplifier.typesToImport()) {
+          output.append("import ").append(toImport).append(";\n");
+        }
+        copyStart = scanner.tokenEnd(importMarker.getAsInt());
+      } else {
+        copyStart = 0;
+      }
+
+      // Replace each of the classname tokens with the appropriate spelling of the classname.
+      int token;
+      for (token = copyStart; token < textLength; token = scanner.tokenEnd(token)) {
+        if (text.charAt(token) == '`') {
+          output.append(text, copyStart, token);
+          decode(output, typeSimplifier, token);
+          copyStart = scanner.tokenEnd(token);
+        }
+      }
+      output.append(text, copyStart, textLength);
+      return output.toString();
+    }
+
+    private Set<TypeMirror> findReferencedClasses() {
+      Set<TypeMirror> classes = new TypeMirrorSet();
+      for (int token = 0; token < textLength; token = scanner.tokenEnd(token)) {
+        if (text.charAt(token) == '`' && !text.startsWith("`import`", token)) {
+          String className = classNameAt(token);
+          classes.add(classForName(className));
+        }
+      }
+      return classes;
+    }
+
+    private DeclaredType classForName(String className) {
+      TypeElement typeElement = elementUtils.getTypeElement(className);
+      checkState(typeElement != null, "Could not find referenced class %s", className);
+      return MoreTypes.asDeclared(typeElement.asType());
+    }
+
+    private void decode(StringBuilder output, TypeSimplifier typeSimplifier, int token) {
+      String className = classNameAt(token);
+      DeclaredType type = classForName(className);
+      String simplified = typeSimplifier.simplifiedClassName(type);
+      int dot;
+      switch (text.charAt(token + 1)) {
+        case '«':
+          // If this is `«java.util.Map` then we want "java.util." here.
+          // That's because this is the first part of something like "java.util.@Nullable Map"
+          // or "java.util.Map.@Nullable Entry".
+          // If there's no dot, then we want nothing here, for "@Nullable Map".
+          dot = simplified.lastIndexOf('.');
+          output.append(simplified.substring(0, dot + 1)); // correct even if dot == -1
+          break;
+        case '»':
+          dot = simplified.lastIndexOf('.');
+          output.append(simplified.substring(dot + 1)); // correct even if dot == -1
+          break;
+        default:
+          output.append(simplified);
+          break;
+      }
+    }
+
+    private OptionalInt findImportMarker() {
+      for (int token = 0; token < textLength; token = scanner.tokenEnd(token)) {
+        if (text.startsWith("`import`", token)) {
+          return OptionalInt.of(token);
+        }
+      }
+      return OptionalInt.empty();
+    }
+
+    private String classNameAt(int token) {
+      checkArgument(text.charAt(token) == '`');
+      int end = scanner.tokenEnd(token) - 1; // points to the closing `
+      int t = token + 1;
+      char c = text.charAt(t);
+      if (c == '«' || c == '»') {
+        t++;
+      }
+      return text.substring(t, end);
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/TypeMirrorSet.java b/value/src/main/java/com/google/auto/value/processor/TypeMirrorSet.java
new file mode 100644
index 0000000..28b8e05
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/TypeMirrorSet.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Equivalence;
+import com.google.common.collect.ImmutableList;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import javax.lang.model.type.TypeMirror;
+
+/**
+ * A set of TypeMirror objects.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+class TypeMirrorSet extends AbstractSet<TypeMirror> {
+  private final Set<Equivalence.Wrapper<TypeMirror>> wrappers = new LinkedHashSet<>();
+
+  TypeMirrorSet() {}
+
+  TypeMirrorSet(Collection<? extends TypeMirror> types) {
+    addAll(types);
+  }
+
+  static TypeMirrorSet of(TypeMirror... types) {
+    return new TypeMirrorSet(ImmutableList.copyOf(types));
+  }
+
+  private Equivalence.Wrapper<TypeMirror> wrap(TypeMirror typeMirror) {
+    return MoreTypes.equivalence().wrap(typeMirror);
+  }
+
+  @Override
+  public boolean add(TypeMirror typeMirror) {
+    return wrappers.add(wrap(typeMirror));
+  }
+
+  @Override
+  public Iterator<TypeMirror> iterator() {
+    final Iterator<Equivalence.Wrapper<TypeMirror>> iterator = wrappers.iterator();
+    return new Iterator<TypeMirror>() {
+      @Override
+      public boolean hasNext() {
+        return iterator.hasNext();
+      }
+
+      @Override
+      public TypeMirror next() {
+        return iterator.next().get();
+      }
+
+      @Override
+      public void remove() {
+        iterator.remove();
+      }
+    };
+  }
+
+  @Override
+  public int size() {
+    return wrappers.size();
+  }
+
+  @Override
+  public boolean contains(Object o) {
+    if (o instanceof TypeMirror) {
+      return wrappers.contains(wrap((TypeMirror) o));
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public boolean remove(Object o) {
+    if (o instanceof TypeMirror) {
+      return wrappers.remove(wrap((TypeMirror) o));
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o instanceof TypeMirrorSet) {
+      TypeMirrorSet that = (TypeMirrorSet) o;
+      return wrappers.equals(that.wrappers);
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    return wrappers.hashCode();
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/TypeSimplifier.java b/value/src/main/java/com/google/auto/value/processor/TypeSimplifier.java
new file mode 100644
index 0000000..290e59e
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/TypeSimplifier.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toCollection;
+import static javax.lang.model.element.Modifier.PRIVATE;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.processor.MissingTypes.MissingTypeException;
+import com.google.common.collect.ImmutableSortedSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.NestingKind;
+import javax.lang.model.element.QualifiedNameable;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.TypeVisitor;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor8;
+import javax.lang.model.util.Types;
+
+/**
+ * Takes a set of types and a package and determines which of those types can be imported, and how
+ * to spell any of the types in the set given those imports.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+final class TypeSimplifier {
+  /**
+   * The spelling that should be used to refer to a given class, and an indication of whether it
+   * should be imported.
+   */
+  private static class Spelling {
+    final String spelling;
+    final boolean importIt;
+
+    Spelling(String spelling, boolean importIt) {
+      this.spelling = spelling;
+      this.importIt = importIt;
+    }
+  }
+
+  private final Map<String, Spelling> imports;
+
+  /**
+   * Makes a new simplifier for the given package and set of types.
+   *
+   * @param elementUtils the result of {@code ProcessingEnvironment.getElementUtils()} for the
+   *     current annotation processing environment.
+   * @param typeUtils the result of {@code ProcessingEnvironment.getTypeUtils()} for the current
+   *     annotation processing environment.
+   * @param packageName the name of the package from which classes will be referenced. Classes that
+   *     are in the same package do not need to be imported.
+   * @param types the types that will be referenced.
+   * @param base a base class that the class containing the references will extend. This is needed
+   *     because nested classes in that class or one of its ancestors are in scope in the generated
+   *     subclass, so a reference to another class with the same name as one of them is ambiguous.
+   * @throws MissingTypeException if one of the input types contains an error (typically, is
+   *     undefined).
+   */
+  TypeSimplifier(
+      Elements elementUtils,
+      Types typeUtils,
+      String packageName,
+      Set<TypeMirror> types,
+      TypeMirror base) {
+    Set<TypeMirror> typesPlusBase = new TypeMirrorSet(types);
+    if (base != null) {
+      typesPlusBase.add(base);
+    }
+    Set<TypeMirror> topLevelTypes = topLevelTypes(typeUtils, typesPlusBase);
+    Set<TypeMirror> defined = nonPrivateDeclaredTypes(typeUtils, base);
+    this.imports = findImports(elementUtils, typeUtils, packageName, topLevelTypes, defined);
+  }
+
+  /**
+   * Returns the set of types to import. We import every type that is neither in java.lang nor in
+   * the package containing the AutoValue class, provided that the result refers to the type
+   * unambiguously. For example, if there is a property of type java.util.Map.Entry then we will
+   * import java.util.Map.Entry and refer to the property as Entry. We could also import just
+   * java.util.Map in this case and refer to Map.Entry, but currently we never do that.
+   */
+  ImmutableSortedSet<String> typesToImport() {
+    ImmutableSortedSet.Builder<String> typesToImport = ImmutableSortedSet.naturalOrder();
+    for (Map.Entry<String, Spelling> entry : imports.entrySet()) {
+      if (entry.getValue().importIt) {
+        typesToImport.add(entry.getKey());
+      }
+    }
+    return typesToImport.build();
+  }
+
+  String simplifiedClassName(DeclaredType type) {
+    TypeElement typeElement = MoreElements.asType(type.asElement());
+    TypeElement top = topLevelType(typeElement);
+    // We always want to write a class name starting from the outermost class. For example,
+    // if the type is java.util.Map.Entry then we will import java.util.Map and write Map.Entry.
+    String topString = top.getQualifiedName().toString();
+    if (imports.containsKey(topString)) {
+      String suffix = typeElement.getQualifiedName().toString().substring(topString.length());
+      return imports.get(topString).spelling + suffix;
+    } else {
+      return typeElement.getQualifiedName().toString();
+    }
+  }
+
+  // The actual type parameters of the given type.
+  // If we have @AutoValue abstract class Foo<T extends Something> then the subclass will be
+  // final class AutoValue_Foo<T extends Something> extends Foo<T>.
+  // <T extends Something> is the formal type parameter list and
+  // <T> is the actual type parameter list, which is what this method returns.
+  static String actualTypeParametersString(TypeElement type) {
+    List<? extends TypeParameterElement> typeParameters = type.getTypeParameters();
+    if (typeParameters.isEmpty()) {
+      return "";
+    } else {
+      return typeParameters
+          .stream()
+          .map(e -> e.getSimpleName().toString())
+          .collect(joining(", ", "<", ">"));
+    }
+  }
+
+  /** Returns the name of the given type, including any enclosing types but not the package. */
+  static String classNameOf(TypeElement type) {
+    String name = type.getQualifiedName().toString();
+    String pkgName = packageNameOf(type);
+    return pkgName.isEmpty() ? name : name.substring(pkgName.length() + 1);
+  }
+
+  private static TypeElement topLevelType(TypeElement type) {
+    while (type.getNestingKind() != NestingKind.TOP_LEVEL) {
+      type = MoreElements.asType(type.getEnclosingElement());
+    }
+    return type;
+  }
+
+  /**
+   * Returns the name of the package that the given type is in. If the type is in the default
+   * (unnamed) package then the name is the empty string.
+   */
+  static String packageNameOf(TypeElement type) {
+    return MoreElements.getPackage(type).getQualifiedName().toString();
+  }
+
+  static String simpleNameOf(String s) {
+    if (s.contains(".")) {
+      return s.substring(s.lastIndexOf('.') + 1);
+    } else {
+      return s;
+    }
+  }
+
+  /**
+   * Given a set of referenced types, works out which of them should be imported and what the
+   * resulting spelling of each one is.
+   *
+   * <p>This method operates on a {@code Set<TypeMirror>} rather than just a {@code Set<String>}
+   * because it is not strictly possible to determine what part of a fully-qualified type name is
+   * the package and what part is the top-level class. For example, {@code java.util.Map.Entry} is a
+   * class called {@code Map.Entry} in a package called {@code java.util} assuming Java conventions
+   * are being followed, but it could theoretically also be a class called {@code Entry} in a
+   * package called {@code java.util.Map}. Since we are operating as part of the compiler, our goal
+   * should be complete correctness, and the only way to achieve that is to operate on the real
+   * representations of types.
+   *
+   * @param codePackageName The name of the package where the class containing these references is
+   *     defined. Other classes within the same package do not need to be imported.
+   * @param referenced The complete set of declared types (classes and interfaces) that will be
+   *     referenced in the generated code.
+   * @param defined The complete set of declared types (classes and interfaces) that are defined
+   *     within the scope of the generated class (i.e. nested somewhere in its superclass chain, or
+   *     in its interface set)
+   * @return a map where the keys are fully-qualified types and the corresponding values indicate
+   *     whether the type should be imported, and how the type should be spelled in the source code.
+   */
+  private static Map<String, Spelling> findImports(
+      Elements elementUtils,
+      Types typeUtils,
+      String codePackageName,
+      Set<TypeMirror> referenced,
+      Set<TypeMirror> defined) {
+    Map<String, Spelling> imports = new HashMap<>();
+    Set<TypeMirror> typesInScope = new TypeMirrorSet();
+    typesInScope.addAll(referenced);
+    typesInScope.addAll(defined);
+    Set<String> ambiguous = ambiguousNames(typeUtils, typesInScope);
+    for (TypeMirror type : referenced) {
+      TypeElement typeElement = (TypeElement) typeUtils.asElement(type);
+      String fullName = typeElement.getQualifiedName().toString();
+      String simpleName = typeElement.getSimpleName().toString();
+      String pkg = packageNameOf(typeElement);
+      boolean importIt;
+      String spelling;
+      if (ambiguous.contains(simpleName)) {
+        importIt = false;
+        spelling = fullName;
+      } else if (pkg.equals("java.lang")) {
+        importIt = false;
+        spelling = javaLangSpelling(elementUtils, codePackageName, typeElement);
+      } else if (pkg.equals(codePackageName)) {
+        importIt = false;
+        spelling = fullName.substring(pkg.isEmpty() ? 0 : pkg.length() + 1);
+      } else {
+        importIt = true;
+        spelling = simpleName;
+      }
+      imports.put(fullName, new Spelling(spelling, importIt));
+    }
+    return imports;
+  }
+
+  /**
+   * Handles the tricky case where the class being referred to is in {@code java.lang}, but the
+   * package of the referring code contains another class of the same name. For example, if the
+   * current package is {@code foo.bar} and there is a {@code foo.bar.Compiler}, then we will refer
+   * to {@code java.lang.Compiler} by its full name. The plain name {@code Compiler} would reference
+   * {@code foo.bar.Compiler} in this case. We need to write {@code java.lang.Compiler} even if the
+   * other {@code Compiler} class is not being considered here, so the {@link #ambiguousNames} logic
+   * is not enough. We have to look to see if the class exists.
+   */
+  private static String javaLangSpelling(
+      Elements elementUtils, String codePackageName, TypeElement typeElement) {
+    // If this is java.lang.Thread.State or the like, we have to look for a clash with Thread.
+    TypeElement topLevelType = topLevelType(typeElement);
+    TypeElement clash =
+        elementUtils.getTypeElement(codePackageName + "." + topLevelType.getSimpleName());
+    String fullName = typeElement.getQualifiedName().toString();
+    return (clash == null) ? fullName.substring("java.lang.".length()) : fullName;
+  }
+
+  /**
+   * Finds the top-level types for all the declared types (classes and interfaces) in the given
+   * {@code Set<TypeMirror>}.
+   *
+   * <p>The returned set contains only top-level types. If we reference {@code java.util.Map.Entry}
+   * then the returned set will contain {@code java.util.Map}. This is because we want to write
+   * {@code Map.Entry} everywhere rather than {@code Entry}.
+   */
+  private static Set<TypeMirror> topLevelTypes(Types typeUtil, Set<TypeMirror> types) {
+    return types
+        .stream()
+        .map(typeMirror -> MoreElements.asType(typeUtil.asElement(typeMirror)))
+        .map(typeElement -> topLevelType(typeElement).asType())
+        .collect(toCollection(TypeMirrorSet::new));
+  }
+
+  /**
+   * Finds all types that are declared with non private visibility by the given {@code TypeMirror},
+   * any class in its superclass chain, or any interface it implements.
+   */
+  private static Set<TypeMirror> nonPrivateDeclaredTypes(Types typeUtils, TypeMirror type) {
+    if (type == null) {
+      return new TypeMirrorSet();
+    } else {
+      Set<TypeMirror> declared = new TypeMirrorSet();
+      declared.add(type);
+      List<TypeElement> nestedTypes =
+          ElementFilter.typesIn(typeUtils.asElement(type).getEnclosedElements());
+      for (TypeElement nestedType : nestedTypes) {
+        if (!nestedType.getModifiers().contains(PRIVATE)) {
+          declared.add(nestedType.asType());
+        }
+      }
+      for (TypeMirror supertype : typeUtils.directSupertypes(type)) {
+        declared.addAll(nonPrivateDeclaredTypes(typeUtils, supertype));
+      }
+      return declared;
+    }
+  }
+
+  private static Set<String> ambiguousNames(Types typeUtils, Set<TypeMirror> types) {
+    Set<String> ambiguous = new HashSet<>();
+    Map<String, Name> simpleNamesToQualifiedNames = new HashMap<>();
+    for (TypeMirror type : types) {
+      if (type.getKind() == TypeKind.ERROR) {
+        throw new MissingTypeException(MoreTypes.asError(type));
+      }
+      String simpleName = typeUtils.asElement(type).getSimpleName().toString();
+      /*
+       * Compare by qualified names, because in Eclipse JDT, if Java 8 type annotations are used,
+       * the same (unannotated) type may appear multiple times in the Set<TypeMirror>.
+       * TODO(emcmanus): investigate further, because this might cause problems elsewhere.
+       */
+      Name qualifiedName = ((QualifiedNameable) typeUtils.asElement(type)).getQualifiedName();
+      Name previous = simpleNamesToQualifiedNames.put(simpleName, qualifiedName);
+      if (previous != null && !previous.equals(qualifiedName)) {
+        ambiguous.add(simpleName);
+      }
+    }
+    return ambiguous;
+  }
+
+  /**
+   * Returns true if casting to the given type will elicit an unchecked warning from the compiler.
+   * Only generic types such as {@code List<String>} produce such warnings. There will be no warning
+   * if the type's only generic parameters are simple wildcards, as in {@code Map<?, ?>}.
+   */
+  static boolean isCastingUnchecked(TypeMirror type) {
+    return CASTING_UNCHECKED_VISITOR.visit(type, null);
+  }
+
+  private static final TypeVisitor<Boolean, Void> CASTING_UNCHECKED_VISITOR =
+      new SimpleTypeVisitor8<Boolean, Void>(false) {
+        @Override
+        public Boolean visitUnknown(TypeMirror t, Void p) {
+          // We don't know whether casting is unchecked for this mysterious type but assume it is,
+          // so we will insert a possibly unnecessary @SuppressWarnings("unchecked").
+          return true;
+        }
+
+        @Override
+        public Boolean visitArray(ArrayType t, Void p) {
+          return visit(t.getComponentType(), p);
+        }
+
+        @Override
+        public Boolean visitDeclared(DeclaredType t, Void p) {
+          return t.getTypeArguments().stream().anyMatch(TypeSimplifier::uncheckedTypeArgument);
+        }
+
+        @Override
+        public Boolean visitTypeVariable(TypeVariable t, Void p) {
+          return true;
+        }
+      };
+
+  // If a type has a type argument, then casting to the type is unchecked, except if the argument
+  // is <?> or <? extends Object>. The same applies to all type arguments, so casting to Map<?, ?>
+  // does not produce an unchecked warning for example.
+  private static boolean uncheckedTypeArgument(TypeMirror arg) {
+    if (arg.getKind() == TypeKind.WILDCARD) {
+      WildcardType wildcard = (WildcardType) arg;
+      if (wildcard.getExtendsBound() == null || isJavaLangObject(wildcard.getExtendsBound())) {
+        // This is <?>, unless there's a super bound, in which case it is <? super Foo> and
+        // is erased.
+        return (wildcard.getSuperBound() != null);
+      }
+    }
+    return true;
+  }
+
+  private static boolean isJavaLangObject(TypeMirror type) {
+    if (type.getKind() != TypeKind.DECLARED) {
+      return false;
+    }
+    DeclaredType declaredType = (DeclaredType) type;
+    TypeElement typeElement = (TypeElement) declaredType.asElement();
+    return typeElement.getQualifiedName().contentEquals("java.lang.Object");
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/TypeVariables.java b/value/src/main/java/com/google/auto/value/processor/TypeVariables.java
new file mode 100644
index 0000000..d664ff4
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/TypeVariables.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.type.WildcardType;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.SimpleTypeVisitor8;
+import javax.lang.model.util.Types;
+
+/**
+ * Methods for handling type variables.
+ */
+final class TypeVariables {
+  private TypeVariables() {}
+
+  /**
+   * Returns a map from methods to return types, where the return types are not necessarily the
+   * original return types of the methods. Consider this example:
+   *
+   * <pre>
+   * &#64;AutoValue class {@code Foo<T>} {
+   *   abstract T getFoo();
+   *
+   *   &#64;AutoValue.Builder
+   *   abstract class {@code Builder<T>} {
+   *     abstract Builder setFoo(T t);
+   *     abstract {@code Foo<T>} build();
+   *   }
+   * }
+   * </pre>
+   *
+   * We want to be able to check that the parameter type of {@code setFoo} is the same as the
+   * return type of {@code getFoo}. But in fact it isn't, because the {@code T} of {@code Foo<T>}
+   * is not the same as the {@code T} of {@code Foo.Builder<T>}. So we create a parallel
+   * {@code Foo<T>} where the {@code T} <i>is</i> the one from {@code Foo.Builder<T>}. That way the
+   * types do correspond. This method then returns the return types of the given methods as they
+   * appear in that parallel class, meaning the type given for {@code getFoo()} is the {@code T} of
+   * {@code Foo.Builder<T>}.
+   *
+   * <p>We do the rewrite this way around (applying the type parameter from {@code Foo.Builder} to
+   * {@code Foo}) because if we hit one of the historical Eclipse bugs with {@link Types#asMemberOf}
+   * then {@link EclipseHack#methodReturnType} can use fallback logic, which only works for methods
+   * with no arguments.
+   *
+   * @param methods the methods whose return types are to be rewritten.
+   * @param sourceType the class containing those methods ({@code Foo} in the example).
+   * @param targetType the class to translate the methods into ({@code Foo.Builder<T>}) in the
+   *     example.
+   */
+  static ImmutableMap<ExecutableElement, TypeMirror> rewriteReturnTypes(
+      Elements elementUtils,
+      Types typeUtils,
+      Collection<ExecutableElement> methods,
+      TypeElement sourceType,
+      TypeElement targetType) {
+    List<? extends TypeParameterElement> sourceTypeParameters = sourceType.getTypeParameters();
+    List<? extends TypeParameterElement> targetTypeParameters = targetType.getTypeParameters();
+    Preconditions.checkArgument(
+        sourceTypeParameters.toString().equals(targetTypeParameters.toString()),
+        "%s != %s",
+        sourceTypeParameters,
+        targetTypeParameters);
+    // What we're doing is only valid if the type parameters are "the same". The check here even
+    // requires the names to be the same. The logic would still work without that, but we impose
+    // that requirement elsewhere and it means we can check in this simple way.
+    EclipseHack eclipseHack = new EclipseHack(elementUtils, typeUtils);
+    TypeMirror[] targetTypeParameterMirrors = new TypeMirror[targetTypeParameters.size()];
+    for (int i = 0; i < targetTypeParameters.size(); i++) {
+      targetTypeParameterMirrors[i] = targetTypeParameters.get(i).asType();
+    }
+    DeclaredType parallelSource = typeUtils.getDeclaredType(sourceType, targetTypeParameterMirrors);
+    return methods.stream()
+        .collect(
+            ImmutableMap.toImmutableMap(
+                m -> m, m -> eclipseHack.methodReturnType(m, parallelSource)));
+  }
+
+  /**
+   * Tests whether a given parameter can be given to a static method like
+   * {@code ImmutableMap.copyOf} to produce a value that can be assigned to the given target type.
+   *
+   * <p>For example, suppose we have this method in {@code ImmutableMap}:<br>
+   * {@code static <K, V> ImmutableMap<K, V> copyOf(Map<? extends K, ? extends V>)}<br>
+   * and we want to know if we can do this:
+   *
+   * <pre>
+   * {@code ImmutableMap<String, Integer> actualParameter = ...;}
+   * {@code ImmutableMap<String, Number> target = ImmutableMap.copyOf(actualParameter);}
+   * </pre>
+   *
+   * We will infer {@code K=String}, {@code V=Number} based on the target type, and then rewrite the
+   * formal parameter type from<br>
+   * {@code Map<? extends K, ? extends V>} to<br>
+   * {@code Map<? extends String, ? extends Number>}. Then we can check whether
+   * {@code actualParameter} is assignable to that.
+   *
+   * <p>The logic makes some simplifying assumptions, which are met for the {@code copyOf} and
+   * {@code of} methods that we use this for. The method must be static, it must have exactly one
+   * parameter, and it must have type parameters without bounds that are the same as the type
+   * parameters of its return type. We can see that these assumptions are met for the
+   * {@code ImmutableMap.copyOf} example above.
+   */
+  static boolean canAssignStaticMethodResult(
+      ExecutableElement method,
+      TypeMirror actualParameterType,
+      TypeMirror targetType,
+      Types typeUtils) {
+    if (!targetType.getKind().equals(TypeKind.DECLARED)
+        || !method.getModifiers().contains(Modifier.STATIC)
+        || method.getParameters().size() != 1) {
+      return false;
+    }
+    List<? extends TypeParameterElement> typeParameters = method.getTypeParameters();
+    List<? extends TypeMirror> targetTypeArguments =
+        MoreTypes.asDeclared(targetType).getTypeArguments();
+    if (typeParameters.size() != targetTypeArguments.size()) {
+      return false;
+    }
+    Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables = new LinkedHashMap<>();
+    for (int i = 0; i < typeParameters.size(); i++) {
+      TypeVariable v = MoreTypes.asTypeVariable(typeParameters.get(i).asType());
+      typeVariables.put(MoreTypes.equivalence().wrap(v), targetTypeArguments.get(i));
+    }
+    TypeMirror formalParameterType = method.getParameters().get(0).asType();
+    SubstitutionVisitor substitutionVisitor = new SubstitutionVisitor(typeVariables, typeUtils);
+    TypeMirror substitutedParameterType = substitutionVisitor.visit(formalParameterType, null);
+    if (substitutedParameterType.getKind().equals(TypeKind.WILDCARD)) {
+      // If the target type is Optional<? extends Foo> then <T> T Optional.of(T) will give us
+      // ? extends Foo here, and typeUtils.isAssignable will return false. But we can in fact
+      // give a Foo as an argument, so we just replace ? extends Foo with Foo.
+      WildcardType wildcard = MoreTypes.asWildcard(substitutedParameterType);
+      if (wildcard.getExtendsBound() != null) {
+        substitutedParameterType = wildcard.getExtendsBound();
+      }
+    }
+    return typeUtils.isAssignable(actualParameterType, substitutedParameterType);
+  }
+
+  /**
+   * Rewrites types such that references to type variables in the given map are replaced by the
+   * values of those variables.
+   */
+  private static class SubstitutionVisitor extends SimpleTypeVisitor8<TypeMirror, Void> {
+    private final Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables;
+    private final Types typeUtils;
+
+    SubstitutionVisitor(
+        Map<Equivalence.Wrapper<TypeVariable>, TypeMirror> typeVariables,
+        Types typeUtils) {
+      this.typeVariables = ImmutableMap.copyOf(typeVariables);
+      this.typeUtils = typeUtils;
+    }
+
+    @Override protected TypeMirror defaultAction(TypeMirror t, Void p) {
+      return t;
+    }
+
+    @Override public TypeMirror visitTypeVariable(TypeVariable t, Void p) {
+      TypeMirror substituted = typeVariables.get(MoreTypes.equivalence().wrap(t));
+      return (substituted == null) ? t : substituted;
+    }
+
+    @Override public TypeMirror visitDeclared(DeclaredType t, Void p) {
+      List<? extends TypeMirror> typeArguments = t.getTypeArguments();
+      TypeMirror[] substitutedTypeArguments = new TypeMirror[typeArguments.size()];
+      for (int i = 0; i < typeArguments.size(); i++) {
+        substitutedTypeArguments[i] = visit(typeArguments.get(i));
+      }
+      return typeUtils.getDeclaredType(
+          MoreElements.asType(t.asElement()), substitutedTypeArguments);
+    }
+
+    @Override public TypeMirror visitWildcard(WildcardType t, Void p) {
+      TypeMirror ext = visitOrNull(t.getExtendsBound());
+      if (ext != null && ext.getKind().equals(TypeKind.WILDCARD)) {
+        // An example of where this happens is if we have this method in ImmutableSet:
+        //    static <E> ImmutableSet<E> copyOf(Collection<? extends E>)
+        // and we want to know if we can do this (where T is parameter of the enclosing class):
+        //    ImmutableSet<T> actualParameter = ...
+        //    ImmutableSet<? extends T> target = ImmutableSet.copyOf(actualParameter);
+        // We will infer E=<? extends T> and rewrite the formal parameter type to
+        // Collection<? extends ? extends T>, which we must simplify to Collection<? extends T>.
+        return ext;
+      }
+      return typeUtils.getWildcardType(ext, visitOrNull(t.getSuperBound()));
+    }
+
+    @Override public TypeMirror visitArray(ArrayType t, Void p) {
+      TypeMirror comp = visit(t.getComponentType());
+      if (comp.getKind().equals(TypeKind.WILDCARD)) {
+        // An example of where this happens is if we have this method in ImmutableSet:
+        //    static <E> ImmutableSet<E> copyOf(E[])
+        // and we want to know if we can do this:
+        //    String[] actualParameter = ...
+        //    ImmutableSet<? extends T> target = ImmutableSet.copyOf(actualParameter);
+        // We will infer E=<? extends T> and rewrite the formal parameter type to
+        // <? extends T>[], which we must simplify to T[].
+        // TODO: what if getExtendsBound() returns null?
+        comp = MoreTypes.asWildcard(comp).getExtendsBound();
+      }
+      return typeUtils.getArrayType(comp);
+    }
+
+    // We'd like to override visitIntersectionType here for completeness, but Types has no method
+    // to fabricate a new IntersectionType. Anyway, currently IntersectionType can only occur as
+    // the result of TypeVariable.getUpperBound(), but the TypeMirror we're starting from is not
+    // that, and if we encounter a TypeVariable during our visit we don't visit its upper bound.
+
+    private TypeMirror visitOrNull(TypeMirror t) {
+      if (t == null) {
+        return null;
+      } else {
+        return visit(t);
+      }
+    }
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/autoannotation.vm b/value/src/main/java/com/google/auto/value/processor/autoannotation.vm
new file mode 100644
index 0000000..1d14d3f
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/autoannotation.vm
@@ -0,0 +1,403 @@
+## Copyright 2014 Google LLC
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+## 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.
+
+## Template for each generated AutoAnnotation_Foo_bar class.
+## This template uses the Apache Velocity Template Language (VTL).
+## The variables ($pkg, $props, and so on) are defined by the fields of AutoAnnotationTemplateVars.
+##
+## Comments, like this one, begin with ##. The comment text extends up to and including the newline
+## character at the end of the line. So comments also serve to join a line to the next one.
+## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.
+## That does mean that we sometimes need an extra blank line after such a directive.
+##
+## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.
+## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to
+## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.
+
+#macro (cloneArray $a)
+  #if ($gwtCompatible)
+    `java.util.Arrays`.copyOf($a, ${a}.length)
+  #else
+    ${a}.clone()
+  #end
+#end
+
+#if (!$pkg.empty)
+package $pkg;
+#end
+
+## The following line will be replaced by the required imports during post-processing.
+`import`
+
+#if (!$generated.empty)
+@${generated}("com.google.auto.value.processor.AutoAnnotationProcessor")
+#else
+// Generated by com.google.auto.value.processor.AutoAnnotationProcessor
+#end
+final class $className implements $annotationName {
+
+## Fields
+
+#foreach ($m in $members)
+  #if ($params.containsKey($m.toString()))
+
+  private final $m.type $m;
+
+  #else
+
+  private static final $m.type $m = $m.defaultValue;
+
+  #end
+#end
+
+## Constructor
+
+  $className(
+#foreach ($p in $params.keySet())
+
+      $params[$p].type $members[$p] #if ($foreach.hasNext) , #end
+#end ) {
+#foreach ($p in $params.keySet())
+  #if (!$members[$p].kind.primitive)
+
+    if ($p == null) {
+      throw new NullPointerException("Null $p");
+    }
+
+  #end
+
+  #if ($members[$p].kind == "ARRAY")
+    #if ($params[$p].kind == "ARRAY")
+
+    this.$p = #cloneArray(${p});
+
+    #elseif ($members[$p].typeMirror.componentType.kind.primitive)
+
+    this.$p = ${members[$p].typeMirror.componentType}ArrayFromCollection($p);
+
+    #elseif ($members[$p].arrayOfClassWithBounds)
+
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    ${members[$p].componentType}[] ${p}$ = ${p}.toArray(new Class[0]);
+    this.$p = ${p}$;
+
+    #else
+
+    this.$p = ${p}.toArray(new ${members[$p].componentType}[0]);
+
+    #end
+  #else
+
+    this.$p = $p;
+
+  #end
+#end
+
+  }
+
+## annotationType method (defined by the Annotation interface)
+
+  @Override
+  public Class<? extends $annotationName> annotationType() {
+    return ${annotationName}.class;
+  }
+
+## Member getters
+
+#foreach ($m in $members)
+
+  @Override
+  public ${m.type} ${m}() {
+
+  #if ($m.kind == "ARRAY")
+
+    return #cloneArray(${m});
+
+  #else
+
+    return ${m};
+
+  #end
+
+  }
+
+#end
+
+## toString
+
+#macro (appendMemberString $m)
+  #if ($m.typeMirror.toString() == "java.lang.String")
+    #set ($appendQuotedStringMethod = "true")
+
+    appendQuoted(sb, $m) ##
+  #elseif ($m.typeMirror.toString() == "char")
+    #set ($appendQuotedCharMethod = "true")
+
+    appendQuoted(sb, $m) ##
+  #elseif ($m.typeMirror.toString() == "java.lang.String[]")
+    #set ($appendQuotedStringArrayMethod = "true")
+
+    appendQuoted(sb, $m) ##
+  #elseif ($m.typeMirror.toString() == "char[]")
+    #set ($appendQuotedCharArrayMethod = "true")
+
+    appendQuoted(sb, $m) ##
+  #elseif ($m.kind == "ARRAY")
+
+    sb.append(`java.util.Arrays`.toString($m)) ##
+  #else
+
+    sb.append($m) ##
+  #end
+#end
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("@$annotationFullName(");
+
+  #foreach ($p in $params.keySet())
+
+    #if ($params.size() > 1 || $params.keySet().iterator().next() != "value")
+
+    sb.append("$p=");
+    #end
+
+    #appendMemberString($members[$p]);
+
+    #if ($foreach.hasNext)
+
+    sb.append(", ");
+    #end
+
+  #end
+
+    return sb.append(')').toString();
+  }
+
+## equals
+
+## An expression that compares `this.something` against `that.something()`.
+## It can appear in a chain of && conditions, so if that would cause precedence
+## problems the expression needs to be parenthesized.
+#macro (memberEqualsThatExpression $m)
+  #if ($m.kind == "FLOAT")
+    Float.floatToIntBits($m) == Float.floatToIntBits(that.${m}()) ##
+  #elseif ($m.kind == "DOUBLE")
+    Double.doubleToLongBits($m) == Double.doubleToLongBits(that.${m}()) ##
+  #elseif ($m.kind.primitive)
+    ($m == that.${m}()) ## parens not strictly needed but avoid confusion when comparing booleans
+  #elseif ($m.kind == "ARRAY")
+    #if ($params.containsKey($m.toString()))
+    `java.util.Arrays`.equals($m,
+        (that instanceof $className)
+            ? (($className) that).$m
+            : that.${m}()) ##
+    #else ## default value, so if |that| is also a $className then it has the same constant value
+    (that instanceof $className || `java.util.Arrays`.equals($m, that.${m}()))
+    #end
+  #else
+    ${m}.equals(that.${m}()) ##
+  #end
+#end
+
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
+    if (o instanceof $annotationName) {
+
+  #if ($members.isEmpty())
+
+      return true;
+
+  #else
+
+      $annotationName that = ($annotationName) o;
+      return ##
+           #foreach ($m in $members)
+           #memberEqualsThatExpression ($m)##
+             #if ($foreach.hasNext)
+
+           && ##
+             #end
+           #end
+           ;
+  #end
+
+    }
+    return false;
+  }
+
+## hashCode
+
+## An expression that returns the hashCode of `this.something`.
+## It appears on the right-hand side of an ^ operator, so if that would cause precedence
+## problems the expression needs to be parenthesized.
+#macro (memberHashCodeExpression $m)
+  #if ($m.kind == "LONG")
+    (int) (($m >>> 32) ^ $m) ##
+  #elseif ($m.kind == "FLOAT")
+    Float.floatToIntBits($m) ##
+  #elseif ($m.kind == "DOUBLE")
+    (int) ((Double.doubleToLongBits($m) >>> 32) ^ Double.doubleToLongBits($m)) ##
+  #elseif ($m.kind == "BOOLEAN")
+    ($m ? 1231 : 1237) ##
+  #elseif ($m.kind.primitive)
+    $m ##
+  #elseif ($m.kind == "ARRAY")
+    `java.util.Arrays`.hashCode($m) ##
+  #else
+    ${m}.hashCode() ##
+  #end
+#end
+
+## The hashCode is the sum of two parts, an invariable part and a variable part. The invariable part
+## comes from defaulted members (ones that don't appear in the @AutoAnnotation method parameters)
+## whose values have hash codes that never change. (That doesn't include Class constants, for
+## example.) We precompute the invariable part, as an optimization but also in order to avoid
+## falling afoul of constant-overflow checks in the compiler.
+
+  @Override
+  public int hashCode() {
+    return
+    ## If the invariable part is 0, we avoid outputting `return 0 + ...` just because it generates
+    ## unnecessary byte code. But if there are no members then we must say `return 0;` here.
+    ## We must write $members.isEmpty() because $members is a Map and Velocity interprets
+    ## $members.empty as meaning $members["empty"] in that case.
+    #if ($invariableHashSum != 0 || $members.isEmpty())
+
+        $invariableHashSum
+        // $invariableHashSum is the contribution from default members $invariableHashes
+    #end
+    #foreach ($m in $members)
+      #if (!$invariableHashes.contains($m.toString()))
+
+        + ($m.nameHash ^ #memberHashCodeExpression($m))
+            // $m.nameHash is 127 * "${m}".hashCode()
+      #end
+    #end
+
+        ;
+
+  }
+
+## support functions
+
+#foreach ($w in $wrapperTypesUsedInCollections)
+  #set ($prim = $w.getField("TYPE").get(""))
+
+  private static ${prim}[] ${prim}ArrayFromCollection(`java.util.Collection`<${w.simpleName}> c) {
+    ${prim}[] a = new ${prim}[c.size()];
+    int i = 0;
+    for (${prim} x : c) {
+      a[i++] = x;
+    }
+    return a;
+  }
+#end
+
+#if ($appendQuotedStringArrayMethod)
+  #set ($appendQuotedStringMethod = "true")
+
+  private static void appendQuoted(StringBuilder sb, String[] strings) {
+    sb.append('[');
+    String sep = "";
+    for (String s : strings) {
+      sb.append(sep);
+      sep = ", ";
+      appendQuoted(sb, s);
+    }
+    sb.append(']');
+  }
+#end
+
+#if ($appendQuotedCharArrayMethod)
+  #set ($appendQuotedCharMethod = "true")
+
+  private static void appendQuoted(StringBuilder sb, char[] chars) {
+    sb.append('[');
+    String sep = "";
+    for (char c : chars) {
+      sb.append(sep);
+      sep = ", ";
+      appendQuoted(sb, c);
+    }
+    sb.append(']');
+  }
+#end
+
+#if ($appendQuotedStringMethod)
+  #set ($appendEscapedMethod = "true")
+
+  private static void appendQuoted(StringBuilder sb, String s) {
+    sb.append('"');
+    for (int i = 0; i < s.length(); i++) {
+      appendEscaped(sb, s.charAt(i));
+    }
+    sb.append('"');
+  }
+#end
+
+#if ($appendQuotedCharMethod)
+  #set ($appendEscapedMethod = "true")
+
+  private static void appendQuoted(StringBuilder sb, char c) {
+    sb.append('\'');
+    appendEscaped(sb, c);
+    sb.append('\'');
+  }
+#end
+
+#if ($appendEscapedMethod)
+  private static void appendEscaped(StringBuilder sb, char c) {
+    switch (c) {
+    case '\\':
+    case '"':
+    case '\'':
+      sb.append('\\').append(c);
+      break;
+    case '\n':
+      sb.append("\\n");
+      break;
+    case '\r':
+      sb.append("\\r");
+      break;
+    case '\t':
+      sb.append("\\t");
+      break;
+    default:
+      if (c < 0x20) {
+        sb.append('\\');
+        appendWithZeroPadding(sb, Integer.toOctalString(c), 3);
+      } else if (c < 0x7f || Character.isLetter(c)) {
+        sb.append(c);
+      } else {
+        sb.append("\\u");
+        appendWithZeroPadding(sb, Integer.toHexString(c), 4);
+      }
+      break;
+    }
+  }
+
+  ## We use this rather than String.format because that doesn't exist on GWT.
+
+  private static void appendWithZeroPadding(StringBuilder sb, String s, int width) {
+    for (int i = width - s.length(); i > 0; i--) {
+      sb.append('0');
+    }
+    sb.append(s);
+  }
+#end
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/autooneof.vm b/value/src/main/java/com/google/auto/value/processor/autooneof.vm
new file mode 100644
index 0000000..04cc194
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/autooneof.vm
@@ -0,0 +1,232 @@
+## Copyright 2018 Google LLC
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+## 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.
+
+## Template for each generated AutoOneOf_Foo class.
+## This template uses the Apache Velocity Template Language (VTL).
+## The variables ($pkg, $props, and so on) are defined by the fields of AutoOneOfTemplateVars.
+##
+## Comments, like this one, begin with ##. The comment text extends up to and including the newline
+## character at the end of the line. So comments also serve to join a line to the next one.
+## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.
+## That does mean that we sometimes need an extra blank line after such a directive.
+##
+## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.
+## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to
+## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.
+
+## Get #equalsThatExpression($p) and #hashCodeExpression($p).
+#parse("equalshashcode.vm")
+
+#if (!$pkg.empty)
+package $pkg;
+#end
+
+## The following line will be replaced by the required imports during post-processing.
+`import`
+
+#if ($generated.empty)
+// Generated by com.google.auto.value.processor.AutoOneOfProcessor
+#else
+@${generated}("com.google.auto.value.processor.AutoOneOfProcessor")
+#end
+final class $generatedClass {
+  private ${generatedClass}() {} // There are no instances of this type.
+
+## Factory methods.
+#foreach ($p in $props)
+
+  #if ($p.type == "void")
+    #if ($wildcardTypes == "")
+
+  static $origClass $p() {
+    return Impl_${p}.INSTANCE;
+  }
+
+    #else
+
+  @SuppressWarnings("unchecked") // type parameters are unused in void instances
+  static $formalTypes $origClass$actualTypes $p() {
+    return ($origClass$actualTypes) Impl_${p}.INSTANCE;
+  }
+
+    #end
+
+  #else
+
+  ## If the @AutoOneOf type is TaskResult<V extends Serializable>, then we might have here:
+  ## static <V extends Serializable> TaskResult<V> value(V value) {
+  ##   return new Impl_value<V>(value);
+  ## }
+  ## The parameter type might be something else (Throwable for example), but we will still
+  ## want <V extends Serializable> TaskResult<V>.
+
+  static $formalTypes $origClass$actualTypes $p($p.type $p) {
+
+    #if (!$p.kind.primitive)
+
+    if ($p == null) {
+      throw new NullPointerException();
+    }
+
+    #end
+
+    return new Impl_$p$actualTypes($p);
+  }
+
+  #end
+
+#end
+
+  #foreach ($a in $annotations)
+
+  $a
+
+  #end
+
+  // Parent class that each implementation will inherit from.
+  private abstract static class Parent_$formalTypes extends $origClass$actualTypes {
+
+#foreach ($p in $props)
+
+    @Override
+    $p.access $p.type ${p.getter}() {
+      throw new UnsupportedOperationException(${kindGetter}().toString());
+    }
+
+#end
+
+  }
+
+#foreach ($p in $props)
+
+
+  #foreach ($a in $annotations)
+
+  $a
+
+  #end
+
+  // Implementation when the contained property is "${p}".
+  private static final class Impl_$p$formalTypes extends Parent_$actualTypes {
+
+  #if ($p.type == "void")
+
+    // There is only one instance of this class.
+    static final Impl_$p$wildcardTypes INSTANCE = new ##
+      #if ($wildcardTypes == "") Impl_$p() #else Impl_$p<>() #end;
+
+    private Impl_$p() {}
+
+    @Override
+    public void ${p.getter}() {}
+
+    #if ($serializable)
+
+    private Object readResolve() {
+      return INSTANCE;
+    }
+
+    #end
+
+    #if ($toString)
+
+    @Override
+    public String toString() {
+      return "${simpleClassName}{$p.name}";
+    }
+
+    #end
+
+    ## The implementations of equals and hashCode are equivalent to the ones
+    ## we inherit from Object. We only need to define them if they're redeclared
+    ## as abstract in an ancestor class. But currently we define them always.
+
+    #if ($equals)
+
+    @Override
+    public boolean equals($equalsParameterType x) {
+      return x == this;
+    }
+
+    #end
+
+    #if ($hashCode)
+
+    @Override
+    public int hashCode() {
+      return System.identityHashCode(this);
+    }
+
+    #end
+
+  #else
+
+    private final $p.type $p;
+
+    Impl_$p($p.type $p) {
+      this.$p = $p;
+    }
+
+    @Override
+    public $p.type ${p.getter}() {
+      return $p;
+    }
+
+    #if ($toString)
+
+    @Override
+    public String toString() {
+      return "${simpleClassName}{$p.name=" ##
+          + #if ($p.kind == "ARRAY") `java.util.Arrays`.toString(this.$p) #else this.$p #end
+          + "}";
+    }
+
+    #end
+
+    #if ($equals)
+
+    @Override
+    public boolean equals($equalsParameterType x) {
+      if (x instanceof $origClass) {
+        $origClass$wildcardTypes that = ($origClass$wildcardTypes) x;
+        return this.${kindGetter}() == that.${kindGetter}()
+            && #equalsThatExpression($p "Impl_$p");
+      } else {
+        return false;
+      }
+    }
+
+    #end
+
+    #if ($hashCode)
+
+    @Override
+    public int hashCode() {
+      return #hashCodeExpression($p);
+    }
+
+    #end
+
+  #end
+
+    @Override
+    public $kindType ${kindGetter}() {
+      return ${kindType}.$propertyToKind[$p.name];
+    }
+
+  }
+
+#end
+
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/autovalue.vm b/value/src/main/java/com/google/auto/value/processor/autovalue.vm
new file mode 100644
index 0000000..80ef79a
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/autovalue.vm
@@ -0,0 +1,434 @@
+## Copyright 2014 Google LLC
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+## 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.
+
+## Template for each generated AutoValue_Foo class.
+## This template uses the Apache Velocity Template Language (VTL).
+## The variables ($pkg, $props, and so on) are defined by the fields of AutoValueTemplateVars.
+##
+## Comments, like this one, begin with ##. The comment text extends up to and including the newline
+## character at the end of the line. So comments also serve to join a line to the next one.
+## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.
+## That does mean that we sometimes need an extra blank line after such a directive.
+##
+## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.
+## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to
+## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.
+
+## Get #equalsThatExpression($p) and #hashCodeExpression($p).
+#parse("equalshashcode.vm")
+
+#if (!$pkg.empty)
+package $pkg;
+#end
+
+## The following line will be replaced by the required imports during post-processing.
+`import`
+
+${gwtCompatibleAnnotation}
+#foreach ($a in $annotations)
+$a
+#end
+#if (!$generated.empty)
+@${generated}("com.google.auto.value.processor.AutoValueProcessor")
+#else
+// Generated by com.google.auto.value.processor.AutoValueProcessor
+#end
+${modifiers}class $subclass$formalTypes extends $origClass$actualTypes {
+
+## Fields
+
+#foreach ($p in $props)
+  #foreach ($a in ${p.fieldAnnotations})
+
+  ${a}##
+  #end
+
+  private final $p.type $p;
+#end
+
+## Constructor
+
+#if ($isFinal && $builderTypeName != "")
+  private ##
+#end
+  $subclass(
+#foreach ($p in $props)
+
+      ${p.nullableAnnotation}$p.type $p #if ($foreach.hasNext) , #end
+#end ) {
+#foreach ($p in $props)
+  #if (!$p.kind.primitive && !$p.nullable && ($builderTypeName == "" || !$isFinal))
+    ## We don't need a null check if the type is primitive or @Nullable. We also don't need it
+    ## if there is a builder, since the build() method will check for us. However, if there is a
+    ## builder but there are also extensions (!$isFinal) then we can't omit the null check because
+    ## the constructor is called from the extension code.
+
+    #if ($identifiers)
+
+    if ($p == null) {
+      throw new NullPointerException("Null $p.name");
+    }
+    #else
+      ## Just throw NullPointerException with no message if it's null.
+      ## The Object cast has no effect on the code but silences an ErrorProne warning.
+
+    ((`java.lang.Object`) ${p}).getClass();
+    #end
+
+  #end
+
+    this.$p = $p;
+#end
+  }
+
+## Property getters
+
+#foreach ($p in $props)
+
+  #foreach ($a in ${p.methodAnnotations})
+
+  ${a}##
+  #end
+
+  @Override
+  ${p.access}${p.type} ${p.getter}() {
+    return $p;
+  }
+
+#end
+
+#if ($toString)
+
+  @Override
+  public `java.lang.String` toString() {
+    return "#if ($identifiers)$simpleClassName#end{"
+
+  #foreach ($p in $props)
+
+        #if ($identifiers)+ "$p.name=" ##
+        #end+ #if ($p.kind == "ARRAY") `java.util.Arrays`.toString($p) #else $p #end
+        #if ($foreach.hasNext) + ", " #end
+
+  #end
+
+        + "}";
+  }
+
+#end
+
+#if ($equals)
+
+  @Override
+  public boolean equals($equalsParameterType o) {
+    if (o == this) {
+      return true;
+    }
+    if (o instanceof $origClass) {
+
+  #if ($props.empty)
+
+      return true;
+
+  #else
+
+      $origClass$wildcardTypes that = ($origClass$wildcardTypes) o;
+      return ##
+          #foreach ($p in $props)
+          #equalsThatExpression ($p $subclass)##
+            #if ($foreach.hasNext)
+
+          && ##
+            #end
+          #end
+          ;
+  #end
+
+    }
+    return false;
+  }
+
+#end
+
+#if ($hashCode)
+
+  @Override
+  public int hashCode() {
+    int h$ = 1;
+
+  #foreach ($p in $props)
+
+    h$ *= 1000003;
+    h$ ^= #hashCodeExpression($p);
+
+  #end
+
+    return h$;
+  }
+#end
+
+#if (!$serialVersionUID.empty)
+  private static final long serialVersionUID = $serialVersionUID;
+#end
+
+#if ($builderTypeName != "")
+
+  #foreach ($m in $toBuilderMethods)
+
+  @Override
+  ${m.access}${builderTypeName}${builderActualTypes} ${m.name}() {
+    return new Builder${builderActualTypes}(this);
+  }
+
+  #end
+
+  ## BUILDER CLASS
+
+  #foreach ($a in $builderAnnotations)
+
+  $a##
+  #end
+
+  static #if ($isFinal) final #end class Builder${builderFormalTypes} ##
+  #if ($builderIsInterface) implements #else extends #end
+      ${builderTypeName}${builderActualTypes} {
+
+  #foreach ($p in $props)
+
+    #if ($p.kind.primitive)
+
+    private $types.boxedClass($p.typeMirror).simpleName $p;
+
+    #else
+
+      #if ($builderPropertyBuilders[$p.name])
+      ## If you have ImmutableList.Builder<String> stringsBuilder() then we define two fields:
+      ## private ImmutableList.Builder<String> stringsBuilder$;
+      ## private ImmutableList<String> strings;
+
+    private ${builderPropertyBuilders[$p.name].builderType} ##
+        ${builderPropertyBuilders[$p.name].name};
+
+      #end
+
+    private $p.type $p #if ($p.optional && !$p.nullable) = $p.optional.empty #end ;
+
+    #end
+  #end
+
+    Builder() {
+    }
+
+  #if (!$toBuilderMethods.empty)
+
+    private Builder(${origClass}${actualTypes} source) {
+
+    #foreach ($p in $props)
+
+      this.$p = source.${p.getter}();
+
+    #end
+
+    }
+
+  #end
+
+  #foreach ($p in $props)
+
+    ## The following is either null or an instance of PropertyBuilderClassifier.PropertyBuilder
+    #set ($propertyBuilder = $builderPropertyBuilders[$p.name])
+
+    ## Setter and/or property builder
+
+    #foreach ($setter in $builderSetters[$p.name])
+
+    @Override
+    ${setter.access}${builderTypeName}${builderActualTypes} ##
+        ${setter.name}(${setter.nullableAnnotation}$setter.parameterType $p) {
+
+      ## Omit null check for primitive, or @Nullable, or if we are going to be calling a copy method
+      ## such as Optional.of, which will have its own null check if appropriate.
+      #if (!$setter.primitiveParameter && !$p.nullable && ${setter.copy($p)} == $p)
+
+        #if ($identifiers)
+
+      if ($p == null) {
+        throw new NullPointerException("Null $p.name");
+      }
+        #else
+          ## Just throw NullPointerException with no message if it's null.
+          ## The Object cast has no effect on the code but silences an ErrorProne warning.
+
+      ((`java.lang.Object`) ${p}).getClass();
+        #end
+
+      #end
+
+      #if ($propertyBuilder)
+
+      if (${propertyBuilder.name} != null) {
+        throw new IllegalStateException(#if ($identifiers)"Cannot set $p after calling ${p.name}Builder()"#end);
+      }
+
+      #end
+
+      this.$p = ${setter.copy($p)};
+      return this;
+    }
+
+    #end
+
+    #if ($propertyBuilder)
+
+    @Override
+    ${propertyBuilder.access}$propertyBuilder.builderType ${p.name}Builder() {
+      if (${propertyBuilder.name} == null) {
+
+        ## This is the first time someone has asked for the builder. If the property it sets already
+        ## has a value (because it came from a toBuilder() call on the AutoValue class, or because
+        ## there is also a setter for this property) then we copy that value into the builder.
+        ## Otherwise the builder starts out empty.
+        ## If we have neither a setter nor a toBuilder() method, then the builder always starts
+        ## off empty.
+
+        #if ($builderSetters[$p.name].empty && $toBuilderMethods.empty)
+
+        ${propertyBuilder.name} = ${propertyBuilder.initializer};
+
+        #else
+
+        if ($p == null) {
+          ${propertyBuilder.name} = ${propertyBuilder.initializer};
+        } else {
+
+          #if (${propertyBuilder.builtToBuilder})
+
+          ${propertyBuilder.name} = ${p}.${propertyBuilder.builtToBuilder}();
+
+          #else
+
+          ${propertyBuilder.name} = ${propertyBuilder.initializer};
+          ${propertyBuilder.name}.${propertyBuilder.copyAll}($p);
+
+          #end
+
+          $p = null;
+        }
+
+        #end
+
+      }
+      return $propertyBuilder.name;
+    }
+
+    #end
+
+    ## Getter
+
+    #if ($builderGetters[$p.name])
+
+    @Override
+    ${p.nullableAnnotation}${builderGetters[$p.name].access}$builderGetters[$p.name].type ${p.getter}() {
+      #if ($builderGetters[$p.name].optional)
+
+      if ($p == null) {
+        return $builderGetters[$p.name].optional.empty;
+      } else {
+        return ${builderGetters[$p.name].optional.rawType}.of($p);
+      }
+
+      #else
+        #if ($builderRequiredProperties.contains($p))
+
+      if ($p == null) {
+        throw new IllegalStateException(#if ($identifiers)"Property \"$p.name\" has not been set"#end);
+      }
+
+        #end
+
+        #if ($propertyBuilder)
+
+      if (${propertyBuilder.name} != null) {
+        return ${propertyBuilder.name}.build();
+      }
+      if ($p == null) {
+        ${propertyBuilder.beforeInitDefault}
+        $p = ${propertyBuilder.initDefault};
+      }
+
+        #end
+
+      return $p;
+
+      #end
+
+    }
+
+    #end
+  #end
+
+    @Override
+    ${buildMethod.get().access}${origClass}${actualTypes} ${buildMethod.get().name}() {
+
+  #foreach ($p in $props)
+    #set ($propertyBuilder = $builderPropertyBuilders[$p.name])
+    #if ($propertyBuilder)
+
+      if (${propertyBuilder.name} != null) {
+        this.$p = ${propertyBuilder.name}.build();
+      } else if (this.$p == null) {
+        ${propertyBuilder.beforeInitDefault}
+        this.$p = ${propertyBuilder.initDefault};
+      }
+
+    #end
+  #end
+
+  #if (!$builderRequiredProperties.empty)
+    #if ($identifiers)  ## build a friendly message showing all missing properties
+
+      `java.lang.String` missing = "";
+
+      #foreach ($p in $builderRequiredProperties)
+
+      if (this.$p == null) {
+        missing += " $p.name";
+      }
+
+      #end
+
+      if (!missing.isEmpty()) {
+        throw new IllegalStateException("Missing required properties:" + missing);
+      }
+
+    #else  ## just throw an exception if anything is missing
+
+      if (#foreach ($p in $builderRequiredProperties)##
+          this.$p == null##
+          #if ($foreach.hasNext) || #end
+          #end) {
+        throw new IllegalStateException();
+      }
+    #end
+  #end
+
+      return new ${finalSubclass}${actualTypes}(
+  #foreach ($p in $props)
+
+          this.$p #if ($foreach.hasNext) , #end
+  #end );
+    }
+  }
+#end
+
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/equalshashcode.vm b/value/src/main/java/com/google/auto/value/processor/equalshashcode.vm
new file mode 100644
index 0000000..094f6c3
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/equalshashcode.vm
@@ -0,0 +1,82 @@
+## Copyright 2018 Google LLC
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+## 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.
+
+## Shared definitions for @AutoFoo templates. This is included in those templates using
+## the #parse directive.
+##
+## This template uses the Apache Velocity Template Language (VTL).
+## The variables ($pkg, $props, and so on) are defined by the fields of AutoValueTemplateVars.
+##
+## Comments, like this one, begin with ##. The comment text extends up to and including the newline
+## character at the end of the line. So comments also serve to join a line to the next one.
+## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.
+## That does mean that we sometimes need an extra blank line after such a directive.
+##
+## Post-processing will remove unwanted spaces and blank lines, but will not join two lines.
+## It will also replace classes spelled as (e.g.) `java.util.Arrays`, with the backquotes, to
+## use just Arrays if that class can be imported unambiguously, or java.util.Arrays if not.
+
+## In the following two macros, $p is an object of type AutoValueProcessor.Property
+## or AutoOneOfProcessor.Property. $p.kind means the getKind() method of those classes,
+## and likewise for $p.getter and $p.nullable (isNullable()).
+
+## Expands to an expression appropriate for comparing the $p property in `this` against
+## the $p property in `that`. If we're generating code for `AutoValue_Baz` then
+## `that` is of type `Baz`.
+## As an example, if $p is the `foo` property and $p.kind is FLOAT,
+## this becomes `Float.floatToIntBits(this.foo) == Float.floatToIntBits(that.foo())`
+## or `...that.getFoo()...`.
+## The expression should be surrounded by parentheses if otherwise there might be precedence
+## problems when it is followed by &&.
+## A reminder that trailing ## here serves to delete the newline, which we don't want in the output.
+#macro (equalsThatExpression $p $subclass)
+  #if ($p.kind == "FLOAT")
+    Float.floatToIntBits(this.$p) == Float.floatToIntBits(that.${p.getter}()) ##
+  #elseif ($p.kind == "DOUBLE")
+    Double.doubleToLongBits(this.$p) == Double.doubleToLongBits(that.${p.getter}()) ##
+  #elseif ($p.kind.primitive)
+    this.$p == that.${p.getter}() ##
+  #elseif ($p.kind == "ARRAY")
+    `java.util.Arrays`.equals(this.$p, ##
+        (that instanceof $subclass) ? (($subclass) that).$p : that.${p.getter}()) ##
+  #elseif ($p.nullable)
+    (this.$p == null ? that.${p.getter}() == null : this.${p}.equals(that.${p.getter}())) ##
+  #else
+    this.${p}.equals(that.${p.getter}()) ##
+  #end
+#end
+
+## Expands to an expression to compute the hashCode of the $p property.
+## For example, if $p is the `foo` property and $p.kind is FLOAT,
+## this becomes `Float.floatToIntBits(this.foo)`.
+## A reminder that trailing ## here serves to delete the newline, which we don't want in the output.
+#macro (hashCodeExpression $p)
+  #if ($p.kind == "LONG")
+    (int) (($p >>> 32) ^ $p) ##
+  #elseif ($p.kind == "FLOAT")
+    Float.floatToIntBits($p) ##
+  #elseif ($p.kind == "DOUBLE")
+    (int) ((Double.doubleToLongBits($p) >>> 32) ^ Double.doubleToLongBits($p)) ##
+  #elseif ($p.kind == "BOOLEAN")
+    $p ? 1231 : 1237 ##
+  #elseif ($p.kind.primitive)
+    $p ##
+  #elseif ($p.kind == "ARRAY")
+    `java.util.Arrays`.hashCode($p) ##
+  #elseif ($p.nullable)
+    ($p == null) ? 0 : ${p}.hashCode() ##
+  #else
+    ${p}.hashCode() ##
+  #end
+#end
diff --git a/value/src/main/java/com/google/auto/value/processor/gwtserializer.vm b/value/src/main/java/com/google/auto/value/processor/gwtserializer.vm
new file mode 100644
index 0000000..0450036
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/gwtserializer.vm
@@ -0,0 +1,122 @@
+## Copyright 2014 Google LLC
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+## 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.
+
+## Template for each generated AutoValue_Foo_CustomFieldSerializer class.
+## This template uses the Apache Velocity Template Language (VTL).
+## The variables ($pkg, $props, and so on) are defined by the fields of
+## GwtSerialization.GwtTemplateVars.
+##
+## Comments, like this one, begin with ##. The comment text extends up to and including the newline
+## character at the end of the line. So comments also serve to join a line to the next one.
+## Velocity deletes a newline after a directive (#if, #foreach, #end etc) so ## is not needed there.
+## That does mean that we sometimes need an extra blank line after such a directive.
+##
+## A post-processing step will remove unwanted spaces and blank lines, but will not join two lines.
+## TODO(emcmanus): perform the post-processing.
+#if (!$pkg.empty)
+package $pkg;
+#end
+
+## The following line will be replaced by the required imports during post-processing.
+`import`
+
+#if (!$generated.empty)
+@${generated}("com.google.auto.value.processor.AutoValueProcessor")
+#else
+// Generated by com.google.auto.value.processor.AutoValueProcessor
+#end
+public final class $serializerClass$formalTypes
+    extends `com.google.gwt.user.client.rpc.CustomFieldSerializer`<$subclass$actualTypes> {
+
+  public static $formalTypes $subclass$actualTypes instantiate(
+      `com.google.gwt.user.client.rpc.SerializationStreamReader` streamReader)
+      throws `com.google.gwt.user.client.rpc.SerializationException` {
+#foreach ($p in $props)
+    #if ($p.castingUnchecked)
+    @SuppressWarnings("unchecked")
+    #end
+    $p.type $p = ${p.gwtCast}streamReader.read${p.gwtType}();
+#end
+#if ($useBuilder)
+
+    ${subclass}.Builder${actualTypes} builder$ = new ${subclass}.Builder${actualTypes}();
+  #foreach ($p in $props)
+
+    #if ($builderSetters[$p.name].empty)
+      #set ($propertyBuilder = $builderPropertyBuilders[$p.name])
+
+    builder$.${propertyBuilder.propertyBuilderMethod}.${propertyBuilder.copyAll}($p);
+
+    #else
+
+    builder$.${builderSetters[$p.name].iterator().next().name}($p);
+    #end
+  #end
+
+    return (${subclass}${actualTypes}) builder$.build();
+#else
+
+    return new ${subclass}$actualTypes(
+        #foreach ($p in $props) $p #if ($foreach.hasNext) , #end #end);
+
+#end
+  }
+
+  public static $formalTypes void serialize(
+      `com.google.gwt.user.client.rpc.SerializationStreamWriter` streamWriter,
+      $subclass$actualTypes instance) throws `com.google.gwt.user.client.rpc.SerializationException` {
+#foreach ($p in $props)
+    streamWriter.write${p.gwtType}(instance.${p.getter}());
+#end
+  }
+
+  public static $formalTypes void deserialize(
+      @SuppressWarnings("unused") `com.google.gwt.user.client.rpc.SerializationStreamReader` streamReader,
+      @SuppressWarnings("unused") $subclass$actualTypes instance) {
+    // instantiate already did all the work.
+  }
+
+  // This dummy field is a hash of the fields in ${subclass}. It will change if they do, including
+  // if their order changes. This is because GWT identity for a class that has a serializer is
+  // based on the fields of the serializer rather than the class itself.
+  @SuppressWarnings("unused")
+  private int dummy_$classHashString;
+
+  @Override
+  public void deserializeInstance(
+      `com.google.gwt.user.client.rpc.SerializationStreamReader` streamReader,
+      $subclass$actualTypes instance) {
+    deserialize(streamReader, instance);
+  }
+
+  @Override
+  public boolean hasCustomInstantiateInstance() {
+    return true;
+  }
+
+  @Override
+  public $subclass$actualTypes instantiateInstance(
+      `com.google.gwt.user.client.rpc.SerializationStreamReader` streamReader)
+      throws `com.google.gwt.user.client.rpc.SerializationException` {
+    return instantiate(streamReader);
+  }
+
+  @Override
+  public void serializeInstance(
+      `com.google.gwt.user.client.rpc.SerializationStreamWriter` streamWriter,
+      $subclass$actualTypes instance)
+      throws `com.google.gwt.user.client.rpc.SerializationException` {
+    serialize(streamWriter, instance);
+  }
+}
diff --git a/value/src/main/java/com/google/auto/value/processor/package-info.java b/value/src/main/java/com/google/auto/value/processor/package-info.java
new file mode 100644
index 0000000..74ff41f
--- /dev/null
+++ b/value/src/main/java/com/google/auto/value/processor/package-info.java
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2013 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * 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.
+ */
+/**
+ * This package contains the annotation processor that implements the {@link
+ * com.google.auto.value.AutoValue} API.
+ */
+package com.google.auto.value.processor;
diff --git a/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedMethodSubject.java b/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedMethodSubject.java
new file mode 100644
index 0000000..18c7736
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedMethodSubject.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.memoized;
+
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+
+import com.google.auto.value.extension.memoized.processor.MemoizeExtension;
+import com.google.auto.value.processor.AutoValueProcessor;
+import com.google.common.collect.ImmutableList;
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+
+final class MemoizedMethodSubject extends Subject {
+  private final String actual;
+
+  MemoizedMethodSubject(FailureMetadata failureMetadata, String actual) {
+    super(failureMetadata, actual);
+    this.actual = actual;
+  }
+
+  void hasError(String error) {
+    JavaFileObject file =
+        JavaFileObjects.forSourceLines(
+            "Value",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.auto.value.extension.memoized.Memoized;",
+            "",
+            "@AutoValue abstract class Value {",
+            "  abstract String string();",
+            actual,
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new MemoizeExtension())))
+            .compile(file);
+    assertThat(compilation)
+        .hadErrorContaining(error)
+        .inFile(file)
+        .onLineContaining(actual);
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedMethodSubjectFactory.java b/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedMethodSubjectFactory.java
new file mode 100644
index 0000000..336a798
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedMethodSubjectFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.memoized;
+
+import static com.google.common.truth.Truth.assertAbout;
+
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+
+final class MemoizedMethodSubjectFactory implements Subject.Factory<MemoizedMethodSubject, String> {
+
+  static MemoizedMethodSubjectFactory memoizeMethod() {
+    return new MemoizedMethodSubjectFactory();
+  }
+
+  static MemoizedMethodSubject assertThatMemoizeMethod(String method) {
+    return assertAbout(memoizeMethod()).that(method);
+  }
+
+  @Override
+  public MemoizedMethodSubject createSubject(FailureMetadata failureMetadata, String that) {
+    return new MemoizedMethodSubject(failureMetadata, that);
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedTest.java b/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedTest.java
new file mode 100644
index 0000000..7bd61ac
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedTest.java
@@ -0,0 +1,485 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.memoized;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
+import com.google.auto.value.AutoValue;
+import com.google.auto.value.AutoValue.CopyAnnotations;
+import com.google.auto.value.extension.memoized.MemoizedTest.HashCodeEqualsOptimization.EqualsCounter;
+import com.google.common.collect.ImmutableList;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class MemoizedTest {
+
+  private Value value;
+  private ListValue<Integer, String> listValue;
+
+  @AutoValue
+  abstract static class ValueWithKeywordName {
+    abstract boolean getNative();
+
+    abstract boolean getNative0();
+
+    @Memoized
+    boolean getMemoizedNative() {
+      return getNative();
+    }
+
+    @Memoized
+    boolean getMemoizedNative0() {
+      return getNative0();
+    }
+  }
+
+  @AutoValue
+  @CopyAnnotations
+  @javax.annotation.Nullable
+  abstract static class ValueWithCopyAnnotations {
+    abstract boolean getNative();
+
+    @Memoized
+    boolean getMemoizedNative() {
+      return getNative();
+    }
+  }
+
+  @AutoValue
+  @javax.annotation.Nullable
+  abstract static class ValueWithoutCopyAnnotations {
+    abstract boolean getNative();
+
+    @Memoized
+    boolean getMemoizedNative() {
+      return getNative();
+    }
+  }
+
+  @AutoValue
+  abstract static class Value {
+    private int primitiveCount;
+    private int notNullableCount;
+    private int nullableCount;
+    private int returnsNullCount;
+    private int nullableWithTypeAnnotationCount;
+    private int returnsNullWithTypeAnnotationCount;
+    private int notNullableButReturnsNullCount;
+    private int throwsExceptionCount;
+
+    @javax.annotation.Nullable
+    abstract String string();
+
+    abstract @org.checkerframework.checker.nullness.qual.Nullable String stringWithTypeAnnotation();
+
+    abstract HashCodeAndToStringCounter counter();
+
+    @Memoized
+    int primitive() {
+      return ++primitiveCount;
+    }
+
+    @Memoized
+    String notNullable() {
+      notNullableCount++;
+      return "derived " + string() + " " + notNullableCount;
+    }
+
+    @Memoized
+    @javax.annotation.Nullable
+    String nullable() {
+      nullableCount++;
+      return "nullable derived " + string() + " " + nullableCount;
+    }
+
+    @Memoized
+    @javax.annotation.Nullable
+    String returnsNull() {
+      returnsNullCount++;
+      return null;
+    }
+
+    @Memoized
+    @org.checkerframework.checker.nullness.qual.Nullable
+    String nullableWithTypeAnnotation() {
+      nullableWithTypeAnnotationCount++;
+      return "nullable derived " + stringWithTypeAnnotation() + " "
+          + nullableWithTypeAnnotationCount;
+    }
+
+    @Memoized
+    @org.checkerframework.checker.nullness.qual.Nullable
+    String returnsNullWithTypeAnnotation() {
+      returnsNullWithTypeAnnotationCount++;
+      return null;
+    }
+
+    @Memoized
+    String notNullableButReturnsNull() {
+      notNullableButReturnsNullCount++;
+      return null;
+    }
+
+    @Memoized
+    String throwsException() throws SomeCheckedException {
+      throwsExceptionCount++;
+      throw new SomeCheckedException();
+    }
+
+    @Override
+    @Memoized
+    public abstract int hashCode();
+
+    @Override
+    @Memoized
+    public abstract String toString();
+  }
+
+  static final class SomeCheckedException extends Exception {}
+
+  @AutoValue
+  abstract static class ListValue<T extends Number, K> {
+
+    abstract T value();
+
+    abstract K otherValue();
+
+    @Memoized
+    ImmutableList<T> myTypedList() {
+      return ImmutableList.of(value());
+    }
+  }
+
+  static class HashCodeAndToStringCounter {
+    int hashCodeCount;
+    int toStringCount;
+
+    @Override
+    public int hashCode() {
+      return ++hashCodeCount;
+    }
+
+    @Override
+    public String toString() {
+      return "a string" + ++toStringCount;
+    }
+  }
+
+  @AutoValue
+  abstract static class HashCodeEqualsOptimization {
+    int overrideHashCode;
+    int hashCodeCount;
+
+    abstract EqualsCounter equalsCounter();
+
+    @Memoized
+    @Override
+    public int hashCode() {
+      hashCodeCount++;
+      return overrideHashCode;
+    }
+
+    static class EqualsCounter {
+      int equalsCount;
+
+      @Override
+      public int hashCode() {
+        return 0;
+      }
+
+      @Override
+      public boolean equals(Object obj) {
+        equalsCount++;
+        return true;
+      }
+    }
+  }
+
+  @AutoValue
+  abstract static class HashCodeEqualsOptimizationOffWhenEqualsIsFinal {
+    int hashCodeCount;
+
+    @Override
+    @Memoized
+    public int hashCode() {
+      hashCodeCount++;
+      return 1;
+    }
+
+    @Override
+    public final boolean equals(Object that) {
+      return that instanceof HashCodeEqualsOptimizationOffWhenEqualsIsFinal;
+    }
+  }
+
+  @Before
+  public void setUp() {
+    value = new AutoValue_MemoizedTest_Value(
+        "string", "stringWithTypeAnnotation", new HashCodeAndToStringCounter());
+    listValue = new AutoValue_MemoizedTest_ListValue<Integer, String>(0, "hello");
+  }
+
+  @Test
+  public void listValueList() {
+    assertThat(listValue.myTypedList()).containsExactly(listValue.value());
+  }
+
+  @Test
+  public void listValueString() {
+    assertThat(listValue.otherValue()).isEqualTo("hello");
+  }
+
+  @Test
+  public void primitive() {
+    assertThat(value.primitive()).isEqualTo(1);
+    assertThat(value.primitive()).isEqualTo(1);
+    assertThat(value.primitiveCount).isEqualTo(1);
+  }
+
+  @Test
+  public void notNullable() {
+    assertThat(value.notNullable()).isEqualTo("derived string 1");
+    assertThat(value.notNullable()).isSameInstanceAs(value.notNullable());
+    assertThat(value.notNullableCount).isEqualTo(1);
+  }
+
+  @Test
+  public void nullable() {
+    assertThat(value.nullable()).isEqualTo("nullable derived string 1");
+    assertThat(value.nullable()).isSameInstanceAs(value.nullable());
+    assertThat(value.nullableCount).isEqualTo(1);
+  }
+
+  @Test
+  public void nullableWithTypeAnnotation() {
+    assertThat(value.nullableWithTypeAnnotation())
+        .isEqualTo("nullable derived stringWithTypeAnnotation 1");
+    assertThat(value.nullableWithTypeAnnotation())
+        .isSameInstanceAs(value.nullableWithTypeAnnotation());
+    assertThat(value.nullableWithTypeAnnotationCount).isEqualTo(1);
+  }
+
+  @Test
+  public void returnsNull() {
+    assertThat(value.returnsNull()).isNull();
+    assertThat(value.returnsNull()).isNull();
+    assertThat(value.returnsNullCount).isEqualTo(1);
+  }
+
+  @Test
+  public void returnsNullWithTypeAnnotation() {
+    assertThat(value.returnsNullWithTypeAnnotation()).isNull();
+    assertThat(value.returnsNullWithTypeAnnotation()).isNull();
+    assertThat(value.returnsNullWithTypeAnnotationCount).isEqualTo(1);
+  }
+
+  @Test
+  public void notNullableButReturnsNull() {
+    try {
+      value.notNullableButReturnsNull();
+      fail();
+    } catch (NullPointerException expected) {
+      assertThat(expected)
+          .hasMessageThat()
+          .isEqualTo("notNullableButReturnsNull() cannot return null");
+    }
+    assertThat(value.notNullableButReturnsNullCount).isEqualTo(1);
+  }
+
+  @Test
+  public void methodThrows() {
+    // The exception is thrown.
+    try {
+      value.throwsException();
+      fail();
+    } catch (SomeCheckedException expected1) {
+      // The exception is not memoized.
+      try {
+        value.throwsException();
+        fail();
+      } catch (SomeCheckedException expected2) {
+        assertThat(expected2).isNotSameInstanceAs(expected1);
+      }
+    }
+    assertThat(value.throwsExceptionCount).isEqualTo(2);
+  }
+
+  @Test
+  public void testHashCode() {
+    assertThat(value.hashCode()).isEqualTo(value.hashCode());
+    assertThat(value.counter().hashCodeCount).isEqualTo(1);
+  }
+
+  @Test
+  public void testToString() {
+    assertThat(value.toString()).isEqualTo(value.toString());
+    assertThat(value.counter().toStringCount).isEqualTo(1);
+  }
+
+  @Test
+  public void keywords() {
+    ValueWithKeywordName value = new AutoValue_MemoizedTest_ValueWithKeywordName(true, false);
+    assertThat(value.getNative()).isTrue();
+    assertThat(value.getMemoizedNative()).isTrue();
+    assertThat(value.getNative0()).isFalse();
+    assertThat(value.getMemoizedNative0()).isFalse();
+  }
+
+  @Test
+  public void copyAnnotations() {
+    ValueWithCopyAnnotations valueWithCopyAnnotations =
+        new AutoValue_MemoizedTest_ValueWithCopyAnnotations(true);
+    ValueWithoutCopyAnnotations valueWithoutCopyAnnotations =
+        new AutoValue_MemoizedTest_ValueWithoutCopyAnnotations(true);
+
+    assertThat(
+            valueWithCopyAnnotations
+                .getClass()
+                .isAnnotationPresent(javax.annotation.Nullable.class))
+        .isTrue();
+    assertThat(
+            valueWithoutCopyAnnotations
+                .getClass()
+                .isAnnotationPresent(javax.annotation.Nullable.class))
+        .isFalse();
+  }
+
+  @Test
+  public void nullableHasAnnotation() throws ReflectiveOperationException {
+    Method nullable = AutoValue_MemoizedTest_Value.class.getDeclaredMethod("nullable");
+    assertThat(nullable.isAnnotationPresent(javax.annotation.Nullable.class)).isTrue();
+  }
+
+  @Test
+  public void nullableWithTypeAnnotationHasAnnotation() throws ReflectiveOperationException {
+    Method nullable =
+        AutoValue_MemoizedTest_Value.class.getDeclaredMethod("nullableWithTypeAnnotation");
+    AnnotatedType returnType = nullable.getAnnotatedReturnType();
+    assertThat(returnType.isAnnotationPresent(
+                   org.checkerframework.checker.nullness.qual.Nullable.class))
+        .isTrue();
+  }
+
+  @Test
+  public void nullableConstructorParameter() throws ReflectiveOperationException {
+    // Constructor parameters are potentially:
+    // [0] @javax.annotation.Nullable String string,
+    // [1] @org.checkerframework.checker.nullness.qual.Nullable String stringWithTypeAnnotation,
+    // [2] HashCodeAndToStringCounter counter
+    // We don't currently copy @javax.annotation.Nullable because it is not a TYPE_USE annotation.
+    Constructor<?> constructor = AutoValue_MemoizedTest_Value.class.getDeclaredConstructor(
+        String.class, String.class, HashCodeAndToStringCounter.class);
+    AnnotatedType paramType = constructor.getAnnotatedParameterTypes()[1];
+    assertThat(paramType.isAnnotationPresent(
+                   org.checkerframework.checker.nullness.qual.Nullable.class))
+        .isTrue();
+  }
+
+  @Test
+  public void hashCodeEqualsOptimization() {
+    HashCodeEqualsOptimization first =
+        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());
+    HashCodeEqualsOptimization second =
+        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());
+
+    first.overrideHashCode = 2;
+    second.overrideHashCode = 2;
+    assertThat(first.equals(second)).isTrue();
+    assertThat(first.equalsCounter().equalsCount).isEqualTo(1);
+
+    HashCodeEqualsOptimization otherwiseEqualsButDifferentHashCode =
+        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());
+    otherwiseEqualsButDifferentHashCode.overrideHashCode = 4;
+
+    assertThat(otherwiseEqualsButDifferentHashCode.equals(first)).isFalse();
+    assertThat(otherwiseEqualsButDifferentHashCode.equalsCounter().equalsCount).isEqualTo(0);
+  }
+
+  @Test
+  public void hashCodeEqualsOptimization_otherTypes() {
+    HashCodeEqualsOptimization optimizedEquals =
+        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());
+
+    assertThat(optimizedEquals.equals(new Object())).isFalse();
+    assertThat(optimizedEquals.equals(null)).isFalse();
+
+    assertThat(optimizedEquals.equalsCounter().equalsCount).isEqualTo(0);
+    assertThat(optimizedEquals.hashCodeCount).isEqualTo(0);
+  }
+
+  @Test
+  public void hashCodeEqualsOptimization_hashCodeIgnoredForSameInstance() {
+    HashCodeEqualsOptimization optimizedEquals =
+        new AutoValue_MemoizedTest_HashCodeEqualsOptimization(new EqualsCounter());
+
+    assertThat(optimizedEquals.equals(optimizedEquals)).isTrue();
+
+    assertThat(optimizedEquals.equalsCounter().equalsCount).isEqualTo(0);
+    assertThat(optimizedEquals.hashCodeCount).isEqualTo(0);
+  }
+
+  @Test
+  public void hashCodeEqualsOptimization_offWhenEqualsIsFinal() {
+    HashCodeEqualsOptimizationOffWhenEqualsIsFinal memoizedHashCodeAndFinalEqualsMethod =
+        new AutoValue_MemoizedTest_HashCodeEqualsOptimizationOffWhenEqualsIsFinal();
+    HashCodeEqualsOptimizationOffWhenEqualsIsFinal second =
+        new AutoValue_MemoizedTest_HashCodeEqualsOptimizationOffWhenEqualsIsFinal();
+
+    assertThat(memoizedHashCodeAndFinalEqualsMethod.equals(second)).isTrue();
+    assertThat(memoizedHashCodeAndFinalEqualsMethod.hashCodeCount).isEqualTo(0);
+
+    memoizedHashCodeAndFinalEqualsMethod.hashCode();
+    memoizedHashCodeAndFinalEqualsMethod.hashCode();
+    assertThat(memoizedHashCodeAndFinalEqualsMethod.hashCodeCount).isEqualTo(1);
+  }
+
+  interface TypeEdgeIterable<InputT, ResultT> {}
+
+  interface ResourceUri {}
+
+  interface TypePath<InputT, ResultT> {}
+
+  abstract static class AbstractTypePath<InputT, ResultT> {
+    abstract TypeEdgeIterable<InputT, ResultT> edges();
+  }
+
+  @AutoValue
+  abstract static class ResourceUriPath<InputT> extends AbstractTypePath<InputT, ResourceUri> {
+    static <InputT> ResourceUriPath<InputT> create(
+        TypeEdgeIterable<InputT, ResourceUri> edges) {
+      return new AutoValue_MemoizedTest_ResourceUriPath<>(edges);
+    }
+
+    @Memoized
+    TypePath<InputT, String> toServiceName() {
+      return new TypePath<InputT, String>() {};
+    }
+  }
+
+  @Test
+  public void methodTypeFromTypeVariableSubsitution() {
+    ResourceUriPath<String> path =
+        ResourceUriPath.create(new TypeEdgeIterable<String, ResourceUri>() {});
+    assertThat(path.edges()).isNotNull();
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedValidationTest.java b/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedValidationTest.java
new file mode 100644
index 0000000..72213b3
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/memoized/MemoizedValidationTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.memoized;
+
+import static com.google.auto.value.extension.memoized.MemoizedMethodSubjectFactory.assertThatMemoizeMethod;
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+
+import com.google.auto.value.extension.memoized.processor.MemoizedValidator;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class MemoizedValidationTest {
+
+  @Test
+  public void privateMethod() {
+    assertThatMemoizeMethod("@Memoized private String method() { return \"\"; }")
+        .hasError("@Memoized methods cannot be private");
+  }
+
+  @Test
+  public void staticMethod() {
+    assertThatMemoizeMethod("@Memoized static String method() { return \"\"; }")
+        .hasError("@Memoized methods cannot be static");
+  }
+
+  @Test
+  public void finalMethod() {
+    assertThatMemoizeMethod("@Memoized final String method() { return \"\"; }")
+        .hasError("@Memoized methods cannot be final");
+  }
+
+  @Test
+  public void abstractMethod() {
+    assertThatMemoizeMethod("@Memoized abstract String method();")
+        .hasError("@Memoized methods cannot be abstract");
+  }
+
+  @Test
+  public void voidMethod() {
+    assertThatMemoizeMethod("@Memoized void method() {}")
+        .hasError("@Memoized methods cannot be void");
+  }
+
+  @Test
+  public void parameters() {
+    assertThatMemoizeMethod("@Memoized String method(Object param) { return \"\"; }")
+        .hasError("@Memoized methods cannot have parameters");
+  }
+
+  @Test
+  public void notInAutoValueClass() {
+    JavaFileObject source =
+        JavaFileObjects.forSourceLines(
+            "test.EnclosingClass",
+            "package test;",
+            "",
+            "import com.google.auto.value.extension.memoized.Memoized;",
+            "",
+            "abstract class EnclosingClass {",
+            "  @Memoized",
+            "  String string() {",
+            "    return \"\";",
+            "  }",
+            "}");
+    Compilation compilation = javac().withProcessors(new MemoizedValidator()).compile(source);
+    assertThat(compilation).failed();
+    assertThat(compilation)
+        .hadErrorContaining("@Memoized methods must be declared only in @AutoValue classes")
+        .inFile(source)
+        .onLine(6);
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/processor/SerializableAutoValueExtensionTest.java b/value/src/test/java/com/google/auto/value/extension/serializable/processor/SerializableAutoValueExtensionTest.java
new file mode 100644
index 0000000..1879d1e
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/processor/SerializableAutoValueExtensionTest.java
@@ -0,0 +1,418 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
+import static org.junit.Assert.assertThrows;
+
+import com.google.auto.value.AutoValue;
+import com.google.auto.value.extension.serializable.SerializableAutoValue;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.testing.SerializableTester;
+import java.io.ByteArrayOutputStream;
+import java.io.NotSerializableException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.Optional;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class SerializableAutoValueExtensionTest {
+  private static final String A = "a";
+  private static final int B = 1;
+  private static final String C = "c";
+  private static final int D = 2;
+
+  @SerializableAutoValue
+  @AutoValue
+  abstract static class DummySerializableAutoValue implements Serializable {
+    // Primitive fields
+    abstract String a();
+
+    abstract int b();
+
+    // Optional fields
+    abstract Optional<String> optionalC();
+
+    abstract Optional<Integer> optionalD();
+
+    static DummySerializableAutoValue.Builder builder() {
+      return new AutoValue_SerializableAutoValueExtensionTest_DummySerializableAutoValue.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract DummySerializableAutoValue.Builder setA(String value);
+
+      abstract DummySerializableAutoValue.Builder setB(int value);
+
+      abstract DummySerializableAutoValue.Builder setOptionalC(String value);
+
+      abstract DummySerializableAutoValue.Builder setOptionalD(int value);
+
+      abstract DummySerializableAutoValue build();
+    }
+  }
+
+  @Test
+  public void allFieldsAreSet_noEmpty() {
+    DummySerializableAutoValue autoValue =
+        DummySerializableAutoValue.builder()
+            .setA(A)
+            .setB(B)
+            .setOptionalC(C)
+            .setOptionalD(D)
+            .build();
+
+    assertThat(autoValue.a()).isEqualTo(A);
+    assertThat(autoValue.b()).isEqualTo(B);
+    assertThat(autoValue.optionalC()).hasValue(C);
+    assertThat(autoValue.optionalD()).hasValue(D);
+  }
+
+  @Test
+  public void allFieldsAreSet_withMixedEmpty() {
+    DummySerializableAutoValue autoValue =
+        DummySerializableAutoValue.builder().setA(A).setB(B).setOptionalC(C).build();
+
+    assertThat(autoValue.a()).isEqualTo(A);
+    assertThat(autoValue.b()).isEqualTo(B);
+    assertThat(autoValue.optionalC()).hasValue(C);
+    assertThat(autoValue.optionalD()).isEmpty();
+  }
+
+  @Test
+  public void allFieldsAreSet_withEmpty() {
+    DummySerializableAutoValue autoValue =
+        DummySerializableAutoValue.builder().setA(A).setB(B).build();
+
+    assertThat(autoValue.a()).isEqualTo(A);
+    assertThat(autoValue.b()).isEqualTo(B);
+    assertThat(autoValue.optionalC()).isEmpty();
+    assertThat(autoValue.optionalD()).isEmpty();
+  }
+
+  @Test
+  public void allFieldsAreSerialized_noEmpty() {
+    DummySerializableAutoValue autoValue =
+        DummySerializableAutoValue.builder()
+            .setA(A)
+            .setB(B)
+            .setOptionalC(C)
+            .setOptionalD(D)
+            .build();
+
+    DummySerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @Test
+  public void allFieldsAreSerialized_withEmpty() {
+    DummySerializableAutoValue autoValue =
+        DummySerializableAutoValue.builder().setA(A).setB(B).build();
+
+    DummySerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @Test
+  public void allFieldsAreSerialized_withMixedEmpty() {
+    DummySerializableAutoValue autoValue =
+        DummySerializableAutoValue.builder().setA(A).setB(B).setOptionalC(C).build();
+
+    DummySerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @SerializableAutoValue
+  @AutoValue
+  abstract static class PrefixSerializableAutoValue implements Serializable {
+    // Primitive fields
+    abstract String getA();
+
+    abstract boolean isB();
+
+    // Optional fields
+    abstract Optional<String> getC();
+
+    abstract Optional<Boolean> getD();
+
+    static PrefixSerializableAutoValue.Builder builder() {
+      return new AutoValue_SerializableAutoValueExtensionTest_PrefixSerializableAutoValue.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract PrefixSerializableAutoValue.Builder a(String value);
+
+      abstract PrefixSerializableAutoValue.Builder b(boolean value);
+
+      abstract PrefixSerializableAutoValue.Builder c(String value);
+
+      abstract PrefixSerializableAutoValue.Builder d(boolean value);
+
+      abstract PrefixSerializableAutoValue build();
+    }
+  }
+
+  @Test
+  public void allPrefixFieldsAreSerialized_noEmpty() {
+    PrefixSerializableAutoValue autoValue =
+        PrefixSerializableAutoValue.builder().a("A").b(true).c("C").d(false).build();
+
+    PrefixSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @Test
+  public void allPrefixFieldsAreSerialized_WithEmpty() {
+    PrefixSerializableAutoValue autoValue =
+        PrefixSerializableAutoValue.builder().a("A").b(true).build();
+
+    PrefixSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @SerializableAutoValue
+  @AutoValue
+  abstract static class NotSerializable {
+    static NotSerializable create() {
+      return new AutoValue_SerializableAutoValueExtensionTest_NotSerializable(Optional.of("A"));
+    }
+
+    abstract Optional<String> optionalA();
+  }
+
+  @Test
+  public void missingImplementsSerializableThrowsException() throws Exception {
+    NotSerializable autoValue = NotSerializable.create();
+    ByteArrayOutputStream bo = new ByteArrayOutputStream();
+    ObjectOutputStream so = new ObjectOutputStream(bo);
+
+    assertThrows(NotSerializableException.class, () -> so.writeObject(autoValue));
+  }
+
+  @AutoValue
+  abstract static class NotSerializableNoAnnotation implements Serializable {
+    static NotSerializableNoAnnotation create() {
+      return new AutoValue_SerializableAutoValueExtensionTest_NotSerializableNoAnnotation(
+          Optional.of("A"));
+    }
+
+    abstract Optional<String> optionalA();
+  }
+
+  @Test
+  public void missingSerializableAutoValueAnnotationThrowsException() throws Exception {
+    NotSerializableNoAnnotation autoValue = NotSerializableNoAnnotation.create();
+    ByteArrayOutputStream bo = new ByteArrayOutputStream();
+    ObjectOutputStream so = new ObjectOutputStream(bo);
+
+    assertThrows(NotSerializableException.class, () -> so.writeObject(autoValue));
+  }
+
+  @SerializableAutoValue
+  @AutoValue
+  // Technically all type parameters should extend serializable, but for the purposes of testing,
+  // only one type parameter is bounded.
+  abstract static class HasTypeParameters<T extends Serializable, S> implements Serializable {
+    abstract T a();
+
+    abstract Optional<S> optionalB();
+
+    static <T extends Serializable, S> Builder<T, S> builder() {
+      return new AutoValue_SerializableAutoValueExtensionTest_HasTypeParameters.Builder<>();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder<T extends Serializable, S> {
+      abstract Builder<T, S> setA(T value);
+
+      abstract Builder<T, S> setOptionalB(S value);
+
+      abstract HasTypeParameters<T, S> build();
+    }
+  }
+
+  @Test
+  public void typeParameterizedFieldsAreSet_noEmpty() {
+    HasTypeParameters<String, Integer> autoValue =
+        HasTypeParameters.<String, Integer>builder().setA(A).setOptionalB(B).build();
+
+    assertThat(autoValue.a()).isEqualTo(A);
+    assertThat(autoValue.optionalB()).hasValue(B);
+  }
+
+  @Test
+  public void typeParameterizedFieldsAreSet_withEmpty() {
+    HasTypeParameters<String, Integer> autoValue =
+        HasTypeParameters.<String, Integer>builder().setA(A).build();
+
+    assertThat(autoValue.a()).isEqualTo(A);
+    assertThat(autoValue.optionalB()).isEmpty();
+  }
+
+  @Test
+  public void typeParameterizedFieldsAreSerializable_noEmpty() {
+    HasTypeParameters<String, Integer> autoValue =
+        HasTypeParameters.<String, Integer>builder().setA(A).setOptionalB(B).build();
+
+    HasTypeParameters<String, Integer> actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @Test
+  public void typeParameterizedFieldsAreSerializable_withEmpty() {
+    HasTypeParameters<String, Integer> autoValue =
+        HasTypeParameters.<String, Integer>builder().setA(A).build();
+
+    HasTypeParameters<String, Integer> actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @SerializableAutoValue
+  @AutoValue
+  abstract static class ImmutableListSerializableAutoValue implements Serializable {
+    abstract ImmutableList<Optional<String>> payload();
+
+    static ImmutableListSerializableAutoValue.Builder builder() {
+      return new AutoValue_SerializableAutoValueExtensionTest_ImmutableListSerializableAutoValue
+          .Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract ImmutableListSerializableAutoValue.Builder setPayload(
+          ImmutableList<Optional<String>> payload);
+
+      abstract ImmutableListSerializableAutoValue build();
+    }
+  }
+
+  @Test
+  public void immutableList_emptyListSerialized() {
+    ImmutableListSerializableAutoValue autoValue =
+        ImmutableListSerializableAutoValue.builder().setPayload(ImmutableList.of()).build();
+
+    ImmutableListSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @Test
+  public void immutableList_allFieldsSetAndSerialized() {
+    ImmutableListSerializableAutoValue autoValue =
+        ImmutableListSerializableAutoValue.builder()
+            .setPayload(ImmutableList.of(Optional.of("a1"), Optional.of("a2")))
+            .build();
+
+    ImmutableListSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @SerializableAutoValue
+  @AutoValue
+  abstract static class ImmutableMapSerializableAutoValue implements Serializable {
+    abstract ImmutableMap<Optional<String>, String> a();
+
+    abstract ImmutableMap<String, Optional<String>> b();
+
+    static ImmutableMapSerializableAutoValue.Builder builder() {
+      return new AutoValue_SerializableAutoValueExtensionTest_ImmutableMapSerializableAutoValue
+          .Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract ImmutableMapSerializableAutoValue.Builder setA(
+          ImmutableMap<Optional<String>, String> a);
+
+      abstract ImmutableMapSerializableAutoValue.Builder setB(
+          ImmutableMap<String, Optional<String>> b);
+
+      abstract ImmutableMapSerializableAutoValue build();
+    }
+  }
+
+  @Test
+  public void immutableMap_emptyMapSerialized() {
+    ImmutableMapSerializableAutoValue autoValue =
+        ImmutableMapSerializableAutoValue.builder()
+            .setA(ImmutableMap.of())
+            .setB(ImmutableMap.of())
+            .build();
+
+    ImmutableMapSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @Test
+  public void immutableMap_allFieldsSetAndSerialized() {
+    ImmutableMapSerializableAutoValue autoValue =
+        ImmutableMapSerializableAutoValue.builder()
+            .setA(ImmutableMap.of(Optional.of("key"), "value"))
+            .setB(ImmutableMap.of("key", Optional.of("value")))
+            .build();
+
+    ImmutableMapSerializableAutoValue actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+
+  @SerializableAutoValue
+  @AutoValue
+  abstract static class MultiplePropertiesSameType implements Serializable {
+    abstract String a();
+
+    abstract String b();
+
+    static MultiplePropertiesSameType.Builder builder() {
+      return new AutoValue_SerializableAutoValueExtensionTest_MultiplePropertiesSameType.Builder();
+    }
+
+    @AutoValue.Builder
+    abstract static class Builder {
+      abstract MultiplePropertiesSameType.Builder setA(String value);
+
+      abstract MultiplePropertiesSameType.Builder setB(String value);
+
+      abstract MultiplePropertiesSameType build();
+    }
+  }
+
+  @Test
+  public void multiplePropertiesSameType_allFieldsSerialized() {
+    MultiplePropertiesSameType autoValue =
+        MultiplePropertiesSameType.builder().setA("A").setB("B").build();
+
+    MultiplePropertiesSameType actualAutoValue = SerializableTester.reserialize(autoValue);
+
+    assertThat(actualAutoValue).isEqualTo(autoValue);
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/serializer/SerializerFactoryLoaderTest.java b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/SerializerFactoryLoaderTest.java
new file mode 100644
index 0000000..8141076
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/SerializerFactoryLoaderTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;
+import com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class SerializerFactoryLoaderTest extends CompilationAbstractTest {
+
+  @Test
+  public void getFactory_extensionsLoaded() throws Exception {
+    SerializerFactory factory = SerializerFactoryLoader.getFactory(mockProcessingEnvironment);
+
+    Serializer actualSerializer = factory.getSerializer(typeMirrorOf(String.class));
+
+    assertThat(actualSerializer.getClass().getName())
+        .contains("TestStringSerializerFactory$TestStringSerializer");
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/IdentitySerializerFactoryTest.java b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/IdentitySerializerFactoryTest.java
new file mode 100644
index 0000000..87800b3
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/IdentitySerializerFactoryTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;
+import com.squareup.javapoet.CodeBlock;
+import javax.lang.model.type.TypeMirror;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class IdentitySerializerFactoryTest extends CompilationAbstractTest {
+
+  @Test
+  public void proxyFieldType_isUnchanged() throws Exception {
+    TypeMirror typeMirror = typeMirrorOf(String.class);
+
+    TypeMirror actualTypeMirror =
+        IdentitySerializerFactory.getSerializer(typeMirror).proxyFieldType();
+
+    assertThat(actualTypeMirror).isSameInstanceAs(typeMirror);
+  }
+
+  @Test
+  public void toProxy_isUnchanged() throws Exception {
+    TypeMirror typeMirror = typeMirrorOf(String.class);
+    CodeBlock inputExpression = CodeBlock.of("x");
+
+    CodeBlock outputExpression =
+        IdentitySerializerFactory.getSerializer(typeMirror).toProxy(inputExpression);
+
+    assertThat(outputExpression).isSameInstanceAs(inputExpression);
+  }
+
+  @Test
+  public void fromProxy_isUnchanged() throws Exception {
+    TypeMirror typeMirror = typeMirrorOf(String.class);
+    CodeBlock inputExpression = CodeBlock.of("x");
+
+    CodeBlock outputExpression =
+        IdentitySerializerFactory.getSerializer(typeMirror).fromProxy(inputExpression);
+
+    assertThat(outputExpression).isSameInstanceAs(inputExpression);
+  }
+
+  @Test
+  public void isIdentity() throws Exception {
+    TypeMirror typeMirror = typeMirrorOf(String.class);
+
+    boolean actualIsIdentity = IdentitySerializerFactory.getSerializer(typeMirror).isIdentity();
+
+    assertThat(actualIsIdentity).isTrue();
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableListSerializerExtensionTest.java b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableListSerializerExtensionTest.java
new file mode 100644
index 0000000..159059d
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableListSerializerExtensionTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
+
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;
+import com.google.auto.value.extension.serializable.serializer.utils.FakeSerializerFactory;
+import com.google.common.collect.ImmutableList;
+import com.squareup.javapoet.CodeBlock;
+import java.util.Optional;
+import javax.lang.model.type.TypeMirror;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class ImmutableListSerializerExtensionTest extends CompilationAbstractTest {
+
+  private static final String FUNCTION_WITH_EXCEPTIONS =
+      "com.google.auto.value.extension.serializable.serializer.runtime.FunctionWithExceptions";
+  private static final String IMMUTABLE_LIST = "com.google.common.collect.ImmutableList";
+
+  private ImmutableListSerializerExtension extension;
+  private FakeSerializerFactory fakeSerializerFactory;
+
+  @Before
+  public void setUpExtension() {
+    extension = new ImmutableListSerializerExtension();
+    fakeSerializerFactory = new FakeSerializerFactory();
+    fakeSerializerFactory.setReturnIdentitySerializer(false);
+  }
+
+  @Test
+  public void getSerializer_nonImmutableList_emptyReturned() {
+    TypeMirror typeMirror = typeMirrorOf(String.class);
+
+    Optional<Serializer> actualSerializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);
+
+    assertThat(actualSerializer).isEmpty();
+  }
+
+  @Test
+  public void getSerializer_immutableListWithSerializableContainedType_emptyReturned() {
+    fakeSerializerFactory.setReturnIdentitySerializer(true);
+    TypeMirror typeMirror = typeMirrorOf(ImmutableList.class);
+
+    Optional<Serializer> actualSerializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);
+
+    assertThat(actualSerializer).isEmpty();
+  }
+
+  @Test
+  public void getSerializer_immutableList_serializerReturned() {
+    TypeMirror typeMirror = typeMirrorOf(ImmutableList.class);
+
+    Serializer actualSerializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+
+    assertThat(actualSerializer.getClass().getName())
+        .contains("ImmutableListSerializerExtension$ImmutableListSerializer");
+  }
+
+  @Test
+  public void proxyFieldType() {
+    TypeMirror typeMirror = declaredTypeOf(ImmutableList.class, Integer.class);
+
+    Serializer serializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+    TypeMirror actualTypeMirror = serializer.proxyFieldType();
+
+    assertThat(typeUtils.isSameType(actualTypeMirror, typeMirror)).isTrue();
+  }
+
+  @Test
+  public void toProxy() {
+    TypeMirror typeMirror = declaredTypeOf(ImmutableList.class, Integer.class);
+
+    Serializer serializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+    CodeBlock actualCodeBlock = serializer.toProxy(CodeBlock.of("x"));
+
+    assertThat(actualCodeBlock.toString())
+        .isEqualTo(
+            String.format(
+                "x.stream().map(%s.wrapper(value$ -> value$)).collect(%s.toImmutableList())",
+                FUNCTION_WITH_EXCEPTIONS, IMMUTABLE_LIST));
+  }
+
+  @Test
+  public void fromProxy() {
+    TypeMirror typeMirror = declaredTypeOf(ImmutableList.class, Integer.class);
+
+    Serializer serializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+    CodeBlock actualCodeBlock = serializer.fromProxy(CodeBlock.of("x"));
+
+    assertThat(actualCodeBlock.toString())
+        .isEqualTo(
+            String.format(
+                "x.stream().map(%s.wrapper(value$ -> value$)).collect(%s.toImmutableList())",
+                FUNCTION_WITH_EXCEPTIONS, IMMUTABLE_LIST));
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableMapSerializerExtensionTest.java b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableMapSerializerExtensionTest.java
new file mode 100644
index 0000000..a7006f5
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/ImmutableMapSerializerExtensionTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
+
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;
+import com.google.auto.value.extension.serializable.serializer.utils.FakeSerializerFactory;
+import com.google.common.collect.ImmutableMap;
+import com.squareup.javapoet.CodeBlock;
+import java.util.Optional;
+import javax.lang.model.type.TypeMirror;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class ImmutableMapSerializerExtensionTest extends CompilationAbstractTest {
+
+  private static final String FUNCTION_WITH_EXCEPTIONS =
+      "com.google.auto.value.extension.serializable.serializer.runtime.FunctionWithExceptions";
+  private static final String IMMUTABLE_MAP = "com.google.common.collect.ImmutableMap";
+  private static final String INTEGER = "java.lang.Integer";
+  private static final String STRING = "java.lang.String";
+
+  private ImmutableMapSerializerExtension extension;
+  private FakeSerializerFactory fakeSerializerFactory;
+
+  @Before
+  public void setUpExtension() {
+    extension = new ImmutableMapSerializerExtension();
+    fakeSerializerFactory = new FakeSerializerFactory();
+    fakeSerializerFactory.setReturnIdentitySerializer(false);
+  }
+
+  @Test
+  public void getSerializer_nonImmutableMap_emptyReturned() {
+    TypeMirror typeMirror = typeMirrorOf(String.class);
+
+    Optional<Serializer> actualSerializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);
+
+    assertThat(actualSerializer).isEmpty();
+  }
+
+  @Test
+  public void getSerializer_immutableMapWithSerializableContainedTypes_emptyReturned() {
+    fakeSerializerFactory.setReturnIdentitySerializer(true);
+    TypeMirror typeMirror = typeMirrorOf(ImmutableMap.class);
+
+    Optional<Serializer> actualSerializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);
+
+    assertThat(actualSerializer).isEmpty();
+  }
+
+  @Test
+  public void getSerializer_immutableMap_serializerReturned() {
+    TypeMirror typeMirror = typeMirrorOf(ImmutableMap.class);
+
+    Serializer actualSerializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+
+    assertThat(actualSerializer.getClass().getName())
+        .contains("ImmutableMapSerializerExtension$ImmutableMapSerializer");
+  }
+
+  @Test
+  public void proxyFieldType() {
+    TypeMirror typeMirror = declaredTypeOf(ImmutableMap.class, Integer.class, String.class);
+
+    Serializer serializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+    TypeMirror actualTypeMirror = serializer.proxyFieldType();
+
+    assertThat(typeUtils.isSameType(actualTypeMirror, typeMirror)).isTrue();
+  }
+
+  @Test
+  public void toProxy() {
+    TypeMirror typeMirror = declaredTypeOf(ImmutableMap.class, Integer.class, String.class);
+
+    Serializer serializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+    CodeBlock actualCodeBlock = serializer.toProxy(CodeBlock.of("x"));
+
+    assertThat(actualCodeBlock.toString())
+        .isEqualTo(
+            String.format(
+                "x.entrySet().stream().collect(%s.toImmutableMap(value$ -> %s.<%s,"
+                    + " %s>wrapper(element$ -> element$).apply(value$.getKey()), value$ -> %s.<%s,"
+                    + " %s>wrapper(element$ -> element$).apply(value$.getValue())))",
+                IMMUTABLE_MAP,
+                FUNCTION_WITH_EXCEPTIONS,
+                INTEGER,
+                INTEGER,
+                FUNCTION_WITH_EXCEPTIONS,
+                STRING,
+                STRING));
+  }
+
+  @Test
+  public void fromProxy() {
+    TypeMirror typeMirror = declaredTypeOf(ImmutableMap.class, Integer.class, String.class);
+
+    Serializer serializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+    CodeBlock actualCodeBlock = serializer.fromProxy(CodeBlock.of("x"));
+
+    assertThat(actualCodeBlock.toString())
+        .isEqualTo(
+            String.format(
+                "x.entrySet().stream().collect(%s.toImmutableMap(value$ -> %s.<%s,"
+                    + " %s>wrapper(element$ -> element$).apply(value$.getKey()), value$ -> %s.<%s,"
+                    + " %s>wrapper(element$ -> element$).apply(value$.getValue())))",
+                IMMUTABLE_MAP,
+                FUNCTION_WITH_EXCEPTIONS,
+                INTEGER,
+                INTEGER,
+                FUNCTION_WITH_EXCEPTIONS,
+                STRING,
+                STRING));
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/OptionalSerializerExtensionTest.java b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/OptionalSerializerExtensionTest.java
new file mode 100644
index 0000000..e817911
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/OptionalSerializerExtensionTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
+
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;
+import com.google.auto.value.extension.serializable.serializer.utils.FakeSerializerFactory;
+import com.squareup.javapoet.CodeBlock;
+import java.util.Optional;
+import javax.lang.model.type.TypeMirror;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class OptionalSerializerExtensionTest extends CompilationAbstractTest {
+
+  private OptionalSerializerExtension extension;
+  private FakeSerializerFactory fakeSerializerFactory;
+
+  @Before
+  public void setUpExtension() {
+    extension = new OptionalSerializerExtension();
+    fakeSerializerFactory = new FakeSerializerFactory();
+  }
+
+  @Test
+  public void getSerializer_nonOptional_emptyReturned() {
+    TypeMirror typeMirror = typeMirrorOf(String.class);
+
+    Optional<Serializer> actualSerializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment);
+
+    assertThat(actualSerializer).isEmpty();
+  }
+
+  @Test
+  public void getSerializer_optional_serializerReturned() {
+    TypeMirror typeMirror = typeMirrorOf(Optional.class);
+
+    Serializer actualSerializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+
+    assertThat(actualSerializer.getClass().getName())
+        .contains("OptionalSerializerExtension$OptionalSerializer");
+  }
+
+  @Test
+  public void proxyFieldType() {
+    TypeMirror typeMirror = declaredTypeOf(Optional.class, Integer.class);
+
+    Serializer serializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+    TypeMirror actualTypeMirror = serializer.proxyFieldType();
+
+    assertThat(actualTypeMirror).isEqualTo(typeMirrorOf(Integer.class));
+  }
+
+  @Test
+  public void toProxy() {
+    TypeMirror typeMirror = declaredTypeOf(Optional.class, Integer.class);
+
+    Serializer serializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+    CodeBlock actualCodeBlock = serializer.toProxy(CodeBlock.of("x"));
+
+    assertThat(actualCodeBlock.toString()).isEqualTo("x.isPresent() ? x.get() : null");
+  }
+
+  @Test
+  public void fromProxy() {
+    TypeMirror typeMirror = declaredTypeOf(Optional.class, Integer.class);
+
+    Serializer serializer =
+        extension.getSerializer(typeMirror, fakeSerializerFactory, mockProcessingEnvironment).get();
+    CodeBlock actualCodeBlock = serializer.fromProxy(CodeBlock.of("x"));
+
+    assertThat(actualCodeBlock.toString())
+        .isEqualTo("java.util.Optional.ofNullable(x == null ? null : x)");
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/SerializerFactoryImplTest.java b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/SerializerFactoryImplTest.java
new file mode 100644
index 0000000..e5150f9
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/impl/SerializerFactoryImplTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.utils.CompilationAbstractTest;
+import com.google.auto.value.extension.serializable.serializer.utils.TestStringSerializerFactory;
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class SerializerFactoryImplTest extends CompilationAbstractTest {
+
+  @Test
+  public void getSerializer_emptyFactories_identitySerializerReturned() throws Exception {
+    SerializerFactoryImpl factory =
+        new SerializerFactoryImpl(ImmutableList.of(), mockProcessingEnvironment);
+
+    Serializer actualSerializer = factory.getSerializer(typeMirrorOf(String.class));
+
+    assertThat(actualSerializer.getClass().getName())
+        .contains("IdentitySerializerFactory$IdentitySerializer");
+  }
+
+  @Test
+  public void getSerializer_factoriesProvided_factoryReturned() throws Exception {
+    SerializerFactoryImpl factory =
+        new SerializerFactoryImpl(
+            ImmutableList.of(new TestStringSerializerFactory()), mockProcessingEnvironment);
+
+    Serializer actualSerializer = factory.getSerializer(typeMirrorOf(String.class));
+
+    assertThat(actualSerializer.getClass().getName())
+        .contains("TestStringSerializerFactory$TestStringSerializer");
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/CompilationAbstractTest.java b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/CompilationAbstractTest.java
new file mode 100644
index 0000000..0eb634a
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/CompilationAbstractTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.utils;
+
+import static org.mockito.Mockito.when;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.testing.compile.CompilationRule;
+import java.util.Arrays;
+import javax.annotation.processing.Messager;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+@RunWith(JUnit4.class)
+public abstract class CompilationAbstractTest {
+
+  @Rule public final CompilationRule compilationRule = new CompilationRule();
+  @Rule public final MockitoRule mockito = MockitoJUnit.rule();
+
+  @Mock protected ProcessingEnvironment mockProcessingEnvironment;
+  @Mock protected Messager mockMessager;
+
+  protected Types typeUtils;
+  protected Elements elementUtils;
+
+  @Before
+  public final void setUp() {
+    typeUtils = compilationRule.getTypes();
+    elementUtils = compilationRule.getElements();
+
+    when(mockProcessingEnvironment.getTypeUtils()).thenReturn(typeUtils);
+    when(mockProcessingEnvironment.getElementUtils()).thenReturn(elementUtils);
+    when(mockProcessingEnvironment.getMessager()).thenReturn(mockMessager);
+  }
+
+  protected TypeElement typeElementOf(Class<?> c) {
+    return elementUtils.getTypeElement(c.getCanonicalName());
+  }
+
+  protected TypeMirror typeMirrorOf(Class<?> c) {
+    return typeElementOf(c).asType();
+  }
+
+  protected DeclaredType declaredTypeOf(Class<?> enclosingClass, Class<?> containedClass) {
+    return typeUtils.getDeclaredType(typeElementOf(enclosingClass), typeMirrorOf(containedClass));
+  }
+
+  protected DeclaredType declaredTypeOf(Class<?> enclosingClass, Class<?>... classArgs) {
+    return typeUtils.getDeclaredType(
+        typeElementOf(enclosingClass),
+        Iterables.toArray(
+            Arrays.stream(classArgs)
+                .map(this::typeMirrorOf)
+                .collect(ImmutableList.toImmutableList()),
+            TypeMirror.class));
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/FakeSerializerFactory.java b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/FakeSerializerFactory.java
new file mode 100644
index 0000000..388977f
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/FakeSerializerFactory.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.utils;
+
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;
+import com.squareup.javapoet.CodeBlock;
+import javax.lang.model.type.TypeMirror;
+
+/** A fake {@link SerializerFactory} that returns an identity serializer used for tests. */
+public final class FakeSerializerFactory implements SerializerFactory {
+
+  private boolean isIdentity = true;
+
+  public FakeSerializerFactory() {}
+
+  /**
+   * Set if this factory should return a serializer that is considered an identity serializer.
+   *
+   * <p>The underlying fake serializer implementation will always be an identity serializer. This
+   * only changes the {@link Serializer#isIdentity} return value.
+   */
+  public void setReturnIdentitySerializer(boolean isIdentity) {
+    this.isIdentity = isIdentity;
+  }
+
+  @Override
+  public Serializer getSerializer(TypeMirror type) {
+    return new FakeIdentitySerializer(type, isIdentity);
+  }
+
+  private static class FakeIdentitySerializer implements Serializer {
+
+    private final TypeMirror typeMirror;
+    private final boolean isIdentity;
+
+    FakeIdentitySerializer(TypeMirror typeMirror, boolean isIdentity) {
+      this.typeMirror = typeMirror;
+      this.isIdentity = isIdentity;
+    }
+
+    @Override
+    public TypeMirror proxyFieldType() {
+      return typeMirror;
+    }
+
+    @Override
+    public CodeBlock toProxy(CodeBlock expression) {
+      return expression;
+    }
+
+    @Override
+    public CodeBlock fromProxy(CodeBlock expression) {
+      return expression;
+    }
+
+    @Override
+    public boolean isIdentity() {
+      return isIdentity;
+    }
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/TestStringSerializerFactory.java b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/TestStringSerializerFactory.java
new file mode 100644
index 0000000..7c0f204
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/extension/serializable/serializer/utils/TestStringSerializerFactory.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.extension.serializable.serializer.utils;
+
+import com.google.auto.common.MoreElements;
+import com.google.auto.common.MoreTypes;
+import com.google.auto.service.AutoService;
+import com.google.auto.value.extension.serializable.serializer.interfaces.Serializer;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerExtension;
+import com.google.auto.value.extension.serializable.serializer.interfaces.SerializerFactory;
+import com.squareup.javapoet.CodeBlock;
+import java.util.Optional;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+
+/** A test implementation of {@link SerializerExtension} that overwrites a string field's value. */
+@AutoService(SerializerExtension.class)
+public final class TestStringSerializerFactory implements SerializerExtension {
+
+  public TestStringSerializerFactory() {}
+
+  @Override
+  public Optional<Serializer> getSerializer(
+      TypeMirror typeMirror, SerializerFactory factory, ProcessingEnvironment processingEnv) {
+    if (typeMirror.getKind() != TypeKind.DECLARED) {
+      return Optional.empty();
+    }
+
+    DeclaredType declaredType = MoreTypes.asDeclared(typeMirror);
+    TypeElement typeElement = MoreElements.asType(declaredType.asElement());
+    if (typeElement.getQualifiedName().contentEquals("java.lang.String")) {
+      return Optional.of(new TestStringSerializer(typeMirror));
+    }
+
+    return Optional.empty();
+  }
+
+  private static class TestStringSerializer implements Serializer {
+
+    private final TypeMirror typeMirror;
+
+    TestStringSerializer(TypeMirror typeMirror) {
+      this.typeMirror = typeMirror;
+    }
+
+    @Override
+    public TypeMirror proxyFieldType() {
+      return typeMirror;
+    }
+
+    @Override
+    public CodeBlock toProxy(CodeBlock expression) {
+      return CodeBlock.of("$S", "test");
+    }
+
+    @Override
+    public CodeBlock fromProxy(CodeBlock expression) {
+      return CodeBlock.of("$S", "test");
+    }
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/AutoAnnotationCompilationTest.java b/value/src/test/java/com/google/auto/value/processor/AutoAnnotationCompilationTest.java
new file mode 100644
index 0000000..b8a36ea
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/AutoAnnotationCompilationTest.java
@@ -0,0 +1,473 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth8.assertThat;
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class AutoAnnotationCompilationTest {
+
+  @Test
+  public void testSimple() {
+    JavaFileObject myAnnotationJavaFile =
+        JavaFileObjects.forSourceLines(
+            "com.example.annotations.MyAnnotation",
+            "package com.example.annotations;",
+            "",
+            "import com.example.enums.MyEnum;",
+            "",
+            "public @interface MyAnnotation {",
+            "  MyEnum value();",
+            "  int defaultedValue() default 23;",
+            "}");
+    int invariableHash = ("defaultedValue".hashCode() * 127) ^ 23;
+    JavaFileObject myEnumJavaFile =
+        JavaFileObjects.forSourceLines(
+            "com.example.enums.MyEnum",
+            "package com.example.enums;",
+            "",
+            "public enum MyEnum {",
+            "  ONE",
+            "}");
+    JavaFileObject annotationFactoryJavaFile =
+        JavaFileObjects.forSourceLines(
+            "com.example.factories.AnnotationFactory",
+            "package com.example.factories;",
+            "",
+            "import com.google.auto.value.AutoAnnotation;",
+            "import com.example.annotations.MyAnnotation;",
+            "import com.example.enums.MyEnum;",
+            "",
+            "public class AnnotationFactory {",
+            "  @AutoAnnotation",
+            "  public static MyAnnotation newMyAnnotation(MyEnum value) {",
+            "    return new AutoAnnotation_AnnotationFactory_newMyAnnotation(value);",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation",
+            "package com.example.factories;",
+            "",
+            "import com.example.annotations.MyAnnotation;",
+            "import com.example.enums.MyEnum;",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"" + AutoAnnotationProcessor.class.getName() + "\")",
+            "final class AutoAnnotation_AnnotationFactory_newMyAnnotation",
+            "     implements MyAnnotation {",
+            "  private final MyEnum value;",
+            "  private static final int defaultedValue = 23;",
+            "",
+            "  AutoAnnotation_AnnotationFactory_newMyAnnotation(MyEnum value) {",
+            "    if (value == null) {",
+            "      throw new NullPointerException(\"Null value\");",
+            "    }",
+            "    this.value = value;",
+            "  }",
+            "",
+            "  @Override public Class<? extends MyAnnotation> annotationType() {",
+            "    return MyAnnotation.class;",
+            "  }",
+            "",
+            "  @Override public MyEnum value() {",
+            "    return value;",
+            "  }",
+            "",
+            "  @Override public int defaultedValue() {",
+            "    return defaultedValue;",
+            "  }",
+            "",
+            "  @Override public String toString() {",
+            "    StringBuilder sb = new StringBuilder(\"@com.example.annotations.MyAnnotation(\");",
+            "    sb.append(value);",
+            "    return sb.append(')').toString();",
+            "  }",
+            "",
+            "  @Override public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof MyAnnotation) {",
+            "      MyAnnotation that = (MyAnnotation) o;",
+            "      return value.equals(that.value())",
+            "          && (defaultedValue == that.defaultedValue());",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+            "  @Override public int hashCode() {",
+            "    return ",
+            "        " + invariableHash,
+            "        + (" + 127 * "value".hashCode() + " ^ value.hashCode())",
+            "    ;",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(annotationFactoryJavaFile, myAnnotationJavaFile, myEnumJavaFile);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile(
+            "com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  @Test
+  public void testEmptyPackage() {
+    JavaFileObject myAnnotationJavaFile =
+        JavaFileObjects.forSourceLines(
+            "MyAnnotation", //
+            "public @interface MyAnnotation {}");
+    JavaFileObject annotationFactoryJavaFile =
+        JavaFileObjects.forSourceLines(
+            "AnnotationFactory",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "public class AnnotationFactory {",
+            "  @AutoAnnotation",
+            "  public static MyAnnotation newMyAnnotation() {",
+            "    return new AutoAnnotation_AnnotationFactory_newMyAnnotation();",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "AutoAnnotation_AnnotationFactory_newMyAnnotation",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"" + AutoAnnotationProcessor.class.getName() + "\")",
+            "final class AutoAnnotation_AnnotationFactory_newMyAnnotation",
+            "    implements MyAnnotation {",
+            "  AutoAnnotation_AnnotationFactory_newMyAnnotation() {",
+            "  }",
+            "",
+            "  @Override public Class<? extends MyAnnotation> annotationType() {",
+            "    return MyAnnotation.class;",
+            "  }",
+            "",
+            "  @Override public String toString() {",
+            "    StringBuilder sb = new StringBuilder(\"@MyAnnotation(\");",
+            "    return sb.append(')').toString();",
+            "  }",
+            "",
+            "  @Override public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof MyAnnotation) {",
+            "      return true;",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+            "  @Override public int hashCode() {",
+            "    return 0;",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(annotationFactoryJavaFile, myAnnotationJavaFile);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("AutoAnnotation_AnnotationFactory_newMyAnnotation")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  @Test
+  public void testGwtSimple() {
+    JavaFileObject myAnnotationJavaFile =
+        JavaFileObjects.forSourceLines(
+            "com.example.annotations.MyAnnotation",
+            "package com.example.annotations;",
+            "",
+            "import com.google.common.annotations.GwtCompatible;",
+            "",
+            "@GwtCompatible",
+            "public @interface MyAnnotation {",
+            "  int[] value();",
+            "}");
+    JavaFileObject gwtCompatibleJavaFile =
+        JavaFileObjects.forSourceLines(
+            "com.google.common.annotations.GwtCompatible",
+            "package com.google.common.annotations;",
+            "",
+            "public @interface GwtCompatible {}");
+    JavaFileObject annotationFactoryJavaFile =
+        JavaFileObjects.forSourceLines(
+            "com.example.factories.AnnotationFactory",
+            "package com.example.factories;",
+            "",
+            "import com.google.auto.value.AutoAnnotation;",
+            "import com.example.annotations.MyAnnotation;",
+            "",
+            "public class AnnotationFactory {",
+            "  @AutoAnnotation",
+            "  public static MyAnnotation newMyAnnotation(int[] value) {",
+            "    return new AutoAnnotation_AnnotationFactory_newMyAnnotation(value);",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation",
+            "package com.example.factories;",
+            "",
+            "import com.example.annotations.MyAnnotation;",
+            "import java.util.Arrays;",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"" + AutoAnnotationProcessor.class.getName() + "\")",
+            "final class AutoAnnotation_AnnotationFactory_newMyAnnotation implements MyAnnotation"
+                + " {",
+            "  private final int[] value;",
+            "",
+            "  AutoAnnotation_AnnotationFactory_newMyAnnotation(int[] value) {",
+            "    if (value == null) {",
+            "      throw new NullPointerException(\"Null value\");",
+            "    }",
+            "    this.value = Arrays.copyOf(value, value.length);",
+            "  }",
+            "",
+            "  @Override public Class<? extends MyAnnotation> annotationType() {",
+            "    return MyAnnotation.class;",
+            "  }",
+            "",
+            "  @Override public int[] value() {",
+            "    return Arrays.copyOf(value, value.length);",
+            "  }",
+            "",
+            "  @Override public String toString() {",
+            "    StringBuilder sb = new StringBuilder(\"@com.example.annotations.MyAnnotation(\");",
+            "    sb.append(Arrays.toString(value));",
+            "    return sb.append(')').toString();",
+            "  }",
+            "",
+            "  @Override public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof MyAnnotation) {",
+            "      MyAnnotation that = (MyAnnotation) o;",
+            "      return Arrays.equals(value,",
+            "          (that instanceof AutoAnnotation_AnnotationFactory_newMyAnnotation)",
+            "              ? ((AutoAnnotation_AnnotationFactory_newMyAnnotation) that).value",
+            "              : that.value());",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+            "  @Override public int hashCode() {",
+            "    return ",
+            "        + (" + 127 * "value".hashCode() + " ^ Arrays.hashCode(value));",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(annotationFactoryJavaFile, myAnnotationJavaFile, gwtCompatibleJavaFile);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile(
+            "com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  @Test
+  public void testCollectionsForArrays() {
+    JavaFileObject myAnnotationJavaFile =
+        JavaFileObjects.forSourceLines(
+            "com.example.annotations.MyAnnotation",
+            "package com.example.annotations;",
+            "",
+            "import com.example.enums.MyEnum;",
+            "",
+            "public @interface MyAnnotation {",
+            "  int[] value();",
+            "  MyEnum[] enums() default {};",
+            "}");
+    JavaFileObject myEnumJavaFile =
+        JavaFileObjects.forSourceLines(
+            "com.example.enums.MyEnum",
+            "package com.example.enums;",
+            "",
+            "public enum MyEnum {",
+            "  ONE",
+            "}");
+    JavaFileObject annotationFactoryJavaFile =
+        JavaFileObjects.forSourceLines(
+            "com.example.factories.AnnotationFactory",
+            "package com.example.factories;",
+            "",
+            "import com.google.auto.value.AutoAnnotation;",
+            "import com.example.annotations.MyAnnotation;",
+            "import com.example.enums.MyEnum;",
+            "",
+            "import java.util.List;",
+            "import java.util.Set;",
+            "",
+            "public class AnnotationFactory {",
+            "  @AutoAnnotation",
+            "  public static MyAnnotation newMyAnnotation(",
+            "      List<Integer> value, Set<MyEnum> enums) {",
+            "    return new AutoAnnotation_AnnotationFactory_newMyAnnotation(value, enums);",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation",
+            "package com.example.factories;",
+            "",
+            "import com.example.annotations.MyAnnotation;",
+            "import com.example.enums.MyEnum;",
+            "import java.util.Arrays;",
+            "import java.util.Collection;",
+            "import java.util.List;",
+            "import java.util.Set;",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"" + AutoAnnotationProcessor.class.getName() + "\")",
+            "final class AutoAnnotation_AnnotationFactory_newMyAnnotation implements MyAnnotation"
+                + " {",
+            "  private final int[] value;",
+            "  private final MyEnum[] enums;",
+            "",
+            "  AutoAnnotation_AnnotationFactory_newMyAnnotation(",
+            "      List<Integer> value,",
+            "      Set<MyEnum> enums) {",
+            "    if (value == null) {",
+            "      throw new NullPointerException(\"Null value\");",
+            "    }",
+            "    this.value = intArrayFromCollection(value);",
+            "    if (enums == null) {",
+            "      throw new NullPointerException(\"Null enums\");",
+            "    }",
+            "    this.enums = enums.toArray(new MyEnum[0];",
+            "  }",
+            "",
+            "  @Override public Class<? extends MyAnnotation> annotationType() {",
+            "    return MyAnnotation.class;",
+            "  }",
+            "",
+            "  @Override public int[] value() {",
+            "    return value.clone();",
+            "  }",
+            "",
+            "  @Override public MyEnum[] enums() {",
+            "    return enums.clone();",
+            "  }",
+            "",
+            "  @Override public String toString() {",
+            "    StringBuilder sb = new StringBuilder(\"@com.example.annotations.MyAnnotation(\");",
+            "    sb.append(\"value=\");",
+            "    sb.append(Arrays.toString(value));",
+            "    sb.append(\", \");",
+            "    sb.append(\"enums=\");",
+            "    sb.append(Arrays.toString(enums));",
+            "    return sb.append(')').toString();",
+            "  }",
+            "",
+            "  @Override public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof MyAnnotation) {",
+            "      MyAnnotation that = (MyAnnotation) o;",
+            "      return Arrays.equals(value,",
+            "          (that instanceof AutoAnnotation_AnnotationFactory_newMyAnnotation)",
+            "              ? ((AutoAnnotation_AnnotationFactory_newMyAnnotation) that).value",
+            "              : that.value())",
+            "          && Arrays.equals(enums,",
+            "          (that instanceof AutoAnnotation_AnnotationFactory_newMyAnnotation)",
+            "              ? ((AutoAnnotation_AnnotationFactory_newMyAnnotation) that).enums",
+            "              : that.enums())",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+            "  @Override public int hashCode() {",
+            "    return ",
+            "        + (" + 127 * "value".hashCode() + " ^ Arrays.hashCode(value))",
+            "        + (" + 127 * "enums".hashCode() + " ^ Arrays.hashCode(enums));",
+            "  }",
+            "",
+            "  private static int[] intArrayFromCollection(Collection<Integer> c) {",
+            "    int[] a = new int[c.size()];",
+            "    int i = 0;",
+            "    for (int x : c) {",
+            "      a[i++] = x;",
+            "    }",
+            "    return a;",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(annotationFactoryJavaFile, myEnumJavaFile, myAnnotationJavaFile);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile(
+            "com.example.factories.AutoAnnotation_AnnotationFactory_newMyAnnotation")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  @Test
+  public void testMissingClass() {
+    // Test that referring to an undefined annotation does not trigger @AutoAnnotation processing.
+    // The class Erroneous references an undefined annotation @NotAutoAnnotation. If we didn't have
+    // any special treatment of undefined types then we could run into a compiler bug where
+    // AutoAnnotationProcessor would think that a method annotated with @NotAutoAnnotation was in
+    // fact annotated with @AutoAnnotation. As it is, we do get an error about @NotAutoAnnotation
+    // being undefined, and we do not get an error complaining that this supposed @AutoAnnotation
+    // method is not static. We do need to have @AutoAnnotation appear somewhere so that the
+    // processor will run.
+    JavaFileObject erroneousJavaFileObject =
+        JavaFileObjects.forSourceLines(
+            "com.example.annotations.Erroneous",
+            "package com.example.annotations;",
+            "",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "public class Erroneous {",
+            "  @interface Empty {}",
+            "  @AutoAnnotation static Empty newEmpty() {}",
+            "  @NotAutoAnnotation Empty notNewEmpty() {}",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(erroneousJavaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("NotAutoAnnotation")
+        .inFile(erroneousJavaFileObject)
+        .onLineContaining("@NotAutoAnnotation");
+    assertThat(
+            compilation.errors().stream()
+                .map(diag -> diag.getMessage(null))
+                .filter(m -> m.contains("static")))
+        .isEmpty();
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/AutoAnnotationErrorsTest.java b/value/src/test/java/com/google/auto/value/processor/AutoAnnotationErrorsTest.java
new file mode 100644
index 0000000..55a4c5d
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/AutoAnnotationErrorsTest.java
@@ -0,0 +1,408 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for compilation errors with the AutoAnnotation processor.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class AutoAnnotationErrorsTest {
+  private static final JavaFileObject TEST_ANNOTATION =
+      JavaFileObjects.forSourceLines(
+          "com.example.TestAnnotation",
+          "package com.example;",
+          "",
+          "public @interface TestAnnotation {",
+          "  int value();",
+          "}");
+
+  @Test
+  public void testCorrect() {
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(int value) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(TEST_ANNOTATION, testSource);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void testNotStatic() {
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation TestAnnotation newTestAnnotation(int value) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(TEST_ANNOTATION, testSource);
+    assertThat(compilation)
+        .hadErrorContaining("must be static")
+        .inFile(testSource)
+        .onLineContaining("TestAnnotation newTestAnnotation(int value)");
+  }
+
+  @Test
+  public void testDoesNotReturnAnnotation() {
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static String newString(int value) {",
+            "    return new AutoAnnotation_Test_newString(value);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(TEST_ANNOTATION, testSource);
+    assertThat(compilation)
+        .hadErrorContaining("must be an annotation type, not java.lang.String")
+        .inFile(testSource)
+        .onLineContaining("static String newString(int value)");
+  }
+
+  @Test
+  public void testOverload() {
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(int value) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+            "  }",
+            "",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(Integer value) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(TEST_ANNOTATION, testSource);
+    assertThat(compilation)
+        .hadErrorContaining("@AutoAnnotation methods cannot be overloaded")
+        .inFile(testSource)
+        .onLineContaining("newTestAnnotation(Integer value)");
+  }
+
+  // Overload detection used to detect all @AutoAnnotation methods that resulted in
+  // annotation class of the same SimpleName as being an overload.
+  // This verifies that implementations in different packages work correctly.
+  @Test
+  public void testSameNameDifferentPackagesDoesNotTriggerOverload() {
+
+    JavaFileObject fooTestSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(int value) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+            "  }",
+            "}");
+    JavaFileObject barTestSource =
+        JavaFileObjects.forSourceLines(
+            "com.bar.Test",
+            "package com.bar;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(int value) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(fooTestSource, barTestSource, TEST_ANNOTATION);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void testWrongName() {
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(int fred) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(fred);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(TEST_ANNOTATION, testSource);
+    assertThat(compilation)
+        .hadErrorContaining("method parameter 'fred' must have the same name")
+        .inFile(testSource)
+        .onLineContaining("newTestAnnotation(int fred)");
+  }
+
+  @Test
+  public void testWrongType() {
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(String value) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(TEST_ANNOTATION, testSource);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "method parameter 'value' has type java.lang.String "
+                + "but com.example.TestAnnotation.value has type int")
+        .inFile(testSource)
+        .onLineContaining("newTestAnnotation(String value)");
+  }
+
+  @Test
+  public void testWrongTypeCollection() {
+    JavaFileObject testAnnotation =
+        JavaFileObjects.forSourceLines(
+            "com.example.TestAnnotation",
+            "package com.example;",
+            "",
+            "public @interface TestAnnotation {",
+            "  int[] value();",
+            "}");
+    String[] wrongTypes = {
+      "java.util.List<java.lang.Long>",
+      "java.util.List<java.lang.String>",
+      "java.util.Set<java.lang.Long>",
+      "java.util.Map<java.lang.Integer,java.lang.Integer>",
+      "java.util.concurrent.Callable<java.lang.Integer>",
+      "java.util.List<int[]>",
+    };
+    for (String wrongType : wrongTypes) {
+      JavaFileObject testSource =
+          JavaFileObjects.forSourceLines(
+              "com.foo.Test",
+              "package com.foo;",
+              "",
+              "import com.example.TestAnnotation;",
+              "import com.google.auto.value.AutoAnnotation;",
+              "",
+              "class Test {",
+              "  @AutoAnnotation static TestAnnotation newTestAnnotation("
+                  + wrongType
+                  + " value) {",
+              "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+              "  }",
+              "}");
+      Compilation compilation =
+          javac()
+              .withProcessors(new AutoAnnotationProcessor())
+              .compile(testSource, testAnnotation);
+      assertThat(compilation)
+          .hadErrorContaining(
+              "method parameter 'value' has type "
+                  + wrongType
+                  + " but com.example.TestAnnotation.value has type int[]")
+          .inFile(testSource)
+          .onLineContaining("TestAnnotation newTestAnnotation(");
+    }
+  }
+
+  @Test
+  public void testExtraParameters() {
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(int value, int other) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(TEST_ANNOTATION, testSource);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "method parameter 'other' must have the same name as a member of "
+                + "com.example.TestAnnotation")
+        .inFile(testSource)
+        .onLineContaining("newTestAnnotation(int value, int other)");
+  }
+
+  @Test
+  public void testMissingParameters() {
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation() {",
+            "    return new AutoAnnotation_Test_newTestAnnotation();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(TEST_ANNOTATION, testSource);
+    assertThat(compilation)
+        .hadErrorContaining("method needs a parameter with name 'value' and type int")
+        .inFile(testSource)
+        .onLineContaining("TestAnnotation newTestAnnotation()");
+  }
+
+  @Test
+  public void testAnnotationValuedDefaultsNotSupportedYet() {
+    JavaFileObject annotationSource =
+        JavaFileObjects.forSourceLines(
+            "com.example.TestAnnotation",
+            "package com.example;",
+            "",
+            "public @interface TestAnnotation {",
+            "  String value();",
+            "  Override optionalAnnotation() default @Override;",
+            "}");
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(String value) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(annotationSource, testSource);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "@AutoAnnotation cannot yet supply a default value for annotation-valued member "
+                + "'optionalAnnotation'")
+        .inFile(testSource)
+        .onLineContaining("TestAnnotation newTestAnnotation(String value)");
+  }
+
+  @Test
+  public void testAnnotationMemberNameConflictWithGeneratedLocal() {
+    JavaFileObject annotationSource =
+        JavaFileObjects.forSourceLines(
+            "com.example.TestAnnotation",
+            "package com.example;",
+            "",
+            "import java.lang.annotation.Annotation;",
+            "",
+            "public @interface TestAnnotation {",
+            "  Class<? extends Annotation>[] value();",
+            "  int value$();",
+            "}");
+    JavaFileObject testSource =
+        JavaFileObjects.forSourceLines(
+            "com.foo.Test",
+            "package com.foo;",
+            "",
+            "import java.lang.annotation.Annotation;",
+            "import java.util.Collection;",
+            "",
+            "import com.example.TestAnnotation;",
+            "import com.google.auto.value.AutoAnnotation;",
+            "",
+            "class Test {",
+            "  @AutoAnnotation static TestAnnotation newTestAnnotation(",
+            "     Collection<Class<? extends Annotation>> value, int value$) {",
+            "    return new AutoAnnotation_Test_newTestAnnotation(value, value$);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoAnnotationProcessor())
+            .compile(annotationSource, testSource);
+    assertThat(compilation)
+        .hadErrorContaining("variable value$ is already defined in constructor");
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/AutoOneOfCompilationTest.java b/value/src/test/java/com/google/auto/value/processor/AutoOneOfCompilationTest.java
new file mode 100644
index 0000000..63e8419
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/AutoOneOfCompilationTest.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+
+import com.google.common.truth.Expect;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.JavaFileObjects;
+import javax.tools.JavaFileObject;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class AutoOneOfCompilationTest {
+  @Rule public final Expect expect = Expect.create();
+
+  @Test
+  public void success() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.TaskResult",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoOneOf;",
+            "import java.io.Serializable;",
+            "",
+            "@AutoOneOf(TaskResult.Kind.class)",
+            "public abstract class TaskResult<V, T extends Throwable> {",
+            "  public enum Kind {VALUE, EXCEPTION, EMPTY}",
+            "  public abstract Kind getKind();",
+            "",
+            "  public abstract V value();",
+            "  public abstract Throwable exception();",
+            "  public abstract void empty();",
+            "",
+            "  public static <V> TaskResult<V, ?> value(V value) {",
+            "    return AutoOneOf_TaskResult.value(value);",
+            "  }",
+            "",
+            "  public static <T extends Throwable> TaskResult<?, T> exception(T exception) {",
+            "    return AutoOneOf_TaskResult.exception(exception);",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoOneOf_TaskResult",
+            "package foo.bar;",
+            "",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"com.google.auto.value.processor.AutoOneOfProcessor\")",
+            "final class AutoOneOf_TaskResult {",
+            "  private AutoOneOf_TaskResult() {} // There are no instances of this type.",
+            "",
+            "  static <V, T extends Throwable> TaskResult<V, T> value(V value) {",
+            "    if (value == null) {",
+            "      throw new NullPointerException();",
+            "    }",
+            "    return new Impl_value<V, T>(value);",
+            "  }",
+            "",
+            "  static <V, T extends Throwable> TaskResult<V, T> exception(Throwable exception) {",
+            "    if (exception == null) {",
+            "      throw new NullPointerException();",
+            "    }",
+            "    return new Impl_exception<V, T>(exception);",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"unchecked\") // type parameters are unused in void instances",
+            "  static <V, T extends Throwable> TaskResult<V, T> empty() {",
+            "    return (TaskResult<V, T>) Impl_empty.INSTANCE;",
+            "  }",
+            "",
+            "  // Parent class that each implementation will inherit from.",
+            "  private abstract static class Parent_<V, T extends Throwable> "
+                + "extends TaskResult<V, T> {",
+            "    @Override",
+            "    public V value() {",
+            "      throw new UnsupportedOperationException(getKind().toString());",
+            "    }",
+            "",
+            "    @Override",
+            "    public Throwable exception() {",
+            "      throw new UnsupportedOperationException(getKind().toString());",
+            "    }",
+            "",
+            "    @Override",
+            "    public void empty() {",
+            "      throw new UnsupportedOperationException(getKind().toString());",
+            "    }",
+            "  }",
+            "",
+            "  // Implementation when the contained property is \"value\".",
+            "  private static final class Impl_value<V, T extends Throwable> "
+                + "extends Parent_<V, T> {",
+            "    private final V value;",
+            "",
+            "    Impl_value(V value) {",
+            "      this.value = value;",
+            "    }",
+            "",
+            "    @Override",
+            "    public V value() {",
+            "      return value;",
+            "    }",
+            "",
+            "    @Override",
+            "    public String toString() {",
+            "      return \"TaskResult{value=\" + this.value + \"}\";",
+            "    }",
+            "",
+            "    @Override",
+            "    public boolean equals(Object x) {",
+            "      if (x instanceof TaskResult) {",
+            "        TaskResult<?, ?> that = (TaskResult<?, ?>) x;",
+            "        return this.getKind() == that.getKind()",
+            "            && this.value.equals(that.value());",
+            "      } else {",
+            "        return false;",
+            "      }",
+            "    }",
+            "",
+            "    @Override",
+            "    public int hashCode() {",
+            "      return value.hashCode();",
+            "    }",
+            "",
+            "    @Override",
+            "    public TaskResult.Kind getKind() {",
+            "      return TaskResult.Kind.VALUE;",
+            "    }",
+            "  }",
+            "",
+            "  // Implementation when the contained property is \"exception\".",
+            "  private static final class Impl_exception<V, T extends Throwable> "
+                + "extends Parent_<V, T> {",
+            "    private final Throwable exception;",
+            "",
+            "    Impl_exception(Throwable exception) {",
+            "      this.exception = exception;",
+            "    }",
+            "",
+            "    @Override",
+            "    public Throwable exception() {",
+            "      return exception;",
+            "    }",
+            "",
+            "    @Override",
+            "    public String toString() {",
+            "      return \"TaskResult{exception=\" + this.exception + \"}\";",
+            "    }",
+            "",
+            "    @Override",
+            "    public boolean equals(Object x) {",
+            "      if (x instanceof TaskResult) {",
+            "        TaskResult<?, ?> that = (TaskResult<?, ?>) x;",
+            "        return this.getKind() == that.getKind()",
+            "            && this.exception.equals(that.exception());",
+            "      } else {",
+            "        return false;",
+            "      }",
+            "    }",
+            "",
+            "    @Override",
+            "    public int hashCode() {",
+            "      return exception.hashCode();",
+            "    }",
+            "",
+            "    @Override",
+            "    public TaskResult.Kind getKind() {",
+            "      return TaskResult.Kind.EXCEPTION;",
+            "    }",
+            "  }",
+            "",
+            "  // Implementation when the contained property is \"empty\".",
+            "  private static final class Impl_empty<V, T extends Throwable> "
+                + "extends Parent_<V, T> {",
+            "    static final Impl_empty<?, ?> INSTANCE = new Impl_empty<>();",
+            "",
+            "    private Impl_empty() {}",
+            "",
+            "    @Override",
+            "    public void empty() {}",
+            "",
+            "    @Override",
+            "    public String toString() {",
+            "      return \"TaskResult{empty}\";",
+            "    }",
+            "",
+            "    @Override",
+            "    public boolean equals(Object x) {",
+            "      return x == this;",
+            "    }",
+            "",
+            "    @Override",
+            "    public int hashCode() {",
+            "      return System.identityHashCode(this);",
+            "    }",
+            "",
+            "    @Override",
+            "    public TaskResult.Kind getKind() {",
+            "      return TaskResult.Kind.EMPTY;",
+            "    }",
+            "  }");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoOneOfProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoOneOf_TaskResult")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  @Test
+  public void voidInstanceWithoutGenericTypeParameters() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Nothing",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoOneOf;",
+            "import java.io.Serializable;",
+            "",
+            "@AutoOneOf(Nothing.Kind.class)",
+            "abstract class Nothing {",
+            "",
+            "  enum Kind {NOTHING}",
+            "",
+            "  abstract Kind kind();",
+            "",
+            "  abstract void nothing();",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Nothing",
+            "package foo.bar;",
+            "",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"com.google.auto.value.processor.AutoOneOfProcessor\")",
+            "final class AutoOneOf_Nothing {",
+            "  private AutoOneOf_Nothing() {} // There are no instances of this type.",
+            "",
+            "  static Nothing nothing() {",
+            "    return Impl_nothing.INSTANCE;",
+            "  }",
+            "",
+            "  // Parent class that each implementation will inherit from.",
+            "  private abstract static class Parent_ extends Nothing {",
+            "    @Override",
+            "    void nothing() {",
+            "      throw new UnsupportedOperationException(kind().toString());",
+            "    }",
+            "  }",
+            "",
+            "  // Implementation when the contained property is \"nothing\".",
+            "  private static final class Impl_nothing extends Parent_ {",
+            "    // There is only one instance of this class.",
+            "    static final Impl_nothing INSTANCE = new Impl_nothing();",
+            "",
+            "    private Impl_nothing() {}",
+            "",
+            "    @Override",
+            "    public void nothing() {}",
+            "",
+            "    @Override",
+            "    public String toString() {",
+            "      return \"Nothing{nothing}\";",
+            "    }",
+            "",
+            "    @Override",
+            "    public boolean equals(Object x) {",
+            "      return x == this;",
+            "    }",
+            "",
+            "    @Override",
+            "    public int hashCode() {",
+            "      return System.identityHashCode(this);",
+            "    }",
+            "",
+            "    @Override",
+            "    public Nothing.Kind kind() {",
+            "      return Nothing.Kind.NOTHING;",
+            "    }",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoOneOfProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoOneOf_Nothing")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  @Test
+  public void noKindGetter() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Pet",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoOneOf;",
+            "",
+            "@AutoOneOf(Pet.Kind.class)",
+            "public abstract class Pet {",
+            "  public enum Kind {DOG, CAT}",
+            "  public abstract String dog();",
+            "  public abstract String cat();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "foo.bar.Pet must have a no-arg abstract method returning foo.bar.Pet.Kind")
+        .inFile(javaFileObject)
+        .onLineContaining("class Pet");
+  }
+
+  @Test
+  public void kindGetterHasParam() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Pet",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoOneOf;",
+            "",
+            "@AutoOneOf(Pet.Kind.class)",
+            "public abstract class Pet {",
+            "  public enum Kind {DOG, CAT}",
+            "  public abstract Kind getKind(String wut);",
+            "  public abstract String dog();",
+            "  public abstract String cat();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "foo.bar.Pet must have a no-arg abstract method returning foo.bar.Pet.Kind")
+        .inFile(javaFileObject)
+        .onLineContaining("class Pet");
+  }
+
+  @Test
+  public void twoKindGetters() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Pet",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoOneOf;",
+            "",
+            "@AutoOneOf(Pet.Kind.class)",
+            "public abstract class Pet {",
+            "  public enum Kind {DOG, CAT}",
+            "  public abstract Kind getKind();",
+            "  public abstract Kind alsoGetKind();",
+            "  public abstract String dog();",
+            "  public abstract String cat();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("More than one abstract method returns foo.bar.Pet.Kind")
+        .inFile(javaFileObject)
+        .onLineContaining("getKind");
+    assertThat(compilation)
+        .hadErrorContaining("More than one abstract method returns foo.bar.Pet.Kind")
+        .inFile(javaFileObject)
+        .onLineContaining("alsoGetKind");
+  }
+
+  @Test
+  public void enumMissingCase() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Pet",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoOneOf;",
+            "",
+            "@AutoOneOf(Pet.Kind.class)",
+            "public abstract class Pet {",
+            "  public enum Kind {DOG}",
+            "  public abstract Kind getKind();",
+            "  public abstract String dog();",
+            "  public abstract String cat();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Enum has no constant with name corresponding to property 'cat'")
+        .inFile(javaFileObject)
+        .onLineContaining("enum Kind");
+  }
+
+  @Test
+  public void enumExtraCase() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Pet",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoOneOf;",
+            "",
+            "@AutoOneOf(Pet.Kind.class)",
+            "public abstract class Pet {",
+            "  public enum Kind {",
+            "    DOG,",
+            "    CAT,",
+            "    GERBIL,",
+            "  }",
+            "  public abstract Kind getKind();",
+            "  public abstract String dog();",
+            "  public abstract String cat();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Name of enum constant 'GERBIL' does not correspond to any property name")
+        .inFile(javaFileObject)
+        .onLineContaining("GERBIL");
+  }
+
+  @Test
+  public void cantBeNullable() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Pet",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoOneOf;",
+            "",
+            "@AutoOneOf(Pet.Kind.class)",
+            "public abstract class Pet {",
+            "  @interface Nullable {}",
+            "",
+            "  public enum Kind {",
+            "    DOG,",
+            "    CAT,",
+            "  }",
+            "  public abstract Kind getKind();",
+            "  public abstract @Nullable String dog();",
+            "  public abstract String cat();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoOneOfProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("@AutoOneOf properties cannot be @Nullable")
+        .inFile(javaFileObject)
+        .onLineContaining("@Nullable String dog()");
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/AutoValueCompilationTest.java b/value/src/test/java/com/google/auto/value/processor/AutoValueCompilationTest.java
new file mode 100644
index 0000000..2d4aa7c
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/AutoValueCompilationTest.java
@@ -0,0 +1,3337 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.CompilationSubject.compilations;
+import static com.google.testing.compile.Compiler.javac;
+import static java.util.stream.Collectors.joining;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.truth.Expect;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.JavaFileObjects;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.util.ElementFilter;
+import javax.tools.JavaFileObject;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class AutoValueCompilationTest {
+  @Rule public final Expect expect = Expect.create();
+
+  @Test
+  public void simpleSuccess() {
+    // Positive test case that ensures we generate the expected code for at least one case.
+    // Most AutoValue code-generation tests are functional, meaning that we check that the generated
+    // code does the right thing rather than checking what it looks like, but this test is a sanity
+    // check that we are not generating correct but weird code.
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract long buh();",
+            "",
+            "  public static Baz create(long buh) {",
+            "    return new AutoValue_Baz(buh);",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoValue_Baz",
+            "package foo.bar;",
+            "",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"" + AutoValueProcessor.class.getName() + "\")",
+            "final class AutoValue_Baz extends Baz {",
+            "  private final long buh;",
+            "",
+            "  AutoValue_Baz(long buh) {",
+            "    this.buh = buh;",
+            "  }",
+            "",
+            "  @Override public long buh() {",
+            "    return buh;",
+            "  }",
+            "",
+            "  @Override public String toString() {",
+            "    return \"Baz{\"",
+            "        + \"buh=\" + buh",
+            "        + \"}\";",
+            "  }",
+            "",
+            "  @Override public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof Baz) {",
+            "      Baz that = (Baz) o;",
+            "      return this.buh == that.buh();",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+            "  @Override public int hashCode() {",
+            "    int h$ = 1;",
+            "    h$ *= 1000003;",
+            "    h$ ^= (int) ((buh >>> 32) ^ buh);",
+            "    return h$;",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  @Test
+  public void importTwoWays() {
+    // Test that referring to the same class in two different ways does not confuse the import logic
+    // into thinking it is two different classes and that therefore it can't import. The code here
+    // is nonsensical but successfully reproduces a real problem, which is that a TypeMirror that is
+    // extracted using Elements.getTypeElement(name).asType() does not compare equal to one that is
+    // extracted from ExecutableElement.getReturnType(), even though Types.isSameType considers them
+    // equal. So unless we are careful, the java.util.Arrays that we import explicitly to use its
+    // methods will appear different from the java.util.Arrays that is the return type of the
+    // arrays() method here.
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "import java.util.Arrays;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  @SuppressWarnings(\"mutable\")",
+            "  public abstract int[] ints();",
+            "  public abstract Arrays arrays();",
+            "",
+            "  public static Baz create(int[] ints, Arrays arrays) {",
+            "    return new AutoValue_Baz(ints, arrays);",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoValue_Baz",
+            "package foo.bar;",
+            "",
+            "import java.util.Arrays;",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"" + AutoValueProcessor.class.getName() + "\")",
+            "final class AutoValue_Baz extends Baz {",
+            "  private final int[] ints;",
+            "  private final Arrays arrays;",
+            "",
+            "  AutoValue_Baz(int[] ints, Arrays arrays) {",
+            "    if (ints == null) {",
+            "      throw new NullPointerException(\"Null ints\");",
+            "    }",
+            "    this.ints = ints;",
+            "    if (arrays == null) {",
+            "      throw new NullPointerException(\"Null arrays\");",
+            "    }",
+            "    this.arrays = arrays;",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"mutable\")",
+            "  @Override public int[] ints() {",
+            "    return ints;",
+            "  }",
+            "",
+            "  @Override public Arrays arrays() {",
+            "    return arrays;",
+            "  }",
+            "",
+            "  @Override public String toString() {",
+            "    return \"Baz{\"",
+            "        + \"ints=\" + Arrays.toString(ints) + \", \"",
+            "        + \"arrays=\" + arrays",
+            "        + \"}\";",
+            "  }",
+            "",
+            "  @Override public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof Baz) {",
+            "      Baz that = (Baz) o;",
+            "      return Arrays.equals(this.ints, (that instanceof AutoValue_Baz) "
+                + "? ((AutoValue_Baz) that).ints : that.ints())",
+            "          && this.arrays.equals(that.arrays());",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+            "  @Override public int hashCode() {",
+            "    int h$ = 1;",
+            "    h$ *= 1000003;",
+            "    h$ ^= Arrays.hashCode(ints);",
+            "    h$ *= 1000003;",
+            "    h$ ^= arrays.hashCode();",
+            "    return h$;",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  @Test
+  public void testNoWarningsFromGenerics() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue",
+            "public abstract class Baz<T extends Number, U extends T> {",
+            "  public abstract T t();",
+            "  public abstract U u();",
+            "  public static <T extends Number, U extends T> Baz<T, U> create(T t, U u) {",
+            "    return new AutoValue_Baz<T, U>(t, u);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void testNestedParameterizedTypesWithTypeAnnotations() {
+    JavaFileObject annotFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Annot",
+            "package foo.bar;",
+            "",
+            "import java.lang.annotation.ElementType;",
+            "import java.lang.annotation.Target;",
+            "",
+            "@Target(ElementType.TYPE_USE)",
+            "public @interface Annot {",
+            "  int value();",
+            "}");
+    JavaFileObject outerFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.baz.OuterWithTypeParam",
+            "package foo.baz;",
+            "",
+            "public class OuterWithTypeParam<T extends Number> {",
+            "  public class InnerWithTypeParam<U> {}",
+            "}");
+    JavaFileObject nestyFileObject =
+        JavaFileObjects.forSourceLines(
+            "com.example.Nesty",
+            "package com.example;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import foo.bar.Annot;",
+            "import foo.baz.OuterWithTypeParam;",
+            "",
+            "@AutoValue",
+            "abstract class Nesty {",
+            "  abstract @Annot(1) OuterWithTypeParam<@Annot(2) Double>",
+            "      .@Annot(3) InnerWithTypeParam<@Annot(4) String> inner();",
+            "",
+            "  static Nesty of(",
+            "      @Annot(1) OuterWithTypeParam<@Annot(2) Double>",
+            "          .@Annot(3) InnerWithTypeParam<@Annot(4) String> inner) {",
+            "    return new AutoValue_Nesty(inner);",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "com.example.AutoValue_Nesty",
+            "package com.example;",
+            "",
+            "import foo.bar.Annot;",
+            "import foo.baz.OuterWithTypeParam;",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"com.google.auto.value.processor.AutoValueProcessor\")",
+            "final class AutoValue_Nesty extends Nesty {",
+            "  private final @Annot(1) OuterWithTypeParam<@Annot(2) Double>"
+                + ".@Annot(3) InnerWithTypeParam<@Annot(4) String> inner;",
+            "",
+            "  AutoValue_Nesty(",
+            "      @Annot(1) OuterWithTypeParam<@Annot(2) Double>"
+                + ".@Annot(3) InnerWithTypeParam<@Annot(4) String> inner) {",
+            "    if (inner == null) {",
+            "      throw new NullPointerException(\"Null inner\");",
+            "    }",
+            "    this.inner = inner;",
+            "  }",
+            "",
+            "  @Override",
+            "  @Annot(1) OuterWithTypeParam<@Annot(2) Double>"
+                + ".@Annot(3) InnerWithTypeParam<@Annot(4) String> inner() {",
+            "    return inner;",
+            "  }",
+            "",
+            "  @Override",
+            "  public String toString() {",
+            "    return \"Nesty{\"",
+            "        + \"inner=\" + inner",
+            "        + \"}\";",
+            "  }",
+            "",
+            "  @Override",
+            "  public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof Nesty) {",
+            "      Nesty that = (Nesty) o;",
+            "      return this.inner.equals(that.inner());",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+
+            "  @Override",
+            "  public int hashCode() {",
+            "    int h$ = 1;",
+            "    h$ *= 1000003;",
+            "    h$ ^= inner.hashCode();",
+            "    return h$;",
+            "  }",
+            "}");
+
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(annotFileObject, outerFileObject, nestyFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("com.example.AutoValue_Nesty")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  // Tests that type annotations are correctly copied from the bounds of type parameters in the
+  // @AutoValue class to the bounds of the corresponding parameters in the generated class. For
+  // example, if we have `@AutoValue abstract class Foo<T extends @NullableType Object>`, then the
+  // generated class should be `class AutoValue_Foo<T extends @NullableType Object> extends Foo<T>`.
+  // Some buggy versions of javac do not report type annotations correctly in this context.
+  // AutoValue can't copy them if it can't see them, so we make a special annotation processor to
+  // detect if we are in the presence of this bug and if so we don't fail.
+  @Test
+  public void testTypeParametersWithAnnotationsOnBounds() {
+    @SupportedAnnotationTypes("*")
+    class CompilerBugProcessor extends AbstractProcessor {
+      boolean checkedAnnotationsOnTypeBounds;
+      boolean reportsAnnotationsOnTypeBounds;
+
+      @Override
+      public SourceVersion getSupportedSourceVersion() {
+        return SourceVersion.latestSupported();
+      }
+
+      @Override
+      public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver()) {
+          TypeElement test = processingEnv.getElementUtils().getTypeElement("com.example.Test");
+          TypeParameterElement t = test.getTypeParameters().get(0);
+          this.checkedAnnotationsOnTypeBounds = true;
+          this.reportsAnnotationsOnTypeBounds =
+              !t.getBounds().get(0).getAnnotationMirrors().isEmpty();
+        }
+        return false;
+      }
+    }
+    CompilerBugProcessor compilerBugProcessor = new CompilerBugProcessor();
+    JavaFileObject nullableTypeFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.NullableType",
+            "package foo.bar;",
+            "",
+            "import java.lang.annotation.ElementType;",
+            "import java.lang.annotation.Target;",
+            "",
+            "@Target(ElementType.TYPE_USE)",
+            "public @interface NullableType {}");
+    JavaFileObject autoValueFileObject =
+        JavaFileObjects.forSourceLines(
+            "com.example.Test",
+            "package com.example;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import foo.bar.NullableType;",
+            "",
+            "@AutoValue",
+            "abstract class Test<T extends @NullableType Object & @NullableType Cloneable> {}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), compilerBugProcessor)
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(nullableTypeFileObject, autoValueFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilerBugProcessor.checkedAnnotationsOnTypeBounds).isTrue();
+    if (compilerBugProcessor.reportsAnnotationsOnTypeBounds) {
+      assertThat(compilation)
+          .generatedSourceFile("com.example.AutoValue_Test")
+          .contentsAsUtf8String()
+          .contains(
+              "class AutoValue_Test<T extends @NullableType Object & @NullableType Cloneable>"
+                  + " extends Test<T> {");
+    }
+  }
+
+  // In the following few tests, see AutoValueProcessor.validateMethods for why unrecognized
+  // abstract methods provoke only a warning rather than an error. Compilation will fail anyway
+  // because the generated class is not abstract and does not implement the unrecognized methods.
+
+  @Test
+  public void testAbstractVoid() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract void foo();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation).failed();
+    assertThat(compilation)
+        .hadWarningContaining(
+            "Abstract method is neither a property getter nor a Builder converter")
+        .inFile(javaFileObject)
+        .onLineContaining("void foo()");
+  }
+
+  @Test
+  public void testAbstractWithParams() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract int foo(int bar);",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation).failed();
+    assertThat(compilation)
+        .hadWarningContaining(
+            "Abstract method is neither a property getter nor a Builder converter")
+        .inFile(javaFileObject)
+        .onLineContaining("int foo(int bar)");
+  }
+
+  @Test
+  public void testPrimitiveArrayWarning() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract byte[] bytes();",
+            "  public static Baz create(byte[] bytes) {",
+            "    return new AutoValue_Baz(bytes);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation).succeeded();
+    assertThat(compilation)
+        .hadWarningContaining(
+            "An @AutoValue property that is a primitive array returns the original array")
+        .inFile(javaFileObject)
+        .onLineContaining("byte[] bytes()");
+  }
+
+  @Test
+  public void testPrimitiveArrayWarningFromParent() {
+    // If the array-valued property is defined by an ancestor then we shouldn't try to attach
+    // the warning to the method that defined it, but rather to the @AutoValue class itself.
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "public abstract class Baz {",
+            "  public abstract byte[] bytes();",
+            "",
+            "  @AutoValue",
+            "  public abstract static class BazChild extends Baz {",
+            "    public static BazChild create(byte[] bytes) {",
+            "      return new AutoValue_Baz_BazChild(bytes);",
+            "    }",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation).succeeded();
+    assertThat(compilation)
+        .hadWarningContainingMatch(
+            "An @AutoValue property that is a primitive array returns the original array"
+                + ".*foo\\.bar\\.Baz\\.bytes")
+        .inFile(javaFileObject)
+        .onLineContaining("BazChild extends Baz");
+  }
+
+  @Test
+  public void testPrimitiveArrayWarningSuppressed() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  @SuppressWarnings(\"mutable\")",
+            "  public abstract byte[] bytes();",
+            "  public static Baz create(byte[] bytes) {",
+            "    return new AutoValue_Baz(bytes);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void autoValueMustBeStatic() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "public class Baz {",
+            "  @AutoValue",
+            "  public abstract class NotStatic {",
+            "    public abstract String buh();",
+            "    public NotStatic create(String buh) {",
+            "      return new AutoValue_Baz_NotStatic(buh);",
+            "    }",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Nested @AutoValue class must be static")
+        .inFile(javaFileObject)
+        .onLineContaining("abstract class NotStatic");
+  }
+
+  @Test
+  public void autoValueMustBeNotBePrivate() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "public class Baz {",
+            "  @AutoValue",
+            "  private abstract static class Private {",
+            "    public abstract String buh();",
+            "    public Private create(String buh) {",
+            "      return new AutoValue_Baz_Private(buh);",
+            "    }",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("@AutoValue class must not be private")
+        .inFile(javaFileObject)
+        .onLineContaining("class Private");
+  }
+
+  @Test
+  public void autoValueMustBeNotBeNestedInPrivate() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "public class Baz {",
+            "  private static class Private {",
+            "    @AutoValue",
+            "    abstract static class Nested {",
+            "      public abstract String buh();",
+            "      public Nested create(String buh) {",
+            "        return new AutoValue_Baz_Private_Nested(buh);",
+            "      }",
+            "    }",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("@AutoValue class must not be nested in a private class")
+        .inFile(javaFileObject)
+        .onLineContaining("class Nested");
+  }
+
+  @Test
+  public void noMultidimensionalPrimitiveArrays() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract int[][] ints();",
+            "",
+            "  public static Baz create(int[][] ints) {",
+            "    return new AutoValue_Baz(ints);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "@AutoValue class cannot define an array-valued property "
+                + "unless it is a primitive array")
+        .inFile(javaFileObject)
+        .onLineContaining("int[][] ints()");
+  }
+
+  @Test
+  public void noObjectArrays() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract String[] strings();",
+            "",
+            "  public static Baz create(String[] strings) {",
+            "    return new AutoValue_Baz(strings);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "@AutoValue class cannot define an array-valued property "
+                + "unless it is a primitive array")
+        .inFile(javaFileObject)
+        .onLineContaining("String[] strings()");
+  }
+
+  @Test
+  public void annotationOnInterface() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public interface Baz {}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("AutoValue only applies to classes")
+        .inFile(javaFileObject)
+        .onLineContaining("interface Baz");
+  }
+
+  @Test
+  public void annotationOnEnum() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public enum Baz {}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("AutoValue only applies to classes")
+        .inFile(javaFileObject)
+        .onLineContaining("enum Baz");
+  }
+
+  @Test
+  public void extendAutoValue() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Outer",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "public class Outer {",
+            "  @AutoValue",
+            "  static abstract class Parent {",
+            "    static Parent create(int randomProperty) {",
+            "      return new AutoValue_Outer_Parent(randomProperty);",
+            "    }",
+            "",
+            "    abstract int randomProperty();",
+            "  }",
+            "",
+            "  @AutoValue",
+            "  static abstract class Child extends Parent {",
+            "    static Child create(int randomProperty) {",
+            "      return new AutoValue_Outer_Child(randomProperty);",
+            "    }",
+            "",
+            "    abstract int randomProperty();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("may not extend")
+        .inFile(javaFileObject)
+        .onLineContaining("Child extends Parent");
+  }
+
+  @Test
+  public void bogusSerialVersionUID() {
+    String[] mistakes = {
+      "final long serialVersionUID = 1234L", // not static
+      "static long serialVersionUID = 1234L", // not final
+      "static final Long serialVersionUID = 1234L", // not long
+      "static final long serialVersionUID = (Long) 1234L", // not a compile-time constant
+    };
+    for (String mistake : mistakes) {
+      JavaFileObject javaFileObject =
+          JavaFileObjects.forSourceLines(
+              "foo.bar.Baz",
+              "package foo.bar;",
+              "",
+              "import com.google.auto.value.AutoValue;",
+              "",
+              "@AutoValue",
+              "public abstract class Baz implements java.io.Serializable {",
+              "  " + mistake + ";",
+              "",
+              "  public abstract int foo();",
+              "}");
+      Compilation compilation =
+          javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+      expect
+          .about(compilations())
+          .that(compilation)
+          .hadErrorContaining("serialVersionUID must be a static final long compile-time constant")
+          .inFile(javaFileObject)
+          .onLineContaining(mistake);
+    }
+  }
+
+  @Test
+  public void nonExistentSuperclass() {
+    // The main purpose of this test is to check that AutoValueProcessor doesn't crash the
+    // compiler in this case.
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Existent extends NonExistent {",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("NonExistent")
+        .inFile(javaFileObject)
+        .onLineContaining("NonExistent");
+  }
+
+  @Test
+  public void cannotImplementAnnotation() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.RetentionImpl",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import java.lang.annotation.Retention;",
+            "import java.lang.annotation.RetentionPolicy;",
+            "",
+            "@AutoValue",
+            "public abstract class RetentionImpl implements Retention {",
+            "  public static Retention create(RetentionPolicy policy) {",
+            "    return new AutoValue_RetentionImpl(policy);",
+            "  }",
+            "",
+            "  @Override public Class<? extends Retention> annotationType() {",
+            "    return Retention.class;",
+            "  }",
+            "",
+            "  @Override public boolean equals(Object o) {",
+            "    return (o instanceof Retention && value().equals((Retention) o).value());",
+            "  }",
+            "",
+            "  @Override public int hashCode() {",
+            "    return (\"value\".hashCode() * 127) ^ value().hashCode();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("may not be used to implement an annotation interface")
+        .inFile(javaFileObject)
+        .onLineContaining("RetentionImpl implements Retention");
+  }
+
+  @Test
+  public void missingPropertyType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract MissingType missingType();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("MissingType")
+        .inFile(javaFileObject)
+        .onLineContaining("MissingType");
+  }
+
+  @Test
+  public void missingGenericPropertyType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract MissingType<?> missingType();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("MissingType")
+        .inFile(javaFileObject)
+        .onLineContaining("MissingType");
+  }
+
+  @Test
+  public void missingComplexGenericPropertyType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "import java.util.Map;",
+            "import java.util.Set;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract Map<Set<?>, MissingType<?>> missingType();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("MissingType")
+        .inFile(javaFileObject)
+        .onLineContaining("MissingType");
+  }
+
+  @Test
+  public void missingSuperclassGenericParameter() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T extends MissingType<?>> {",
+            "  public abstract int foo();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("MissingType")
+        .inFile(javaFileObject)
+        .onLineContaining("MissingType");
+  }
+
+  @Test
+  public void nullablePrimitive() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  @interface Nullable {}",
+            "  public abstract @Nullable int foo();",
+            "}");
+    Compilation compilation =
+        javac().withProcessors(new AutoValueProcessor()).compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Primitive types cannot be @Nullable")
+        .inFile(javaFileObject)
+        .onLineContaining("@Nullable int");
+  }
+
+  @Test
+  public void correctBuilder() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.base.Optional;",
+            "import com.google.common.collect.ImmutableList;",
+            "",
+            "import java.util.ArrayList;",
+            "import java.util.List;",
+            "import javax.annotation.Nullable;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T extends Number> {",
+            "  public abstract int anInt();",
+            "  @SuppressWarnings(\"mutable\")",
+            "  public abstract byte[] aByteArray();",
+            "  @SuppressWarnings(\"mutable\")",
+            "  @Nullable public abstract int[] aNullableIntArray();",
+            "  public abstract List<T> aList();",
+            "  public abstract ImmutableList<T> anImmutableList();",
+            "  public abstract Optional<String> anOptionalString();",
+            "  public abstract NestedAutoValue<T> aNestedAutoValue();",
+            "",
+            "  public abstract Builder<T> toBuilder();",
+            "",
+            "  @AutoValue.Builder",
+            "  public abstract static class Builder<T extends Number> {",
+            "    public abstract Builder<T> anInt(int x);",
+            "    public abstract Builder<T> aByteArray(byte[] x);",
+            "    public abstract Builder<T> aNullableIntArray(@Nullable int[] x);",
+            "    public abstract Builder<T> aList(List<T> x);",
+            "    public abstract Builder<T> anImmutableList(List<T> x);",
+            "    public abstract ImmutableList.Builder<T> anImmutableListBuilder();",
+            "    public abstract Builder<T> anOptionalString(Optional<String> s);",
+            "    public abstract Builder<T> anOptionalString(String s);",
+            "    public abstract NestedAutoValue.Builder<T> aNestedAutoValueBuilder();",
+            "",
+            "    public Builder<T> aList(ArrayList<T> x) {",
+            // ArrayList should not be imported in the generated class.
+            "      return aList((List<T>) x);",
+            "    }",
+            "",
+            "    public abstract Optional<Integer> anInt();",
+            "    public abstract List<T> aList();",
+            "    public abstract ImmutableList<T> anImmutableList();",
+            "",
+            "    public abstract Baz<T> build();",
+            "  }",
+            "",
+            "  public static <T extends Number> Builder<T> builder() {",
+            "    return AutoValue_Baz.builder();",
+            "  }",
+            "}");
+    JavaFileObject nestedJavaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.NestedAutoValue",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class NestedAutoValue<T extends Number> {",
+            "  public abstract T t();",
+            "",
+            "  public abstract Builder<T> toBuilder();",
+            "",
+            "  @AutoValue.Builder",
+            "  public abstract static class Builder<T extends Number> {",
+            "    public abstract Builder<T> t(T t);",
+            "    public abstract NestedAutoValue<T> build();",
+            "  }",
+            "",
+            "  public static <T extends Number> Builder<T> builder() {",
+            "    return AutoValue_NestedAutoValue.builder();",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoValue_Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.common.base.Optional;",
+            "import com.google.common.collect.ImmutableList;",
+            "import java.util.Arrays;",
+            "import java.util.List;",
+            sorted(
+                GeneratedImport.importGeneratedAnnotationType(),
+                "import javax.annotation.Nullable;"),
+            "",
+            "@Generated(\"" + AutoValueProcessor.class.getName() + "\")",
+            "final class AutoValue_Baz<T extends Number> extends Baz<T> {",
+            "  private final int anInt;",
+            "  private final byte[] aByteArray;",
+            "  private final int[] aNullableIntArray;",
+            "  private final List<T> aList;",
+            "  private final ImmutableList<T> anImmutableList;",
+            "  private final Optional<String> anOptionalString;",
+            "  private final NestedAutoValue<T> aNestedAutoValue;",
+            "",
+            "  private AutoValue_Baz(",
+            "      int anInt,",
+            "      byte[] aByteArray,",
+            "      @Nullable int[] aNullableIntArray,",
+            "      List<T> aList,",
+            "      ImmutableList<T> anImmutableList,",
+            "      Optional<String> anOptionalString,",
+            "      NestedAutoValue<T> aNestedAutoValue) {",
+            "    this.anInt = anInt;",
+            "    this.aByteArray = aByteArray;",
+            "    this.aNullableIntArray = aNullableIntArray;",
+            "    this.aList = aList;",
+            "    this.anImmutableList = anImmutableList;",
+            "    this.anOptionalString = anOptionalString;",
+            "    this.aNestedAutoValue = aNestedAutoValue;",
+            "  }",
+            "",
+            "  @Override public int anInt() {",
+            "    return anInt;",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"mutable\")",
+            "  @Override public byte[] aByteArray() {",
+            "    return aByteArray;",
+            "  }",
+            "",
+            "  @SuppressWarnings(\"mutable\")",
+            "  @Nullable",
+            "  @Override public int[] aNullableIntArray() {",
+            "    return aNullableIntArray;",
+            "  }",
+            "",
+            "  @Override public List<T> aList() {",
+            "    return aList;",
+            "  }",
+            "",
+            "  @Override public ImmutableList<T> anImmutableList() {",
+            "    return anImmutableList;",
+            "  }",
+            "",
+            "  @Override public Optional<String> anOptionalString() {",
+            "    return anOptionalString;",
+            "  }",
+            "",
+            "  @Override public NestedAutoValue<T> aNestedAutoValue() {",
+            "    return aNestedAutoValue;",
+            "  }",
+            "",
+            "  @Override public String toString() {",
+            "    return \"Baz{\"",
+            "        + \"anInt=\" + anInt + \", \"",
+            "        + \"aByteArray=\" + Arrays.toString(aByteArray) + \", \"",
+            "        + \"aNullableIntArray=\" + Arrays.toString(aNullableIntArray) + \", \"",
+            "        + \"aList=\" + aList + \", \"",
+            "        + \"anImmutableList=\" + anImmutableList + \", \"",
+            "        + \"anOptionalString=\" + anOptionalString + \", \"",
+            "        + \"aNestedAutoValue=\" + aNestedAutoValue",
+            "        + \"}\";",
+            "  }",
+            "",
+            "  @Override public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof Baz) {",
+            "      Baz<?> that = (Baz<?>) o;",
+            "      return this.anInt == that.anInt()",
+            "          && Arrays.equals(this.aByteArray, "
+                + "(that instanceof AutoValue_Baz) "
+                + "? ((AutoValue_Baz) that).aByteArray : that.aByteArray())",
+            "          && Arrays.equals(this.aNullableIntArray, "
+                + "(that instanceof AutoValue_Baz) "
+                + "? ((AutoValue_Baz) that).aNullableIntArray : that.aNullableIntArray())",
+            "          && this.aList.equals(that.aList())",
+            "          && this.anImmutableList.equals(that.anImmutableList())",
+            "          && this.anOptionalString.equals(that.anOptionalString())",
+            "          && this.aNestedAutoValue.equals(that.aNestedAutoValue());",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+            "  @Override public int hashCode() {",
+            "    int h$ = 1;",
+            "    h$ *= 1000003;",
+            "    h$ ^= anInt;",
+            "    h$ *= 1000003;",
+            "    h$ ^= Arrays.hashCode(aByteArray);",
+            "    h$ *= 1000003;",
+            "    h$ ^= Arrays.hashCode(aNullableIntArray);",
+            "    h$ *= 1000003;",
+            "    h$ ^= aList.hashCode();",
+            "    h$ *= 1000003;",
+            "    h$ ^= anImmutableList.hashCode();",
+            "    h$ *= 1000003;",
+            "    h$ ^= anOptionalString.hashCode();",
+            "    h$ *= 1000003;",
+            "    h$ ^= aNestedAutoValue.hashCode();",
+            "    return h$;",
+            "  }",
+            "",
+            "  @Override public Baz.Builder<T> toBuilder() {",
+            "    return new Builder<T>(this);",
+            "  }",
+            "",
+            "  static final class Builder<T extends Number> extends Baz.Builder<T> {",
+            "    private Integer anInt;",
+            "    private byte[] aByteArray;",
+            "    private int[] aNullableIntArray;",
+            "    private List<T> aList;",
+            "    private ImmutableList.Builder<T> anImmutableListBuilder$;",
+            "    private ImmutableList<T> anImmutableList;",
+            "    private Optional<String> anOptionalString = Optional.absent();",
+            "    private NestedAutoValue.Builder<T> aNestedAutoValueBuilder$;",
+            "    private NestedAutoValue<T> aNestedAutoValue;",
+            "",
+            "    Builder() {",
+            "    }",
+            "",
+            "    private Builder(Baz<T> source) {",
+            "      this.anInt = source.anInt();",
+            "      this.aByteArray = source.aByteArray();",
+            "      this.aNullableIntArray = source.aNullableIntArray();",
+            "      this.aList = source.aList();",
+            "      this.anImmutableList = source.anImmutableList();",
+            "      this.anOptionalString = source.anOptionalString();",
+            "      this.aNestedAutoValue = source.aNestedAutoValue();",
+            "    }",
+            "",
+            "    @Override",
+            "    public Baz.Builder<T> anInt(int anInt) {",
+            "      this.anInt = anInt;",
+            "      return this;",
+            "    }",
+            "",
+            "    @Override",
+            "    public Optional<Integer> anInt() {",
+            "      if (anInt == null) {",
+            "        return Optional.absent();",
+            "      } else {",
+            "        return Optional.of(anInt);",
+            "      }",
+            "    }",
+            "",
+            "    @Override",
+            "    public Baz.Builder<T> aByteArray(byte[] aByteArray) {",
+            "      if (aByteArray == null) {",
+            "        throw new NullPointerException(\"Null aByteArray\");",
+            "      }",
+            "      this.aByteArray = aByteArray;",
+            "      return this;",
+            "    }",
+            "",
+            "    @Override",
+            "    public Baz.Builder<T> aNullableIntArray(@Nullable int[] aNullableIntArray) {",
+            "      this.aNullableIntArray = aNullableIntArray;",
+            "      return this;",
+            "    }",
+            "",
+            "    @Override",
+            "    public Baz.Builder<T> aList(List<T> aList) {",
+            "      if (aList == null) {",
+            "        throw new NullPointerException(\"Null aList\");",
+            "      }",
+            "      this.aList = aList;",
+            "      return this;",
+            "    }",
+            "",
+            "    @Override",
+            "    public List<T> aList() {",
+            "      if (aList == null) {",
+            "        throw new IllegalStateException(\"Property \\\"aList\\\" has not been set\");",
+            "      }",
+            "      return aList;",
+            "    }",
+            "",
+            "    @Override",
+            "    public Baz.Builder<T> anImmutableList(List<T> anImmutableList) {",
+            "      if (anImmutableListBuilder$ != null) {",
+            "        throw new IllegalStateException("
+                + "\"Cannot set anImmutableList after calling anImmutableListBuilder()\");",
+            "      }",
+            "      this.anImmutableList = ImmutableList.copyOf(anImmutableList);",
+            "      return this;",
+            "    }",
+            "",
+            "    @Override",
+            "    public ImmutableList.Builder<T> anImmutableListBuilder() {",
+            "      if (anImmutableListBuilder$ == null) {",
+            "        if (anImmutableList == null) {",
+            "          anImmutableListBuilder$ = ImmutableList.builder();",
+            "        } else {",
+            "          anImmutableListBuilder$ = ImmutableList.builder();",
+            "          anImmutableListBuilder$.addAll(anImmutableList);",
+            "          anImmutableList = null;",
+            "        }",
+            "      }",
+            "      return anImmutableListBuilder$;",
+            "    }",
+            "",
+            "    @Override",
+            "    public ImmutableList<T> anImmutableList() {",
+            "      if (anImmutableListBuilder$ != null) {",
+            "        return anImmutableListBuilder$.build();",
+            "      }",
+            "      if (anImmutableList == null) {",
+            "        anImmutableList = ImmutableList.of();",
+            "      }",
+            "      return anImmutableList;",
+            "    }",
+            "",
+            "    @Override",
+            "    public Baz.Builder<T> anOptionalString(Optional<String> anOptionalString) {",
+            "      if (anOptionalString == null) {",
+            "        throw new NullPointerException(\"Null anOptionalString\");",
+            "      }",
+            "      this.anOptionalString = anOptionalString;",
+            "      return this;",
+            "    }",
+            "",
+            "    @Override",
+            "    public Baz.Builder<T> anOptionalString(String anOptionalString) {",
+            "      this.anOptionalString = Optional.of(anOptionalString);",
+            "      return this;",
+            "    }",
+            "",
+            "    @Override",
+            "    public NestedAutoValue.Builder<T> aNestedAutoValueBuilder() {",
+            "      if (aNestedAutoValueBuilder$ == null) {",
+            "        if (aNestedAutoValue == null) {",
+            "          aNestedAutoValueBuilder$ = NestedAutoValue.builder();",
+            "        } else {",
+            "          aNestedAutoValueBuilder$ = aNestedAutoValue.toBuilder();",
+            "          aNestedAutoValue = null;",
+            "        }",
+            "      }",
+            "      return aNestedAutoValueBuilder$;",
+            "    }",
+            "",
+            "    @Override",
+            "    public Baz<T> build() {",
+            "      if (anImmutableListBuilder$ != null) {",
+            "        this.anImmutableList = anImmutableListBuilder$.build();",
+            "      } else if (this.anImmutableList == null) {",
+            "        this.anImmutableList = ImmutableList.of();",
+            "      }",
+            "      if (aNestedAutoValueBuilder$ != null) {",
+            "        this.aNestedAutoValue = aNestedAutoValueBuilder$.build();",
+            "      } else if (this.aNestedAutoValue == null) {",
+            "        NestedAutoValue.Builder<T> aNestedAutoValue$builder = "
+                + "NestedAutoValue.builder();",
+            "        this.aNestedAutoValue = aNestedAutoValue$builder.build();",
+            "      }",
+            "      String missing = \"\";",
+            "      if (this.anInt == null) {",
+            "        missing += \" anInt\";",
+            "      }",
+            "      if (this.aByteArray == null) {",
+            "        missing += \" aByteArray\";",
+            "      }",
+            "      if (this.aList == null) {",
+            "        missing += \" aList\";",
+            "      }",
+            "      if (!missing.isEmpty()) {",
+            "        throw new IllegalStateException(\"Missing required properties:\" + missing);",
+            "      }",
+            "      return new AutoValue_Baz<T>(",
+            "          this.anInt,",
+            "          this.aByteArray,",
+            "          this.aNullableIntArray,",
+            "          this.aList,",
+            "          this.anImmutableList,",
+            "          this.anOptionalString,",
+            "          this.aNestedAutoValue);",
+            "    }",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(javaFileObject, nestedJavaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz")
+        .hasSourceEquivalentTo(expectedOutput);
+  }
+
+  @Test
+  public void autoValueBuilderOnTopLevelClass() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Builder",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue.Builder",
+            "public interface Builder {",
+            "  Builder foo(int x);",
+            "  Object build();",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("can only be applied to a class or interface inside")
+        .inFile(javaFileObject)
+        .onLineContaining("public interface Builder");
+  }
+
+  @Test
+  public void autoValueBuilderNotInsideAutoValue() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "public abstract class Baz {",
+            "  abstract int foo();",
+            "",
+            "  static Builder builder() {",
+            "    return new AutoValue_Baz.Builder();",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder foo(int x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("can only be applied to a class or interface inside")
+        .inFile(javaFileObject)
+        .onLineContaining("public interface Builder");
+  }
+
+  @Test
+  public void autoValueBuilderNotStatic() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Example",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "class Example {",
+            "  @AutoValue",
+            "  abstract static class Baz {",
+            "    abstract int foo();",
+            "",
+            "    static Builder builder() {",
+            "      return new AutoValue_Example_Baz.Builder();",
+            "    }",
+            "",
+            "    @AutoValue.Builder",
+            "    abstract class Builder {",
+            "      abstract Builder foo(int x);",
+            "      abstract Baz build();",
+            "    }",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("@AutoValue.Builder cannot be applied to a non-static class")
+        .inFile(javaFileObject)
+        .onLineContaining("abstract class Builder");
+  }
+
+  @Test
+  public void autoValueBuilderOnEnum() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract int foo();",
+            "",
+            "  static Builder builder() {",
+            "    return null;",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public enum Builder {}",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("can only apply to a class or an interface")
+        .inFile(javaFileObject)
+        .onLineContaining("public enum Builder");
+  }
+
+  @Test
+  public void autoValueBuilderDuplicate() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  @AutoValue.Builder",
+            "  public interface Builder1 {",
+            "    Baz build();",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder2 {",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("already has a Builder: foo.bar.Baz.Builder1")
+        .inFile(javaFileObject)
+        .onLineContaining("public interface Builder2");
+  }
+
+  @Test
+  public void autoValueBuilderMissingSetter() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract int blim();",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blam(String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("with this signature: foo.bar.Baz.Builder blim(int)")
+        .inFile(javaFileObject)
+        .onLineContaining("public interface Builder");
+  }
+
+  @Test
+  public void autoValueBuilderMissingSetterUsingSetPrefix() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract int blim();",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder setBlam(String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("with this signature: foo.bar.Baz.Builder setBlim(int)")
+        .inFile(javaFileObject)
+        .onLineContaining("public interface Builder");
+  }
+
+  @Test
+  public void autoValueBuilderWrongTypeSetter() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract int blim();",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blim(String x);",
+            "    Builder blam(String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Parameter type java.lang.String of setter method should be int "
+                + "to match getter foo.bar.Baz.blim")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder blim(String x)");
+  }
+
+  @Test
+  public void autoValueBuilderWrongTypeSetterWithCopyOf() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableList;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String blim();",
+            "  abstract ImmutableList<String> blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blim(String x);",
+            "    Builder blam(String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Parameter type java.lang.String of setter method should be "
+                + "com.google.common.collect.ImmutableList<java.lang.String> to match getter "
+                + "foo.bar.Baz.blam, or it should be a type that can be passed to "
+                + "ImmutableList.copyOf")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder blam(String x)");
+  }
+
+  @Test
+  public void autoValueBuilderWrongTypeSetterWithCopyOfGenericallyWrong() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableList;",
+            "import java.util.Collection;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String blim();",
+            "  abstract ImmutableList<String> blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blim(String x);",
+            "    Builder blam(Collection<Integer> x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Parameter type java.util.Collection<java.lang.Integer> of setter method should be "
+                + "com.google.common.collect.ImmutableList<java.lang.String> to match getter "
+                + "foo.bar.Baz.blam, or it should be a type that can be passed to "
+                + "ImmutableList.copyOf to produce "
+                + "com.google.common.collect.ImmutableList<java.lang.String>")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder blam(Collection<Integer> x)");
+  }
+
+  @Test
+  public void autoValueBuilderWrongTypeSetterWithGetPrefix() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract int getBlim();",
+            "  abstract String getBlam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blim(String x);",
+            "    Builder blam(String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Parameter type java.lang.String of setter method should be int "
+                + "to match getter foo.bar.Baz.getBlim")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder blim(String x)");
+  }
+
+  @Test
+  public void autoValueBuilderNullableSetterForNonNullable() {
+    JavaFileObject nullableFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Nullable",
+            "package foo.bar;",
+            "",
+            "import java.lang.annotation.ElementType;",
+            "import java.lang.annotation.Target;",
+            "",
+            "@Target(ElementType.TYPE_USE)",
+            "public @interface Nullable {}");
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String notNull();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder setNotNull(@Nullable String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject, nullableFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Parameter of setter method is @Nullable but property method"
+                + " foo.bar.Baz.notNull() is not")
+        .inFile(javaFileObject)
+        .onLineContaining("setNotNull");
+  }
+
+  // Check that we get a helpful error message if some of your properties look like getters but
+  // others don't.
+  @Test
+  public void autoValueBuilderBeansConfusion() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Item",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Item {",
+            "  abstract String getTitle();",
+            "  abstract boolean hasThumbnail();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder setTitle(String title);",
+            "    Builder setHasThumbnail(boolean t);",
+            "    Item build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Method does not correspond to a property of foo.bar.Item")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder setTitle(String title)");
+    assertThat(compilation)
+        .hadNoteContaining("hasThumbnail")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder setTitle(String title)");
+  }
+
+  @Test
+  public void autoValueBuilderExtraSetter() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blim(int x);",
+            "    Builder blam(String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Method does not correspond to a property of foo.bar.Baz")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder blim(int x)");
+  }
+
+  @Test
+  public void autoValueBuilderSetPrefixAndNoSetPrefix() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract int blim();",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blim(int x);",
+            "    Builder setBlam(String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("If any setter methods use the setFoo convention then all must")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder blim(int x)");
+  }
+
+  @Test
+  public void autoValueBuilderWrongTypeGetter() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  abstract T blim();",
+            "  abstract U blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    Builder<T, U> blim(T x);",
+            "    Builder<T, U> blam(U x);",
+            "    T blim();",
+            "    T blam();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Method matches a property of foo.bar.Baz but has return type T instead of U")
+        .inFile(javaFileObject)
+        .onLineContaining("T blam()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderInvalidType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  abstract String blim();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    StringBuilder blimBuilder();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Method looks like a property builder, but it returns java.lang.StringBuilder which "
+                + "does not have a non-static build() method")
+        .inFile(javaFileObject)
+        .onLineContaining("StringBuilder blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderNullable() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableList;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  @interface Nullable {}",
+            "  abstract @Nullable ImmutableList<String> strings();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    ImmutableList.Builder<String> stringsBuilder();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Property strings has a property builder so it cannot be @Nullable")
+        .inFile(javaFileObject)
+        .onLineContaining("@Nullable ImmutableList<String> strings()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderNullableType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableList;",
+            "import java.lang.annotation.ElementType;",
+            "import java.lang.annotation.Target;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  @Target(ElementType.TYPE_USE)",
+            "  @interface Nullable {}",
+            "  abstract @Nullable ImmutableList<String> strings();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    ImmutableList.Builder<String> stringsBuilder();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Property strings has a property builder so it cannot be @Nullable")
+        .inFile(javaFileObject)
+        .onLineContaining("@Nullable ImmutableList<String> strings()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderWrongCollectionType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableList;",
+            "import com.google.common.collect.ImmutableSet;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  abstract ImmutableList<T> blim();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    ImmutableSet.Builder<T> blimBuilder();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Property builder for blim has type com.google.common.collect.ImmutableSet.Builder "
+                + "whose build() method returns com.google.common.collect.ImmutableSet<T> "
+                + "instead of com.google.common.collect.ImmutableList<T>")
+        .inFile(javaFileObject)
+        .onLineContaining("ImmutableSet.Builder<T> blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderWeirdBuilderType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  abstract Integer blim();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    int blimBuilder();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Method looks like a property builder, but its return type is not a class or interface")
+        .inFile(javaFileObject)
+        .onLineContaining("int blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderWeirdBuiltType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  abstract int blim();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    Integer blimBuilder();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Method looks like a property builder, but the type of property blim is not a class "
+                + "or interface")
+        .inFile(javaFileObject)
+        .onLineContaining("Integer blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderHasNoBuild() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  abstract String blim();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    StringBuilder blimBuilder();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Method looks like a property builder, but it returns java.lang.StringBuilder which "
+                + "does not have a non-static build() method")
+        .inFile(javaFileObject)
+        .onLineContaining("StringBuilder blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderHasStaticBuild() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  abstract String blim();",
+            "",
+            "  public static class StringFactory {",
+            "    public static String build() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    StringFactory blimBuilder();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Method looks like a property builder, but it returns foo.bar.Baz.StringFactory which "
+                + "does not have a non-static build() method")
+        .inFile(javaFileObject)
+        .onLineContaining("StringFactory blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderReturnsWrongType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "import java.util.List;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<E> {",
+            "  abstract List<E> blim();",
+            "",
+            "  public static class ListFactory<E> {",
+            "    public List<? extends E> build() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<E> {",
+            "    ListFactory<E> blimBuilder();",
+            "    Baz<E> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Property builder for blim has type foo.bar.Baz.ListFactory whose build() method "
+                + "returns java.util.List<? extends E> instead of java.util.List<E>")
+        .inFile(javaFileObject)
+        .onLineContaining("ListFactory<E> blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderCantConstruct() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<E> {",
+            "  abstract String blim();",
+            "",
+            "  public static class StringFactory {",
+            "    private StringFactory() {}",
+            "",
+            "    public String build() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<E> {",
+            "    StringFactory blimBuilder();",
+            "    Baz<E> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Method looks like a property builder, but its type foo.bar.Baz.StringFactory "
+                + "does not have a public constructor and java.lang.String does not have a static "
+                + "builder() or newBuilder() method that returns foo.bar.Baz.StringFactory")
+        .inFile(javaFileObject)
+        .onLineContaining("StringFactory blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderCantReconstruct() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<E> {",
+            "  abstract String blim();",
+            "  abstract Builder<E> toBuilder();",
+            "",
+            "  public static class StringFactory {",
+            "    public String build() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<E> {",
+            "    StringFactory blimBuilder();",
+            "    Baz<E> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Property builder method returns foo.bar.Baz.StringFactory but there is no way to make"
+                + " that type from java.lang.String: java.lang.String does not have a non-static"
+                + " toBuilder() method that returns foo.bar.Baz.StringFactory, and"
+                + " foo.bar.Baz.StringFactory does not have a method addAll or putAll that accepts"
+                + " an argument of type java.lang.String")
+        .inFile(javaFileObject)
+        .onLineContaining("StringFactory blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderWrongTypeAddAll() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "import java.util.Iterator;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T> {",
+            "  abstract ImmutableSet<String> strings();",
+            "  abstract Builder<T> toBuilder();",
+            "",
+            "  public static class ImmutableSetBuilder<E> {",
+            "    public void addAll(Iterator<? extends E> elements) {}",
+            "",
+            "    public ImmutableSet<E> build() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T> {",
+            "    ImmutableSetBuilder<String> stringsBuilder();",
+            "    Baz<T> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Property builder method returns foo.bar.Baz.ImmutableSetBuilder<java.lang.String> but"
+                + " there is no way to make that type from"
+                + " com.google.common.collect.ImmutableSet<java.lang.String>:"
+                + " com.google.common.collect.ImmutableSet<java.lang.String> does not have a"
+                + " non-static toBuilder() method that returns"
+                + " foo.bar.Baz.ImmutableSetBuilder<java.lang.String>, and"
+                + " foo.bar.Baz.ImmutableSetBuilder<java.lang.String> does not have a method"
+                + " addAll or putAll that accepts an argument of type"
+                + " com.google.common.collect.ImmutableSet<java.lang.String>")
+        .inFile(javaFileObject)
+        .onLineContaining("ImmutableSetBuilder<String> stringsBuilder();");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderCantSet() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<E> {",
+            "  abstract String blim();",
+            "",
+            "  public static class StringFactory {",
+            "    public String build() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<E> {",
+            "    Builder<E> setBlim(String s);",
+            "    StringFactory blimBuilder();",
+            "    Baz<E> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Property builder method returns foo.bar.Baz.StringFactory but there is no way to make "
+                + "that type from java.lang.String: java.lang.String does not have a non-static "
+                + "toBuilder() method that returns foo.bar.Baz.StringFactory")
+        .inFile(javaFileObject)
+        .onLineContaining("StringFactory blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderWrongTypeToBuilder() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<E> {",
+            "  abstract Buh blim();",
+            "  abstract Builder<E> toBuilder();",
+            "",
+            "  public static class Buh {",
+            "    StringBuilder toBuilder() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  public static class BuhBuilder {",
+            "    public Buh build() {",
+            "      return null;",
+            "    }",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<E> {",
+            "    BuhBuilder blimBuilder();",
+            "    Baz<E> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Property builder method returns foo.bar.Baz.BuhBuilder but there is no way to make "
+                + "that type from foo.bar.Baz.Buh: foo.bar.Baz.Buh does not have a non-static "
+                + "toBuilder() method that returns foo.bar.Baz.BuhBuilder")
+        .inFile(javaFileObject)
+        .onLineContaining("BuhBuilder blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderPropertyBuilderWrongElementType() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableSet;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T, U> {",
+            "  abstract ImmutableSet<T> blim();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T, U> {",
+            "    ImmutableSet.Builder<U> blimBuilder();",
+            "    Baz<T, U> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Property builder for blim has type com.google.common.collect.ImmutableSet.Builder "
+                + "whose build() method returns com.google.common.collect.ImmutableSet<U> "
+                + "instead of com.google.common.collect.ImmutableSet<T>")
+        .inFile(javaFileObject)
+        .onLineContaining("ImmutableSet.Builder<U> blimBuilder()");
+  }
+
+  @Test
+  public void autoValueBuilderAlienMethod0() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blam(String x);",
+            "    Builder whut();",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Method without arguments should be a build method returning foo.bar.Baz, or a getter"
+                + " method with the same name and type as a getter method of foo.bar.Baz, or"
+                + " fooBuilder() where foo() or getFoo() is a getter method of foo.bar.Baz")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder whut()");
+  }
+
+  @Test
+  public void autoValueBuilderAlienMethod1() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    void whut(String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Method does not correspond to a property of foo.bar.Baz")
+        .inFile(javaFileObject)
+        .onLineContaining("void whut(String x)");
+  }
+
+  @Test
+  public void autoValueBuilderAlienMethod2() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blam(String x, String y);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Builder methods must have 0 or 1 parameters")
+        .inFile(javaFileObject)
+        .onLineContaining("Builder blam(String x, String y)");
+  }
+
+  @Test
+  public void autoValueBuilderMissingBuildMethod() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T> {",
+            "  abstract T blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T> {",
+            "    Builder<T> blam(T x);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Builder must have a single no-argument method returning foo.bar.Baz<T>")
+        .inFile(javaFileObject)
+        .onLineContaining("public interface Builder<T>");
+  }
+
+  @Test
+  public void autoValueBuilderDuplicateBuildMethods() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blam(String x);",
+            "    Baz build();",
+            "    Baz create();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Builder must have a single no-argument method returning foo.bar.Baz")
+        .inFile(javaFileObject)
+        .onLineContaining("Baz build()");
+    assertThat(compilation)
+        .hadErrorContaining("Builder must have a single no-argument method returning foo.bar.Baz")
+        .inFile(javaFileObject)
+        .onLineContaining("Baz create()");
+  }
+
+  @Test
+  public void autoValueBuilderWrongTypeBuildMethod() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blam(String x);",
+            "    String build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Method without arguments should be a build method returning foo.bar.Baz")
+        .inFile(javaFileObject)
+        .onLineContaining("String build()");
+  }
+
+  @Test
+  public void autoValueBuilderTypeParametersDontMatch1() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T> {",
+            "  abstract String blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder {",
+            "    Builder blam(String x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Type parameters of foo.bar.Baz.Builder must have same names and "
+                + "bounds as type parameters of foo.bar.Baz")
+        .inFile(javaFileObject)
+        .onLineContaining("public interface Builder");
+  }
+
+  @Test
+  public void autoValueBuilderTypeParametersDontMatch2() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T> {",
+            "  abstract T blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<E> {",
+            "    Builder<E> blam(E x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Type parameters of foo.bar.Baz.Builder must have same names and "
+                + "bounds as type parameters of foo.bar.Baz")
+        .inFile(javaFileObject)
+        .onLineContaining("public interface Builder<E>");
+  }
+
+  @Test
+  public void autoValueBuilderTypeParametersDontMatch3() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz<T extends Number & Comparable<T>> {",
+            "  abstract T blam();",
+            "",
+            "  @AutoValue.Builder",
+            "  public interface Builder<T extends Number> {",
+            "    Builder<T> blam(T x);",
+            "    Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "Type parameters of foo.bar.Baz.Builder must have same names and "
+                + "bounds as type parameters of foo.bar.Baz")
+        .inFile(javaFileObject)
+        .onLineContaining("public interface Builder<T extends Number>");
+  }
+
+  @Test
+  public void autoValueBuilderToBuilderWrongTypeParameters() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "abstract class Baz<K extends Comparable<K>, V> {",
+            "  abstract K key();",
+            "  abstract V value();",
+            "  abstract Builder<V, K> toBuilder1();",
+            "",
+            "  @AutoValue.Builder",
+            "  interface Builder<K extends Comparable<K>, V> {",
+            "    Builder<K, V> key(K key);",
+            "    Builder<K, V> value(V value);",
+            "    Baz<K, V> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("Builder converter method should return foo.bar.Baz.Builder<K, V>")
+        .inFile(javaFileObject)
+        .onLineContaining("abstract Builder<V, K> toBuilder1()");
+  }
+
+  @Test
+  public void autoValueBuilderToBuilderDuplicate() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "abstract class Baz<K extends Comparable<K>, V> {",
+            "  abstract K key();",
+            "  abstract V value();",
+            "  abstract Builder<K, V> toBuilder1();",
+            "  abstract Builder<K, V> toBuilder2();",
+            "",
+            "  @AutoValue.Builder",
+            "  interface Builder<K extends Comparable<K>, V> {",
+            "    Builder<K, V> key(K key);",
+            "    Builder<K, V> value(V value);",
+            "    Baz<K, V> build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("There can be at most one builder converter method")
+        .inFile(javaFileObject)
+        .onLineContaining("abstract Builder<K, V> toBuilder1()");
+  }
+
+  @Test
+  public void getFooIsFoo() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract int getFoo();",
+            "  abstract boolean isFoo();",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new AutoValueBuilderProcessor())
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("More than one @AutoValue property called foo")
+        .inFile(javaFileObject)
+        .onLineContaining("getFoo");
+    assertThat(compilation)
+        .hadErrorContaining("More than one @AutoValue property called foo")
+        .inFile(javaFileObject)
+        .onLineContaining("isFoo");
+  }
+
+  @Retention(RetentionPolicy.SOURCE)
+  public @interface Foo {}
+
+  /* Processor that generates an empty class BarFoo every time it sees a class Bar annotated with
+   * @Foo.
+   */
+  public static class FooProcessor extends AbstractProcessor {
+    @Override
+    public Set<String> getSupportedAnnotationTypes() {
+      return ImmutableSet.of(Foo.class.getCanonicalName());
+    }
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latestSupported();
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(Foo.class);
+      for (TypeElement type : ElementFilter.typesIn(elements)) {
+        try {
+          generateFoo(type);
+        } catch (IOException e) {
+          throw new AssertionError(e);
+        }
+      }
+      return false;
+    }
+
+    private void generateFoo(TypeElement type) throws IOException {
+      String pkg = TypeSimplifier.packageNameOf(type);
+      String className = type.getSimpleName().toString();
+      String generatedClassName = className + "Foo";
+      JavaFileObject source =
+          processingEnv.getFiler().createSourceFile(pkg + "." + generatedClassName, type);
+      PrintWriter writer = new PrintWriter(source.openWriter());
+      writer.println("package " + pkg + ";");
+      writer.println("public class " + generatedClassName + " {}");
+      writer.close();
+    }
+  }
+
+  @Test
+  public void referencingGeneratedClass() {
+    // Test that ensures that a type that does not exist can be the type of an @AutoValue property
+    // as long as it later does come into existence. The BarFoo type referenced here does not exist
+    // when the AutoValueProcessor runs on the first round, but the FooProcessor then generates it.
+    // That generation provokes a further round of annotation processing and AutoValueProcessor
+    // should succeed then.
+    JavaFileObject bazFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract BarFoo barFoo();",
+            "",
+            "  public static Baz create(BarFoo barFoo) {",
+            "    return new AutoValue_Baz(barFoo);",
+            "  }",
+            "}");
+    JavaFileObject barFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Bar",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@" + Foo.class.getCanonicalName(),
+            "public abstract class Bar {",
+            "  public abstract BarFoo barFoo();",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(), new FooProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(bazFileObject, barFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void annotationReferencesUndefined() {
+    // Test that we don't throw an exception if asked to compile @SuppressWarnings(UNDEFINED)
+    // where UNDEFINED is an undefined symbol.
+    JavaFileObject bazFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  @SuppressWarnings(UNDEFINED)",
+            "  public abstract int[] buh();",
+            "}");
+    Compilation compilation1 =
+        javac()
+            .withOptions("-Xlint:-processing")
+            .withProcessors(new AutoValueProcessor())
+            .compile(bazFileObject);
+    assertThat(compilation1).hadErrorCount(1);
+    assertThat(compilation1)
+        .hadErrorContaining("UNDEFINED")
+        .inFile(bazFileObject)
+        .onLineContaining("UNDEFINED");
+    assertThat(compilation1).hadWarningCount(1);
+    assertThat(compilation1)
+        .hadWarningContaining("mutable")
+        .inFile(bazFileObject)
+        .onLineContaining("public abstract int[] buh()");
+
+    // Same test, except we do successfully suppress the warning despite the UNDEFINED.
+    bazFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  @SuppressWarnings({UNDEFINED, \"mutable\"})",
+            "  public abstract int[] buh();",
+            "}");
+    Compilation compilation2 =
+        javac()
+            .withOptions("-Xlint:-processing")
+            .withProcessors(new AutoValueProcessor())
+            .compile(bazFileObject);
+    assertThat(compilation2).hadErrorCount(1);
+    assertThat(compilation2)
+        .hadErrorContaining("UNDEFINED")
+        .inFile(bazFileObject)
+        .onLineContaining("UNDEFINED");
+    assertThat(compilation2).hadWarningCount(0);
+  }
+
+  @Test
+  public void packagePrivateAnnotationFromOtherPackage() {
+    JavaFileObject bazFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz extends otherpackage.Parent {",
+            "}");
+    JavaFileObject parentFileObject =
+        JavaFileObjects.forSourceLines(
+            "otherpackage.Parent",
+            "package otherpackage;",
+            "",
+            "public abstract class Parent {",
+            "  @PackageAnnotation",
+            "  public abstract String foo();",
+            "",
+            "  @interface PackageAnnotation {}",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(bazFileObject, parentFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation).generatedSourceFile("foo.bar.AutoValue_Baz");
+  }
+
+  @Test
+  public void visibleProtectedAnnotationFromOtherPackage() {
+    JavaFileObject bazFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz extends otherpackage.Parent {}");
+    JavaFileObject parentFileObject =
+        JavaFileObjects.forSourceLines(
+            "otherpackage.Parent",
+            "package otherpackage;",
+            "",
+            "public abstract class Parent {",
+            "  @ProtectedAnnotation",
+            "  public abstract String foo();",
+            "",
+            "  protected @interface ProtectedAnnotation {}",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(bazFileObject, parentFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz")
+        .contentsAsUtf8String()
+        .containsMatch("(?s:@Parent.ProtectedAnnotation\\s*@Override\\s*public String foo\\(\\))");
+  }
+
+  @Test
+  public void nonVisibleProtectedAnnotationFromOtherPackage() {
+    JavaFileObject bazFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz extends otherpackage.Parent {",
+            "}");
+    JavaFileObject parentFileObject =
+        JavaFileObjects.forSourceLines(
+            "otherpackage.Parent",
+            "package otherpackage;",
+            "",
+            "import otherpackage.Annotations.ProtectedAnnotation;",
+            "",
+            "public abstract class Parent {",
+            "  @ProtectedAnnotation",
+            "  public abstract String foo();",
+            "}");
+    JavaFileObject annotationsFileObject =
+        JavaFileObjects.forSourceLines(
+            "otherpackage.Annotations",
+            "package otherpackage;",
+            "",
+            "public class Annotations {",
+            "  protected @interface ProtectedAnnotation {}",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(bazFileObject, parentFileObject, annotationsFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz")
+        .contentsAsUtf8String()
+        .doesNotContain("ProtectedAnnotation");
+  }
+
+  @Test
+  public void nonVisibleProtectedClassAnnotationFromOtherPackage() {
+    JavaFileObject bazFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Outer",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "class Outer extends otherpackage.Parent {",
+            "  @AutoValue",
+            "  @AutoValue.CopyAnnotations",
+            "  @ProtectedAnnotation",
+            "  abstract static class Inner {",
+            "    abstract String foo();",
+            "  }",
+            "}");
+    JavaFileObject parentFileObject =
+        JavaFileObjects.forSourceLines(
+            "otherpackage.Parent",
+            "package otherpackage;",
+            "",
+            "public abstract class Parent {",
+            "  protected @interface ProtectedAnnotation {}",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(bazFileObject, parentFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Outer_Inner")
+        .contentsAsUtf8String()
+        .doesNotContain("ProtectedAnnotation");
+  }
+
+  @Test
+  public void builderWithVarArgsDoesNotImportJavaUtilArrays() {
+    // Repro from https://github.com/google/auto/issues/373.
+    JavaFileObject testFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Test",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import com.google.common.collect.ImmutableList;",
+            "",
+            "@AutoValue",
+            "public abstract class Test {",
+            "  abstract ImmutableList<String> foo();",
+            "",
+            "  @AutoValue.Builder",
+            "  abstract static class Builder {",
+            "    abstract Builder foo(String... foos);",
+            "    abstract Test build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(testFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Test")
+        .contentsAsUtf8String()
+        .doesNotContain("java.util.Arrays");
+  }
+
+  @Test
+  public void staticBuilderMethodInBuilderClass() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "com.example.Foo",
+            "package com.example;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Foo {",
+            "  public abstract String bar();",
+            "",
+            "  @AutoValue.Builder",
+            "  public abstract static class Builder {",
+            "    public static Builder builder() {",
+            "      return new AutoValue_Foo.Builder();",
+            "    }",
+            "",
+            "    public abstract Builder setBar(String s);",
+            "    public abstract Foo build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(javaFileObject);
+    assertThat(compilation).succeeded();
+    assertThat(compilation)
+        .hadWarningContaining("Static builder() method should be in the containing class")
+        .inFile(javaFileObject)
+        .onLineContaining("builder()");
+  }
+
+  /**
+   * Tests behaviour when the package containing an {@code @AutoValue} class also has classes with
+   * the same name as classes in {@code java.lang}. If you call a class {@code Object} you are
+   * asking for trouble, but you could innocently call a class {@code Compiler} without realizing
+   * there is a {@code java.lang.Compiler}.
+   *
+   * <p>The case where the class in question is mentioned in the {@code @AutoValue} class is the
+   * easy one, because then our logic can easily see that there is a clash and will use
+   * fully-qualified names. This is the case of the {@code Compiler} class below. The case where the
+   * class is <i>not</i> mentioned is harder. We have to realize that we can't elide the package
+   * name in {@code java.lang.Object} because there is also a {@code foo.bar.Object} in scope, and
+   * in fact it takes precedence.
+   */
+  @Test
+  public void javaLangClash() {
+    JavaFileObject object =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Object", //
+            "package foo.bar;",
+            "",
+            "public class Object {}");
+    JavaFileObject string =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.String", //
+            "package foo.bar;",
+            "",
+            "public class String {}");
+    JavaFileObject integer =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Integer", //
+            "package foo.bar;",
+            "",
+            "public class Integer {}");
+    JavaFileObject thread =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Thread", //
+            "package foo.bar;",
+            "",
+            "public class Thread {}");
+    JavaFileObject test =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Test",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Test {",
+            "  public abstract java.lang.Integer integer();",
+            "  public abstract java.lang.Thread.State state();",
+            "  public static Builder builder() {",
+            "    return new AutoValue_Test.Builder();",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public abstract static class Builder {",
+            "    public abstract Builder setInteger(java.lang.Integer x);",
+            "    public abstract Builder setState(java.lang.Thread.State x);",
+            "    public abstract Test build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor())
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(object, string, integer, thread, test);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  // This is a regression test for the problem described in
+  // https://github.com/google/auto/issues/847#issuecomment-629857642.
+  @Test
+  public void generatedParentWithGeneratedGetterButSetterInBuilder() {
+    JavaFileObject test =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Test",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "import foo.baz.GeneratedParent;",
+            "import foo.baz.GeneratedPropertyType;",
+            "import java.util.Optional;",
+            "",
+            "@AutoValue",
+            "public abstract class Test extends GeneratedParent {",
+            "  public abstract String string();",
+            "",
+            "  public static Builder builder() {",
+            "    return new AutoValue_Test.Builder();",
+            "  }",
+            "",
+            "  @AutoValue.Builder",
+            "  public abstract static class Builder extends GeneratedParent.Builder<Builder> {",
+            "    public abstract Builder setString(String x);",
+            "    public abstract Builder setGenerated(GeneratedPropertyType x);",
+            "    public abstract Test build();",
+            "  }",
+            "}");
+    AutoValueProcessor autoValueProcessor = new AutoValueProcessor();
+    GeneratedParentProcessor generatedParentProcessor =
+        new GeneratedParentProcessor(autoValueProcessor, expect);
+    Compilation compilation =
+        javac()
+            .withProcessors(autoValueProcessor, generatedParentProcessor)
+            .withOptions("-Xlint:-processing", "-implicit:none")
+            .compile(test);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Test")
+        .contentsAsUtf8String()
+        .contains("  public int integer() {");
+  }
+
+  @SupportedAnnotationTypes("*")
+  private static class GeneratedParentProcessor extends AbstractProcessor {
+    private static final String GENERATED_PARENT =
+        String.join(
+            "\n",
+            "package foo.baz;",
+            "",
+            "public abstract class GeneratedParent {",
+            "  public abstract int integer();",
+            "  public abstract GeneratedPropertyType generated();",
+            "",
+            "  public abstract static class Builder<B extends Builder<B>> {",
+            "    public abstract B setInteger(int x);",
+            "  }",
+            "}");
+    private static final String GENERATED_PROPERTY_TYPE =
+        String.join(
+            "\n",
+            "package foo.baz;",
+            "",
+            "public class GeneratedPropertyType {}");
+    private static final ImmutableMap<String, String> GENERATED_TYPES =
+        ImmutableMap.of(
+            "foo.baz.GeneratedParent", GENERATED_PARENT,
+            "foo.baz.GeneratedPropertyType", GENERATED_PROPERTY_TYPE);
+
+    private final AutoValueProcessor autoValueProcessor;
+    private final Expect expect;
+
+    GeneratedParentProcessor(AutoValueProcessor autoValueProcessor, Expect expect) {
+      this.autoValueProcessor = autoValueProcessor;
+      this.expect = expect;
+    }
+
+    private boolean generated;
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      if (!generated) {
+        generated = true;
+        // Check that AutoValueProcessor has already run and deferred the foo.bar.Test type because
+        // we haven't generated its parent yet.
+        expect.that(autoValueProcessor.deferredTypeNames()).contains("foo.bar.Test");
+        GENERATED_TYPES.forEach(
+            (typeName, source) -> {
+              try {
+                JavaFileObject generated =
+                    processingEnv
+                        .getFiler()
+                        .createSourceFile(typeName);
+                try (Writer writer = generated.openWriter()) {
+                  writer.write(source);
+                }
+              } catch (IOException e) {
+                throw new UncheckedIOException(e);
+              }
+            }
+        );
+      }
+      return false;
+    }
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latestSupported();
+    }
+  }
+
+  private String sorted(String... imports) {
+     return Arrays.stream(imports).sorted().collect(joining("\n"));
+ }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/ExtensionTest.java b/value/src/test/java/com/google/auto/value/processor/ExtensionTest.java
new file mode 100644
index 0000000..ce9eeed
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/ExtensionTest.java
@@ -0,0 +1,1187 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth8.assertThat;
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.extension.AutoValueExtension;
+import com.google.auto.value.extension.AutoValueExtension.BuilderContext;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.truth.Truth;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.JavaFileObjects;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.Writer;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+import java.util.ServiceConfigurationError;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.jar.JarOutputStream;
+import java.util.zip.ZipEntry;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.SupportedOptions;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ExtensionTest {
+
+  @Test
+  public void testExtensionCompilation() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String foo();",
+            "}");
+    JavaFileObject expectedExtensionOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoValue_Baz",
+            "package foo.bar;",
+            "",
+            "final class AutoValue_Baz extends $AutoValue_Baz {",
+            "  public AutoValue_Baz(String foo) {",
+            "    super(foo);",
+            "  }",
+            "  @Override public String foo() {",
+            "    return \"foo\";",
+            "  }",
+            "  public String dizzle() {\n",
+            "    return \"dizzle\";\n",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz")
+        .hasSourceEquivalentTo(expectedExtensionOutput);
+  }
+
+  @Test
+  public void testExtensionConsumesProperties() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String foo();",
+            "  abstract String dizzle();",
+            "}");
+    JavaFileObject expectedExtensionOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.$AutoValue_Baz",
+            "package foo.bar;",
+            "",
+            GeneratedImport.importGeneratedAnnotationType(),
+            "",
+            "@Generated(\"com.google.auto.value.processor.AutoValueProcessor\")",
+            " abstract class $AutoValue_Baz extends Baz {",
+            "",
+            "  private final String foo;",
+            "",
+            "  $AutoValue_Baz(",
+            "      String foo) {",
+            "    if (foo == null) {",
+            "      throw new NullPointerException(\"Null foo\");",
+            "    }",
+            "    this.foo = foo;",
+            "  }",
+            "",
+            "  @Override",
+            "  String foo() {",
+            "    return foo;",
+            "  }",
+            "",
+            "  @Override",
+            "  public String toString() {",
+            "    return \"Baz{\"",
+            "        + \"foo=\" + foo",
+            "        + \"}\";",
+            "  }",
+            "",
+            "  @Override",
+            "  public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof Baz) {",
+            "      Baz that = (Baz) o;",
+            "      return this.foo.equals(that.foo());",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+            "  @Override",
+            "  public int hashCode() {",
+            "    int h$ = 1;",
+            "    h$ *= 1000003;",
+            "    h$ ^= foo.hashCode();",
+            "    return h$;",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.$AutoValue_Baz")
+        .hasSourceEquivalentTo(expectedExtensionOutput);
+  }
+
+  @Test
+  public void testDoesntRaiseWarningForConsumedProperties() {
+    JavaFileObject impl =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue public abstract class Baz {",
+            "  abstract String foo();",
+            "  abstract String dizzle();",
+            "",
+            "  @AutoValue.Builder",
+            "  public abstract static class Builder {",
+            "    public abstract Builder foo(String s);",
+            "    public abstract Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))
+            .compile(impl);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void testDoesntRaiseWarningForToBuilder() {
+    JavaFileObject impl =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue public abstract class Baz {",
+            "  abstract String foo();",
+            "  abstract String dizzle();",
+            "  abstract Builder toBuilder();",
+            "",
+            "  @AutoValue.Builder",
+            "  public abstract static class Builder {",
+            "    public abstract Builder foo(String s);",
+            "    public abstract Baz build();",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))
+            .compile(impl);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void testCantConsumeTwice() {
+    class ConsumeDizzle extends NonFinalExtension {
+      @Override
+      public Set<String> consumeProperties(Context context) {
+        return ImmutableSet.of("dizzle");
+      }
+    }
+    class AlsoConsumeDizzle extends ConsumeDizzle {}
+    AutoValueExtension ext1 = new ConsumeDizzle();
+    AutoValueExtension ext2 = new AlsoConsumeDizzle();
+    Truth.assertThat(ext1).isNotEqualTo(ext2);
+    JavaFileObject impl =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue public abstract class Baz {",
+            "  abstract String foo();",
+            "  abstract String dizzle();",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(ext1, ext2)))
+            .compile(impl);
+    assertThat(compilation)
+        .hadErrorContaining("wants to consume a method that was already consumed")
+        .inFile(impl)
+        .onLineContaining("String dizzle()");
+  }
+
+  @Test
+  public void testCantConsumeNonExistentProperty() {
+    class ConsumeDizzle extends NonFinalExtension {
+      @Override
+      public Set<String> consumeProperties(Context context) {
+        return ImmutableSet.of("dizzle");
+      }
+    }
+    JavaFileObject impl =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue public abstract class Baz {",
+            "  abstract String foo();",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new ConsumeDizzle())))
+            .compile(impl);
+    assertThat(compilation)
+        .hadErrorContaining("wants to consume a property that does not exist: dizzle")
+        .inFile(impl)
+        .onLineContaining("@AutoValue public abstract class Baz");
+  }
+
+  @Test
+  public void testCantConsumeConcreteMethod() {
+    class ConsumeConcreteMethod extends NonFinalExtension {
+      @Override
+      public Set<ExecutableElement> consumeMethods(Context context) {
+        TypeElement autoValueClass = context.autoValueClass();
+        for (ExecutableElement method :
+            ElementFilter.methodsIn(autoValueClass.getEnclosedElements())) {
+          if (method.getSimpleName().contentEquals("frob")) {
+            return ImmutableSet.of(method);
+          }
+        }
+        throw new AssertionError("Could not find frob method");
+      }
+    }
+    JavaFileObject impl =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue public abstract class Baz {",
+            "  abstract String foo();",
+            "  void frob(int x) {}",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new ConsumeConcreteMethod())))
+            .compile(impl);
+    assertThat(compilation)
+        .hadErrorContainingMatch(
+            "wants to consume a method that is not one of the abstract methods in this class"
+                + ".*frob\\(int\\)")
+        .inFile(impl)
+        .onLineContaining("@AutoValue public abstract class Baz");
+  }
+
+  @Test
+  public void testCantConsumeNonExistentMethod() {
+    class ConsumeBogusMethod extends NonFinalExtension {
+      @Override
+      public Set<ExecutableElement> consumeMethods(Context context) {
+        // Find Integer.intValue() and try to consume that.
+        Elements elementUtils = context.processingEnvironment().getElementUtils();
+        TypeElement javaLangInteger = elementUtils.getTypeElement(Integer.class.getName());
+        for (ExecutableElement method :
+            ElementFilter.methodsIn(javaLangInteger.getEnclosedElements())) {
+          if (method.getSimpleName().contentEquals("intValue")) {
+            return ImmutableSet.of(method);
+          }
+        }
+        throw new AssertionError("Could not find Integer.intValue()");
+      }
+    }
+    JavaFileObject impl =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "import com.google.auto.value.AutoValue;",
+            "@AutoValue public abstract class Baz {",
+            "  abstract String foo();",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new ConsumeBogusMethod())))
+            .compile(impl);
+    assertThat(compilation)
+        .hadErrorContainingMatch(
+            "wants to consume a method that is not one of the abstract methods in this class"
+                + ".*intValue\\(\\)")
+        .inFile(impl)
+        .onLineContaining("@AutoValue public abstract class Baz");
+  }
+
+  @Test
+  public void testExtensionWithoutConsumedPropertiesFails() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String foo();",
+            "  abstract String dizzle();",
+            "  abstract Double[] bad();",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "An @AutoValue class cannot define an array-valued property unless "
+                + "it is a primitive array")
+        .inFile(javaFileObject)
+        .onLineContaining("abstract Double[] bad()");
+  }
+
+  @Test
+  public void testConsumeMethodWithArguments() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String foo();",
+            "  abstract void writeToParcel(Object parcel, int flags);",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(
+                new AutoValueProcessor(ImmutableList.of(new FakeWriteToParcelExtension())))
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void testExtensionWithBuilderCompilation() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String foo();",
+            "  abstract String bar();",
+            "",
+            "  @AutoValue.Builder public static abstract class Builder {",
+            "    public abstract Builder foo(String foo);",
+            "    public abstract Builder bar(String bar);",
+            "    public abstract Baz build();",
+            "  }",
+            "}");
+    JavaFileObject expectedExtensionOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoValue_Baz",
+            "package foo.bar;",
+            "",
+            "final class AutoValue_Baz extends $AutoValue_Baz {",
+            "  public AutoValue_Baz(String foo, String bar) {",
+            "    super(foo, bar);",
+            "  }",
+            "  @Override public String foo() {",
+            "    return \"foo\";",
+            "  }",
+            "  public String dizzle() {\n",
+            "    return \"dizzle\";\n",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz")
+        .hasSourceEquivalentTo(expectedExtensionOutput);
+  }
+
+  @Test
+  public void testLastExtensionGeneratesNoCode() {
+    doTestNoCode(new FooExtension(), new NonFinalExtension(), new SideFileExtension());
+  }
+
+  @Test
+  public void testFirstExtensionGeneratesNoCode() {
+    doTestNoCode(new SideFileExtension(), new FooExtension(), new NonFinalExtension());
+  }
+
+  @Test
+  public void testMiddleExtensionGeneratesNoCode() {
+    doTestNoCode(new FooExtension(), new SideFileExtension(), new NonFinalExtension());
+  }
+
+  @Test
+  public void testLoneExtensionGeneratesNoCode() {
+    doTestNoCode(new SideFileExtension());
+  }
+
+  private void doTestNoCode(AutoValueExtension... extensions) {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public abstract String foo();",
+            "",
+            "  public static Baz create(String foo) {",
+            "    return new AutoValue_Baz(foo);",
+            "  }",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.copyOf(extensions)))
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedFile(StandardLocation.SOURCE_OUTPUT, "foo.bar", "Side_Baz.java");
+  }
+
+  @Test
+  public void testTwoExtensionsBothWantToBeFinal() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String foo();",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(
+                new AutoValueProcessor(ImmutableList.of(new FooExtension(), new FinalExtension())))
+            .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining(
+            "More than one extension wants to generate the final class: "
+                + FooExtension.class.getName()
+                + ", "
+                + FinalExtension.class.getName())
+        .inFile(javaFileObject)
+        .onLineContaining("public abstract class Baz");
+  }
+
+  @Test
+  public void testNonFinalThenFinal() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String foo();",
+            "}");
+    FinalExtension finalExtension = new FinalExtension();
+    NonFinalExtension nonFinalExtension = new NonFinalExtension();
+    assertThat(finalExtension.generated).isFalse();
+    assertThat(nonFinalExtension.generated).isFalse();
+    Compilation compilation =
+        javac()
+            .withProcessors(
+                new AutoValueProcessor(ImmutableList.of(finalExtension, nonFinalExtension)))
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(finalExtension.generated).isTrue();
+    assertThat(nonFinalExtension.generated).isTrue();
+  }
+
+  @Test
+  public void testFinalThenNonFinal() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String foo();",
+            "}");
+    FinalExtension finalExtension = new FinalExtension();
+    NonFinalExtension nonFinalExtension = new NonFinalExtension();
+    assertThat(finalExtension.generated).isFalse();
+    assertThat(nonFinalExtension.generated).isFalse();
+    Compilation compilation =
+        javac()
+            .withProcessors(
+                new AutoValueProcessor(ImmutableList.of(nonFinalExtension, finalExtension)))
+            .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(finalExtension.generated).isTrue();
+    assertThat(nonFinalExtension.generated).isTrue();
+  }
+
+  @Test
+  public void testUnconsumedMethod() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  abstract String foo();",
+            "  abstract void writeToParcel(Object parcel, int flags);",
+            "}");
+    Compilation compilation =
+        javac()
+        .withProcessors(new AutoValueProcessor(ImmutableList.of(new FooExtension())))
+        .compile(javaFileObject);
+    assertThat(compilation)
+        .hadErrorContaining("writeToParcel");
+    assertThat(compilation)
+        .hadWarningContaining(
+            "Abstract method is neither a property getter nor a Builder converter, "
+                + "and no extension consumed it")
+        .inFile(javaFileObject)
+        .onLineContaining("abstract void writeToParcel");
+    // The error here comes from the Java compiler rather than AutoValue, so we don't assume
+    // much about what it looks like. On the other hand, the warning does come from AutoValue
+    // so we know what to expect.
+  }
+
+  /**
+   * Tests that the search for extensions doesn't completely blow AutoValue up if there is a corrupt
+   * jar in the {@code processorpath}. If we're not careful, that can lead to a
+   * ServiceConfigurationError.
+   */
+  @Test
+  public void testBadJarDoesntBlowUp() throws IOException {
+    File badJar = File.createTempFile("bogus", ".jar");
+    try {
+      doTestBadJarDoesntBlowUp(badJar);
+    } finally {
+      badJar.delete();
+    }
+  }
+
+  private void doTestBadJarDoesntBlowUp(File badJar) throws IOException {
+    FileOutputStream fileOutputStream = new FileOutputStream(badJar);
+    JarOutputStream jarOutputStream = new JarOutputStream(fileOutputStream);
+    byte[] bogusLine = "bogus line\n".getBytes("UTF-8");
+    ZipEntry zipEntry = new ZipEntry("META-INF/services/" + AutoValueExtension.class.getName());
+    zipEntry.setSize(bogusLine.length);
+    jarOutputStream.putNextEntry(zipEntry);
+    jarOutputStream.write(bogusLine);
+    jarOutputStream.close();
+    ClassLoader badJarLoader = new URLClassLoader(new URL[] {badJar.toURI().toURL()});
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "}");
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(badJarLoader))
+            .compile(javaFileObject);
+    assertThat(compilation).succeeded();
+    assertThat(compilation).hadWarningContaining(
+        "This may be due to a corrupt jar file in the compiler's classpath.\n  "
+            + ServiceConfigurationError.class.getName());
+    assertThat(compilation).generatedSourceFile("foo.bar.AutoValue_Baz");
+  }
+
+  private static final String CUSTOM_OPTION = "customAnnotation.customOption";
+
+  /**
+   * Tests that extensions providing their own (annotated) annotation types or options get picked
+   * up.
+   */
+  @Test
+  public void extensionsWithAnnotatedOptions() {
+    ExtensionWithAnnotatedOptions extension = new ExtensionWithAnnotatedOptions();
+
+    // Ensure default annotation support works
+    assertThat(extension.getSupportedOptions()).contains(CUSTOM_OPTION);
+
+    // Ensure it's carried over to the AutoValue processor
+    assertThat(new AutoValueProcessor(ImmutableList.of(extension)).getSupportedOptions())
+        .contains(CUSTOM_OPTION);
+  }
+
+  /**
+   * Tests that extensions providing their own implemented annotation types or options get picked
+   * up.
+   */
+  @Test
+  public void extensionsWithImplementedOptions() {
+    ExtensionWithImplementedOptions extension = new ExtensionWithImplementedOptions();
+
+    // Ensure it's carried over to the AutoValue processor
+    assertThat(new AutoValueProcessor(ImmutableList.of(extension)).getSupportedOptions())
+        .contains(CUSTOM_OPTION);
+  }
+
+  @SupportedOptions(CUSTOM_OPTION)
+  static class ExtensionWithAnnotatedOptions extends AutoValueExtension {
+    @Override
+    public String generateClass(
+        Context context, String className, String classToExtend, boolean isFinal) {
+      return null;
+    }
+  }
+
+  static class ExtensionWithImplementedOptions extends AutoValueExtension {
+    @Override
+    public Set<String> getSupportedOptions() {
+      return ImmutableSet.of(CUSTOM_OPTION);
+    }
+
+    @Override
+    public String generateClass(
+        Context context, String className, String classToExtend, boolean isFinal) {
+      return null;
+    }
+  }
+
+  private static class FooExtension extends AutoValueExtension {
+
+    @Override
+    public boolean applicable(Context context) {
+      return true;
+    }
+
+    @Override
+    public boolean mustBeFinal(Context context) {
+      return true;
+    }
+
+    @Override
+    public Set<String> consumeProperties(Context context) {
+      if (context.properties().containsKey("dizzle")) {
+        return ImmutableSet.of("dizzle");
+      } else {
+        return Collections.emptySet();
+      }
+    }
+
+    @Override
+    public String generateClass(
+        Context context, String className, String classToExtend, boolean isFinal) {
+      StringBuilder constructor =
+          new StringBuilder().append("  public ").append(className).append("(");
+
+      boolean first = true;
+      for (Map.Entry<String, ExecutableElement> el : context.properties().entrySet()) {
+        if (first) {
+          first = false;
+        } else {
+          constructor.append(", ");
+        }
+        constructor.append("String ").append(el.getKey());
+      }
+
+      constructor.append(") {\n");
+      constructor.append("    super(");
+
+      first = true;
+      for (Map.Entry<String, ExecutableElement> el : context.properties().entrySet()) {
+        if (first) {
+          first = false;
+        } else {
+          constructor.append(", ");
+        }
+        constructor.append(el.getKey());
+      }
+      constructor.append(");\n");
+      constructor.append("  }\n");
+
+      return String.format(
+          "package %s;\n"
+              + "\n"
+              + "%s class %s extends %s {\n"
+              + constructor
+              + "  @Override public String foo() {\n"
+              + "    return \"foo\";\n"
+              + "  }\n"
+              + "  public String dizzle() {\n"
+              + "    return \"dizzle\";\n"
+              + "  }\n"
+              + "}",
+          context.packageName(),
+          isFinal ? "final" : "abstract",
+          className,
+          classToExtend);
+    }
+  }
+
+  // Extension that generates a class that just forwards to the parent constructor.
+  // We will make subclasses that are respectively final and non-final.
+  private abstract static class EmptyExtension extends AutoValueExtension {
+    @Override
+    public boolean applicable(Context context) {
+      return true;
+    }
+
+    @Override
+    public abstract boolean mustBeFinal(Context context);
+
+    String extraText(Context context) {
+      return "";
+    }
+
+    boolean generated = false;
+
+    @Override
+    public String generateClass(
+        Context context, String className, String classToExtend, boolean isFinal) {
+      generated = true;
+
+      ImmutableList.Builder<String> typesAndNamesBuilder = ImmutableList.builder();
+      context.propertyTypes().forEach((name, type) -> typesAndNamesBuilder.add(type + " " + name));
+      String typesAndNames = Joiner.on(", ").join(typesAndNamesBuilder.build());
+      String template =
+          "package {pkg};\n"
+              + "\n"
+              + "{finalOrAbstract} class {className} extends {classToExtend} {\n"
+              + "  {className}({propertyTypesAndNames}) {\n"
+              + "    super({propertyNames});\n"
+              + "  }\n"
+              + "  {extraText}\n"
+              + "}\n";
+      return template
+          .replace("{pkg}", context.packageName())
+          .replace("{finalOrAbstract}", isFinal ? "final" : "abstract")
+          .replace("{className}", className)
+          .replace("{classToExtend}", classToExtend)
+          .replace("{propertyTypesAndNames}", typesAndNames)
+          .replace("{propertyNames}", Joiner.on(", ").join(context.properties().keySet()))
+          .replace("{extraText}", extraText(context));
+    }
+  }
+
+  private static class NonFinalExtension extends EmptyExtension {
+    @Override
+    public boolean mustBeFinal(Context context) {
+      return false;
+    }
+  }
+
+  private static class FinalExtension extends EmptyExtension {
+    @Override
+    public boolean mustBeFinal(Context context) {
+      return true;
+    }
+  }
+
+  private static class SideFileExtension extends AutoValueExtension {
+    @Override
+    public boolean applicable(Context context) {
+      return true;
+    }
+
+    @Override
+    public boolean mustBeFinal(Context context) {
+      return false;
+    }
+
+    @Override
+    public String generateClass(
+        Context context, String className, String classToExtend, boolean isFinal) {
+      String sideClassName = "Side_" + context.autoValueClass().getSimpleName();
+      String sideClass =
+          "" //
+          + "package " + context.packageName() + ";\n"
+          + "class " + sideClassName + " {}\n";
+      Filer filer = context.processingEnvironment().getFiler();
+      try {
+        String sideClassFqName = context.packageName() + "." + sideClassName;
+        JavaFileObject sourceFile =
+            filer.createSourceFile(sideClassFqName, context.autoValueClass());
+        try (Writer sourceWriter = sourceFile.openWriter()) {
+          sourceWriter.write(sideClass);
+        }
+      } catch (IOException e) {
+        context
+            .processingEnvironment()
+            .getMessager()
+            .printMessage(Diagnostic.Kind.ERROR, e.toString());
+      }
+      return null;
+    }
+  }
+
+  private static class FakeWriteToParcelExtension extends NonFinalExtension {
+    private ExecutableElement writeToParcelMethod(Context context) {
+      for (ExecutableElement method : context.abstractMethods()) {
+        if (method.getSimpleName().contentEquals("writeToParcel")) {
+          return method;
+        }
+      }
+      throw new AssertionError("Did not see abstract method writeToParcel");
+    }
+
+    @Override
+    public Set<ExecutableElement> consumeMethods(Context context) {
+      return ImmutableSet.of(writeToParcelMethod(context));
+    }
+
+    @Override
+    String extraText(Context context) {
+      // This is perhaps overgeneral. It is simply going to generate this:
+      // @Override void writeToParcel(Object parcel, int flags) {}
+      ExecutableElement methodToImplement = writeToParcelMethod(context);
+      assertThat(methodToImplement.getReturnType().getKind()).isEqualTo(TypeKind.VOID);
+      ImmutableList.Builder<String> typesAndNamesBuilder = ImmutableList.builder();
+      for (VariableElement p : methodToImplement.getParameters()) {
+        typesAndNamesBuilder.add(p.asType() + " " + p.getSimpleName());
+      }
+      return "@Override void "
+          + methodToImplement.getSimpleName()
+          + "("
+          + Joiner.on(", ").join(typesAndNamesBuilder.build())
+          + ") {}";
+    }
+  }
+
+  @Test
+  public void propertyTypes() {
+    JavaFileObject parent = JavaFileObjects.forSourceLines(
+        "foo.bar.Parent",
+        "package foo.bar;",
+        "",
+        "import java.util.List;",
+        "",
+        "interface Parent<T> {",
+        "  T thing();",
+        "  List<T> list();",
+        "}");
+    JavaFileObject autoValueClass = JavaFileObjects.forSourceLines(
+        "foo.bar.Baz",
+        "package foo.bar;",
+        "",
+        "import com.google.auto.value.AutoValue;",
+        "",
+        "@AutoValue",
+        "abstract class Baz implements Parent<String> {",
+        "}");
+    ContextChecker checker =
+        context -> {
+          assertThat(context.builder()).isEmpty();
+          Map<String, TypeMirror> propertyTypes = context.propertyTypes();
+          assertThat(propertyTypes.keySet()).containsExactly("thing", "list");
+          TypeMirror thingType = propertyTypes.get("thing");
+          assertThat(thingType).isNotNull();
+          assertThat(thingType.getKind()).isEqualTo(TypeKind.DECLARED);
+          assertThat(MoreTypes.asTypeElement(thingType).getQualifiedName().toString())
+              .isEqualTo("java.lang.String");
+          TypeMirror listType = propertyTypes.get("list");
+          assertThat(listType).isNotNull();
+          assertThat(listType.toString()).isEqualTo("java.util.List<java.lang.String>");
+        };
+    ContextCheckingExtension extension = new ContextCheckingExtension(checker);
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))
+            .compile(autoValueClass, parent);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void finalAutoValueClassName() {
+    JavaFileObject autoValueClass = JavaFileObjects.forSourceLines(
+        "foo.bar.Baz",
+        "package foo.bar;",
+        "",
+        "import com.google.auto.value.AutoValue;",
+        "",
+        "@AutoValue",
+        "abstract class Baz {",
+        "}");
+    ContextChecker checker =
+        context -> {
+          assertThat(context.finalAutoValueClassName()).isEqualTo("foo.bar.AutoValue_Baz");
+        };
+    ContextCheckingExtension extension = new ContextCheckingExtension(checker);
+    Compilation compilation =
+        javac()
+            .withProcessors(
+                new AutoValueProcessor(ImmutableList.of(extension, new FinalExtension())))
+            .compile(autoValueClass);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation).generatedSourceFile("foo.bar.AutoValue_Baz");
+    // ContextCheckingExtension doesn't generate any code, so that name must be the class generated
+    // by FinalExtension.
+  }
+
+  @Test
+  public void builderContext() {
+    JavaFileObject parent = JavaFileObjects.forSourceLines(
+        "foo.bar.Parent",
+        "package foo.bar;",
+        "",
+        "import com.google.common.collect.ImmutableList;",
+        "",
+        "interface Parent<T> {",
+        "  T thing();",
+        "  ImmutableList<T> list();",
+        "}");
+    JavaFileObject autoValueClass = JavaFileObjects.forSourceLines(
+        "foo.bar.Baz",
+        "package foo.bar;",
+        "",
+        "import com.google.auto.value.AutoValue;",
+        "import com.google.common.collect.ImmutableList;",
+        "",
+        "@AutoValue",
+        "abstract class Baz implements Parent<String> {",
+        "  static Builder builder() {",
+        "    return new AutoValue_Baz.Builder();",
+        "  }",
+        "",
+        "  abstract Builder toBuilder();",
+        "",
+        "  @AutoValue.Builder",
+        "  abstract static class Builder {",
+        "    abstract Builder setThing(String x);",
+        "    abstract Builder setList(Iterable<String> x);",
+        "    abstract Builder setList(ImmutableList<String> x);",
+        "    abstract ImmutableList.Builder<String> listBuilder();",
+        "    abstract Baz autoBuild();",
+        "    Baz build() {",
+        "      return autoBuild();",
+        "    }",
+        "  }",
+        "}");
+    ContextChecker checker =
+        context -> {
+          assertThat(context.builder()).isPresent();
+          BuilderContext builderContext = context.builder().get();
+
+          assertThat(builderContext.builderType().getQualifiedName().toString())
+              .isEqualTo("foo.bar.Baz.Builder");
+
+          Set<ExecutableElement> builderMethods = builderContext.builderMethods();
+          assertThat(builderMethods).hasSize(1);
+          ExecutableElement builderMethod = Iterables.getOnlyElement(builderMethods);
+          assertThat(builderMethod.getSimpleName().toString()).isEqualTo("builder");
+
+          Set<ExecutableElement> toBuilderMethods = builderContext.toBuilderMethods();
+          assertThat(toBuilderMethods).hasSize(1);
+          ExecutableElement toBuilderMethod = Iterables.getOnlyElement(toBuilderMethods);
+          assertThat(toBuilderMethod.getSimpleName().toString()).isEqualTo("toBuilder");
+
+          Optional<ExecutableElement> buildMethod = builderContext.buildMethod();
+          assertThat(buildMethod).isPresent();
+          assertThat(buildMethod.get().getSimpleName().toString()).isEqualTo("build");
+          assertThat(buildMethod.get().getParameters()).isEmpty();
+          assertThat(buildMethod.get().getReturnType().toString()).isEqualTo("foo.bar.Baz");
+
+          ExecutableElement autoBuildMethod = builderContext.autoBuildMethod();
+          assertThat(autoBuildMethod.getSimpleName().toString()).isEqualTo("autoBuild");
+          assertThat(autoBuildMethod.getModifiers()).contains(Modifier.ABSTRACT);
+          assertThat(autoBuildMethod.getParameters()).isEmpty();
+          assertThat(autoBuildMethod.getReturnType().toString()).isEqualTo("foo.bar.Baz");
+
+          Map<String, Set<ExecutableElement>> setters = builderContext.setters();
+          assertThat(setters.keySet()).containsExactly("thing", "list");
+          Set<ExecutableElement> thingSetters = setters.get("thing");
+          assertThat(thingSetters).hasSize(1);
+          ExecutableElement thingSetter = Iterables.getOnlyElement(thingSetters);
+          assertThat(thingSetter.getSimpleName().toString()).isEqualTo("setThing");
+          Set<ExecutableElement> listSetters = setters.get("list");
+          assertThat(listSetters).hasSize(2);
+          for (ExecutableElement listSetter : listSetters) {
+            assertThat(listSetter.getSimpleName().toString()).isEqualTo("setList");
+          }
+
+          Map<String, ExecutableElement> propertyBuilders = builderContext.propertyBuilders();
+          assertThat(propertyBuilders.keySet()).containsExactly("list");
+          assertThat(propertyBuilders.get("list").getSimpleName().toString())
+              .isEqualTo("listBuilder");
+        };
+    ContextCheckingExtension extension = new ContextCheckingExtension(checker);
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))
+            .compile(autoValueClass, parent);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  @Test
+  public void oddBuilderContext() {
+    JavaFileObject autoValueClass = JavaFileObjects.forSourceLines(
+        "foo.bar.Baz",
+        "package foo.bar;",
+        "",
+        "import com.google.auto.value.AutoValue;",
+        "import com.google.common.collect.ImmutableList;",
+        "",
+        "@AutoValue",
+        "abstract class Baz {",
+        "  abstract String string();",
+        "",
+        "  @AutoValue.Builder",
+        "  abstract static class Builder {",
+        "    abstract Builder setString(String x);",
+        "    abstract Baz oddBuild();",
+        "    Baz build(int butNotReallyBecauseOfThisParameter) {",
+        "      return null;",
+        "    }",
+        "  }",
+        "}");
+    ContextChecker checker =
+        context -> {
+          assertThat(context.builder()).isPresent();
+          BuilderContext builderContext = context.builder().get();
+          assertThat(builderContext.builderMethods()).isEmpty();
+          assertThat(builderContext.toBuilderMethods()).isEmpty();
+          assertThat(builderContext.buildMethod()).isEmpty();
+          assertThat(builderContext.autoBuildMethod().getSimpleName().toString())
+              .isEqualTo("oddBuild");
+
+          Map<String, Set<ExecutableElement>> setters = builderContext.setters();
+          assertThat(setters.keySet()).containsExactly("string");
+          Set<ExecutableElement> thingSetters = setters.get("string");
+          assertThat(thingSetters).hasSize(1);
+          ExecutableElement thingSetter = Iterables.getOnlyElement(thingSetters);
+          assertThat(thingSetter.getSimpleName().toString()).isEqualTo("setString");
+
+          assertThat(builderContext.propertyBuilders()).isEmpty();
+        };
+    ContextCheckingExtension extension = new ContextCheckingExtension(checker);
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))
+            .compile(autoValueClass);
+    assertThat(compilation).succeededWithoutWarnings();
+  }
+
+  // https://github.com/google/auto/issues/809
+  @Test
+  public void propertyErrorShouldNotCrash() {
+    JavaFileObject autoValueClass = JavaFileObjects.forSourceLines(
+        "test.Test",
+        "package test;",
+        "import com.google.auto.value.AutoValue;",
+        "import java.util.List;",
+        "",
+        "@AutoValue",
+        "public abstract class Test {",
+        "  abstract Integer property();",
+        "  abstract List<String> listProperty();",
+        "",
+        "  @AutoValue.Builder",
+        "  public interface Builder {",
+        "    Builder property(Integer property);",
+        "    Builder listProperty(List<String> listProperty);",
+        "    Builder listProperty(Integer listPropertyValues);",
+        "    Test build();",
+        "  }",
+        "}");
+    // We don't actually expect the extension to be invoked. Previously it was, and that led to a
+    // NullPointerException when calling .setters() in the checker.
+    ContextChecker checker =
+        context -> {
+          assertThat(context.builder()).isPresent();
+          assertThat(context.builder().get().setters()).isEmpty();
+        };
+    ContextCheckingExtension extension = new ContextCheckingExtension(checker);
+    Compilation compilation =
+        javac()
+            .withProcessors(new AutoValueProcessor(ImmutableList.of(extension)))
+            .compile(autoValueClass);
+    assertThat(compilation)
+        .hadErrorContaining("Parameter type java.lang.Integer of setter method")
+        .inFile(autoValueClass)
+        .onLineContaining("Builder listProperty(Integer listPropertyValues)");
+  }
+
+  private interface ContextChecker extends Consumer<AutoValueExtension.Context> {}
+
+  private static class ContextCheckingExtension extends AutoValueExtension {
+    private final Consumer<Context> checker;
+
+    ContextCheckingExtension(Consumer<Context> checker) {
+      this.checker = checker;
+    }
+
+    @Override
+    public boolean applicable(Context context) {
+      return true;
+    }
+
+    @Override
+    public String generateClass(
+        Context context, String className, String classToExtend, boolean isFinal) {
+      checker.accept(context);
+      return null;
+    }
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/GeneratedDoesNotExistTest.java b/value/src/test/java/com/google/auto/value/processor/GeneratedDoesNotExistTest.java
new file mode 100644
index 0000000..f3d3d61
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/GeneratedDoesNotExistTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.reflect.Reflection;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.JavaFileObjects;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Tests that {@link AutoValueProcessor} works even if run in a context where the {@code @Generated}
+ * annotation does not exist.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(Parameterized.class)
+public class GeneratedDoesNotExistTest {
+
+  @Parameters(name = "{0}")
+  public static Collection<Object[]> data() {
+    ImmutableList.Builder<Object[]> params = ImmutableList.builder();
+    if (SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0) {
+      // use default options when running on JDK > 8
+      // TODO(b/72513371): use --release 8 once compile-testing supports that
+      params.add(
+          new Object[] {
+            ImmutableList.of(), "javax.annotation.processing.Generated",
+          });
+    }
+    params.add(
+        new Object[] {
+          ImmutableList.of("-source", "8", "-target", "8"), "javax.annotation.Generated",
+        });
+    return params.build();
+  }
+
+  private final ImmutableList<String> javacOptions;
+  private final String expectedAnnotation;
+
+  public GeneratedDoesNotExistTest(ImmutableList<String> javacOptions, String expectedAnnotation) {
+    this.javacOptions = javacOptions;
+    this.expectedAnnotation = expectedAnnotation;
+  }
+
+  // The classes here are basically just rigmarole to ensure that
+  // Types.getTypeElement("javax.annotation.Generated") returns null, and to check that something
+  // called that. We want a Processor that forwards everything to AutoValueProcessor, except that
+  // the init(ProcessingEnvironment) method should forward a ProcessingEnvironment that filters
+  // out the Generated class. So that ProcessingEnvironment forwards everything to the real
+  // ProcessingEnvironment, except the ProcessingEnvironment.getElementUtils() method. That method
+  // returns an Elements object that forwards everything to the real Elements except
+  // getTypeElement("javax.annotation.Generated") and
+  // getTypeElement("javax.annotation.processing.Generated").
+
+  private static final ImmutableSet<String> GENERATED_ANNOTATIONS =
+      ImmutableSet.of("javax.annotation.Generated", "javax.annotation.processing.Generated");
+
+  /**
+   * InvocationHandler that forwards every method to an original object, except methods where there
+   * is an implementation in this class with the same signature. So for example in the subclass
+   * {@link ElementsHandler} there is a method {@link ElementsHandler#getTypeElement(CharSequence)},
+   * which means that a call of {@link Elements#getTypeElement(CharSequence)} on the proxy with this
+   * invocation handler will end up calling that method, but a call of any of the other methods of
+   * {@code Elements} will end up calling the method on the original object.
+   */
+  private abstract static class OverridableInvocationHandler<T> implements InvocationHandler {
+    final T original;
+
+    OverridableInvocationHandler(T original) {
+      this.original = original;
+    }
+
+    @Override
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+      try {
+        Method override = getClass().getMethod(method.getName(), method.getParameterTypes());
+        if (override.getDeclaringClass() == getClass()) {
+          return override.invoke(this, args);
+        }
+      } catch (NoSuchMethodException ignored) {
+        // OK: we don't have an override for this method, so just invoke the original method.
+      }
+      return method.invoke(original, args);
+    }
+  }
+
+  private static <T> T partialProxy(Class<T> type, OverridableInvocationHandler<T> handler) {
+    return Reflection.newProxy(type, handler);
+  }
+
+  private static class ElementsHandler extends OverridableInvocationHandler<Elements> {
+
+    private final Set<String> ignoredGenerated;
+
+    ElementsHandler(Elements original, Set<String> ignoredGenerated) {
+      super(original);
+      this.ignoredGenerated = ignoredGenerated;
+    }
+
+    public TypeElement getTypeElement(CharSequence name) {
+      if (GENERATED_ANNOTATIONS.contains(name.toString())) {
+        ignoredGenerated.add(name.toString());
+        return null;
+      } else {
+        return original.getTypeElement(name);
+      }
+    }
+  }
+
+  private static class ProcessingEnvironmentHandler
+      extends OverridableInvocationHandler<ProcessingEnvironment> {
+    private final Elements noGeneratedElements;
+
+    ProcessingEnvironmentHandler(ProcessingEnvironment original, Set<String> ignoredGenerated) {
+      super(original);
+      ElementsHandler elementsHandler =
+          new ElementsHandler(original.getElementUtils(), ignoredGenerated);
+      this.noGeneratedElements = partialProxy(Elements.class, elementsHandler);
+    }
+
+    public Elements getElementUtils() {
+      return noGeneratedElements;
+    }
+  }
+
+  private static class ProcessorHandler extends OverridableInvocationHandler<Processor> {
+    private final Set<String> ignoredGenerated;
+
+    ProcessorHandler(Processor original, Set<String> ignoredGenerated) {
+      super(original);
+      this.ignoredGenerated = ignoredGenerated;
+    }
+
+    public void init(ProcessingEnvironment processingEnv) {
+      ProcessingEnvironmentHandler processingEnvironmentHandler =
+          new ProcessingEnvironmentHandler(processingEnv, ignoredGenerated);
+      ProcessingEnvironment noGeneratedProcessingEnvironment =
+          partialProxy(ProcessingEnvironment.class, processingEnvironmentHandler);
+      original.init(noGeneratedProcessingEnvironment);
+    }
+  }
+
+  @Test
+  public void test() {
+    JavaFileObject javaFileObject =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.Baz",
+            "package foo.bar;",
+            "",
+            "import com.google.auto.value.AutoValue;",
+            "",
+            "@AutoValue",
+            "public abstract class Baz {",
+            "  public static Baz create() {",
+            "    return new AutoValue_Baz();",
+            "  }",
+            "}");
+    JavaFileObject expectedOutput =
+        JavaFileObjects.forSourceLines(
+            "foo.bar.AutoValue_Baz",
+            "package foo.bar;",
+            "",
+            "final class AutoValue_Baz extends Baz {",
+            "  AutoValue_Baz() {",
+            "  }",
+            "",
+            "  @Override public String toString() {",
+            "    return \"Baz{\"",
+            "        + \"}\";",
+            "  }",
+            "",
+            "  @Override public boolean equals(Object o) {",
+            "    if (o == this) {",
+            "      return true;",
+            "    }",
+            "    if (o instanceof Baz) {",
+            "      return true;",
+            "    }",
+            "    return false;",
+            "  }",
+            "",
+            "  @Override public int hashCode() {",
+            "    int h$ = 1;",
+            "    return h$;",
+            "  }",
+            "}");
+    Set<String> ignoredGenerated = ConcurrentHashMap.newKeySet();
+    Processor autoValueProcessor = new AutoValueProcessor();
+    ProcessorHandler handler = new ProcessorHandler(autoValueProcessor, ignoredGenerated);
+    Processor noGeneratedProcessor = partialProxy(Processor.class, handler);
+    Compilation compilation =
+        javac()
+        .withOptions(javacOptions)
+        .withProcessors(noGeneratedProcessor)
+        .compile(javaFileObject);
+    assertThat(compilation).succeededWithoutWarnings();
+    assertThat(compilation)
+        .generatedSourceFile("foo.bar.AutoValue_Baz")
+        .hasSourceEquivalentTo(expectedOutput);
+    assertThat(ignoredGenerated).containsExactly(expectedAnnotation);
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/GeneratedImport.java b/value/src/test/java/com/google/auto/value/processor/GeneratedImport.java
new file mode 100644
index 0000000..35af5a8
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/GeneratedImport.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import javax.lang.model.SourceVersion;
+
+/**
+ * Utility methods for compile-testing tests to know which {@code @Generated} annotation is
+ * available.
+ */
+final class GeneratedImport {
+
+  /**
+   * Returns the qualified name of the {@code @Generated} annotation available during a compilation
+   * task.
+   */
+  static String generatedAnnotationType() {
+    return SourceVersion.latestSupported().compareTo(SourceVersion.RELEASE_8) > 0
+        ? "javax.annotation.processing.Generated"
+        : "javax.annotation.Generated";
+  }
+
+  /**
+   * Returns an {@code import} statement that imports the {@code @Generated} annotation {@linkplain
+   * #generatedAnnotationType() available during a compilation task}.
+   */
+  static String importGeneratedAnnotationType() {
+    return "import " + generatedAnnotationType() + ";";
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/GuavaCollectionBuildersTest.java b/value/src/test/java/com/google/auto/value/processor/GuavaCollectionBuildersTest.java
new file mode 100644
index 0000000..4e28224
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/GuavaCollectionBuildersTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.reflect.ClassPath;
+import com.google.common.truth.Expect;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Validates the assumptions AutoValue makes about Guava immutable collection builders. We expect
+ * for each public class {@code com.google.common.collect.ImmutableFoo} that:
+ *
+ * <ul>
+ *   <li>it contains a public nested class {@code ImmutableFoo.Builder} with the same type
+ *       parameters;
+ *   <li>there is a public static method {@code ImmutableFoo.builder()} that returns {@code
+ *       ImmutableFoo.Builder};
+ *   <li>there is a method {@code ImmutableFoo.Builder.build()} that returns {@code ImmutableFoo};
+ *   <li>and there is a method in {@code ImmutableFoo.Builder} called either {@code addAll} or
+ *       {@code putAll} with a single parameter to which {@code ImmutableFoo} can be assigned.
+ * </ul>
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class GuavaCollectionBuildersTest {
+  private static final ImmutableSet<String> NON_BUILDABLE_COLLECTIONS =
+      ImmutableSet.of("ImmutableCollection");
+
+  @Rule public final Expect expect = Expect.create();
+
+  @Test
+  public void testImmutableBuilders() throws Exception {
+    ClassPath classPath = ClassPath.from(getClass().getClassLoader());
+    ImmutableSet<ClassPath.ClassInfo> classes = classPath.getAllClasses();
+    int checked = 0;
+    for (ClassPath.ClassInfo classInfo : classes) {
+      if (classInfo.getPackageName().equals("com.google.common.collect")
+          && classInfo.getSimpleName().startsWith("Immutable")
+          && !NON_BUILDABLE_COLLECTIONS.contains(classInfo.getSimpleName())) {
+        Class<?> c = Class.forName(classInfo.getName());
+        if (Modifier.isPublic(c.getModifiers())) {
+          checked++;
+          checkImmutableClass(c);
+        }
+      }
+    }
+    expect.that(checked).isGreaterThan(10);
+  }
+
+  private void checkImmutableClass(Class<?> c)
+      throws ClassNotFoundException, NoSuchMethodException {
+    if (!Modifier.isPublic(c.getModifiers())) {
+      return;
+    }
+
+    // We have a public static ImmutableFoo.builder()
+    Method builderMethod = c.getMethod("builder");
+    assertThat(Modifier.isStatic(builderMethod.getModifiers())).isTrue();
+
+    // Its return type is Builder with the same type parameters.
+    Type builderMethodReturn = builderMethod.getGenericReturnType();
+    expect.that(builderMethodReturn).isInstanceOf(ParameterizedType.class);
+    ParameterizedType builderMethodParameterizedReturn = (ParameterizedType) builderMethodReturn;
+    Class<?> builderClass = Class.forName(c.getName() + "$Builder");
+    expect.that(builderMethod.getReturnType()).isEqualTo(builderClass);
+    expect
+        .withMessage(c.getName())
+        .that(Arrays.toString(builderMethodParameterizedReturn.getActualTypeArguments()))
+        .isEqualTo(Arrays.toString(builderClass.getTypeParameters()));
+
+    // The Builder has a public build() method that returns ImmutableFoo.
+    Method buildMethod = builderClass.getMethod("build");
+    expect.that(buildMethod.getReturnType()).isEqualTo(c);
+
+    // The Builder has either an addAll or a putAll public method with a parameter that
+    // ImmutableFoo can be assigned to.
+    boolean found = false;
+    for (Method m : builderClass.getMethods()) {
+      if ((m.getName().equals("addAll") || m.getName().equals("putAll"))
+          && m.getParameterTypes().length == 1) {
+        Class<?> parameter = m.getParameterTypes()[0];
+        if (parameter.isAssignableFrom(c)) {
+          found = true;
+          break;
+        }
+      }
+    }
+    expect.withMessage(builderClass.getName() + " has addAll or putAll").that(found).isTrue();
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/IncrementalExtensionTest.java b/value/src/test/java/com/google/auto/value/processor/IncrementalExtensionTest.java
new file mode 100644
index 0000000..27cb093
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/IncrementalExtensionTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Correspondence.transforming;
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.auto.value.extension.AutoValueExtension;
+import com.google.auto.value.extension.AutoValueExtension.IncrementalExtensionType;
+import com.google.auto.value.extension.memoized.processor.MemoizeExtension;
+import com.google.auto.value.extension.serializable.processor.SerializableAutoValueExtension;
+import com.google.common.collect.ImmutableList;
+import javax.annotation.processing.ProcessingEnvironment;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessorType;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests of Gradle incrementality in the presence of extensions. See
+ * <a href="https://docs.gradle.org/5.0/userguide/java_plugin.html#sec:incremental_annotation_processing">
+ * incremental annotation processing</a> in the Gradle user guide.
+ */
+@RunWith(JUnit4.class)
+public class IncrementalExtensionTest {
+  @Test
+  public void builtInExtensionsAreIsolating() {
+    ImmutableList<AutoValueExtension> builtInExtensions =
+        AutoValueProcessor.extensionsFromLoader(AutoValueProcessor.class.getClassLoader());
+    // These are the current built-in extensions. We will update this test if we add more.
+    // The (Object) cast is because otherwise the inferred type is Class<?>, and we can't match
+    // that <?> with the class literals here. Even if we cast them to Class<?> it will be a
+    // different <?>.
+    assertThat(builtInExtensions)
+        .comparingElementsUsing(transforming(e -> (Object) e.getClass(), "is class"))
+        .containsExactly(MemoizeExtension.class, SerializableAutoValueExtension.class);
+
+    AutoValueProcessor processor = new AutoValueProcessor(builtInExtensions);
+    assertThat(processor.getSupportedOptions())
+        .contains(IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());
+  }
+
+  @Test
+  public void customExtensionsAreNotIsolatingByDefault() {
+    AutoValueExtension nonIsolatingExtension = new NonIsolatingExtension();
+    assertThat(nonIsolatingExtension.incrementalType((ProcessingEnvironment) null))
+        .isEqualTo(IncrementalExtensionType.UNKNOWN);
+    ImmutableList<AutoValueExtension> extensions = ImmutableList.<AutoValueExtension>builder()
+        .addAll(AutoValueProcessor.extensionsFromLoader(AutoValueProcessor.class.getClassLoader()))
+        .add(nonIsolatingExtension)
+        .build();
+
+    AutoValueProcessor processor = new AutoValueProcessor(extensions);
+    assertThat(processor.getSupportedOptions())
+        .doesNotContain(IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());
+  }
+
+  @Test
+  public void customExtensionsCanBeIsolating() {
+    AutoValueExtension isolatingExtension = new IsolatingExtension();
+    assertThat(isolatingExtension.incrementalType((ProcessingEnvironment) null))
+        .isEqualTo(IncrementalExtensionType.ISOLATING);
+    ImmutableList<AutoValueExtension> extensions = ImmutableList.<AutoValueExtension>builder()
+        .addAll(AutoValueProcessor.extensionsFromLoader(AutoValueProcessor.class.getClassLoader()))
+        .add(isolatingExtension)
+        .build();
+
+    AutoValueProcessor processor = new AutoValueProcessor(extensions);
+    assertThat(processor.getSupportedOptions())
+        .contains(IncrementalAnnotationProcessorType.ISOLATING.getProcessorOption());
+  }
+
+  // Extensions are "UNKNOWN" by default.
+  private static class NonIsolatingExtension extends AutoValueExtension {
+    @Override
+    public String generateClass(
+        Context context, String className, String classToExtend, boolean isFinal) {
+      return null;
+    }
+  }
+
+  // Extensions are "ISOLATING" if they say they are.
+  private static class IsolatingExtension extends AutoValueExtension {
+    @Override
+    public IncrementalExtensionType incrementalType(ProcessingEnvironment processingEnvironment) {
+      return IncrementalExtensionType.ISOLATING;
+    }
+
+    @Override
+    public String generateClass(
+        Context context, String className, String classToExtend, boolean isFinal) {
+      return null;
+    }
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/JavaScannerTest.java b/value/src/test/java/com/google/auto/value/processor/JavaScannerTest.java
new file mode 100644
index 0000000..3632bbb
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/JavaScannerTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** @author emcmanus@google.com (Éamonn McManus) */
+@RunWith(JUnit4.class)
+public class JavaScannerTest {
+  private static final ImmutableList<String> TOKENS =
+      ImmutableList.of(
+          "  ",
+          "\"hello \\\" world\\n\"",
+          "'a'",
+          "  ",
+          "'\\t'",
+          "  ",
+          "`com.google.Foo`",
+          "   ",
+          "\n  ",
+          "/* comment * comment \" whatever\n     comment continued */",
+          "  ",
+          "t",
+          "h",
+          "i",
+          "n",
+          "g",
+          " ",
+          "t",
+          "h",
+          "i",
+          "n",
+          "g",
+          "  ",
+          "// line comment",
+          "\n",
+          "/*/ tricky comment */",
+          "\n");
+
+  /**
+   * Tests basic scanner functionality. The test concatenates the tokens in {@link #TOKENS} and then
+   * retokenizes that string, checking that the same list of tokens is produced.
+   */
+  @Test
+  public void testScanner() {
+    String input = Joiner.on("").join(TOKENS);
+    ImmutableList.Builder<String> tokensBuilder = ImmutableList.builder();
+    JavaScanner tokenizer = new JavaScanner(input);
+    int end;
+    for (int i = 0; i < input.length(); i = end) {
+      end = tokenizer.tokenEnd(i);
+      tokensBuilder.add(input.substring(i, end));
+    }
+    assertThat(tokensBuilder.build()).containsExactlyElementsIn(TOKENS).inOrder();
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/PropertyAnnotationsTest.java b/value/src/test/java/com/google/auto/value/processor/PropertyAnnotationsTest.java
new file mode 100644
index 0000000..2c3bea0
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/PropertyAnnotationsTest.java
@@ -0,0 +1,560 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.testing.compile.JavaSourceSubjectFactory.javaSource;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.testing.compile.JavaFileObjects;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nullable;
+import javax.tools.JavaFileObject;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests to ensure annotations are kept on AutoValue generated classes
+ *
+ * @author jmcampanini
+ */
+@RunWith(JUnit4.class)
+public class PropertyAnnotationsTest {
+  private static final String TEST_ANNOTATION =
+      "@PropertyAnnotationsTest.TestAnnotation";
+  private static final String TEST_ARRAY_ANNOTATION =
+      "@PropertyAnnotationsTest.TestArrayAnnotation";
+
+  public enum TestEnum {
+    A,
+    B;
+
+    @Override
+    public String toString() {
+      // used to prove that the method we determine the value does not use the `toString()` method
+      // of the enum
+      return "not the same value";
+    }
+  }
+
+  public @interface TestAnnotation {
+    byte testByte() default 1;
+
+    short testShort() default 2;
+
+    int testInt() default 3;
+
+    long testLong() default 4L;
+
+    float testFloat() default 5.6f;
+
+    double testDouble() default 7.8d;
+
+    char testChar() default 'a';
+
+    String testString() default "10";
+
+    boolean testBoolean() default false;
+
+    Class<?> testClass() default TestEnum.class;
+
+    TestEnum testEnum() default TestEnum.A;
+
+    OtherAnnotation testAnnotation() default @OtherAnnotation(foo = 23, bar = "baz");
+  }
+
+  public @interface OtherAnnotation {
+    int foo() default 123;
+
+    String bar() default "bar";
+  }
+
+  public @interface TestArrayAnnotation {
+    byte[] testBytes() default {1, 2};
+
+    short[] testShorts() default {3, 4};
+
+    int[] testInts() default {5, 6};
+
+    long[] testLongs() default {7L, 8L};
+
+    float[] testFloats() default {9.1f, 2.3f};
+
+    double[] testDoubles() default {4.5d, 6.7d};
+
+    char[] testChars() default {'a', 'b'};
+
+    String[] testStrings() default {"cde", "fgh"};
+
+    boolean[] testBooleans() default {true, false};
+
+    Class<?>[] testClasses() default {TestEnum.class, TestEnum.class};
+
+    TestEnum[] testEnums() default {TestEnum.A, TestEnum.B};
+
+    OtherAnnotation[] testAnnotations() default {
+      @OtherAnnotation(foo = 999), @OtherAnnotation(bar = "baz")
+    };
+  }
+
+  @Inherited
+  public @interface InheritedAnnotation {}
+
+  private static class InputFileBuilder {
+    Iterable<String> imports = ImmutableList.of();
+    List<String> annotations = new ArrayList<>();
+    List<String> innerTypes = new ArrayList<>();
+
+    InputFileBuilder setImports(Iterable<String> imports) {
+      this.imports = imports;
+      return this;
+    }
+
+    InputFileBuilder addAnnotations(String... annotations) {
+      this.annotations.addAll(ImmutableList.copyOf(annotations));
+      return this;
+    }
+
+    InputFileBuilder addAnnotations(Iterable<String> annotations) {
+      this.annotations.addAll(ImmutableList.copyOf(annotations));
+      return this;
+    }
+
+    InputFileBuilder addInnerTypes(String... innerTypes) {
+      this.innerTypes.addAll(ImmutableList.copyOf(innerTypes));
+      return this;
+    }
+
+    JavaFileObject build() {
+      ImmutableList<String> list =
+          ImmutableList.<String>builder()
+              .add("package foo.bar;", "", "import com.google.auto.value.AutoValue;")
+              .addAll(imports)
+              .add("", "@AutoValue", "public abstract class Baz {")
+              .addAll(annotations)
+              .add(
+                  "  public abstract int buh();",
+                  "",
+                  "  public static Baz create(int buh) {",
+                  "    return new AutoValue_Baz(buh);",
+                  "  }")
+              .addAll(innerTypes)
+              .add("}")
+              .build();
+      String[] lines = list.toArray(new String[list.size()]);
+      return JavaFileObjects.forSourceLines("foo.bar.Baz", lines);
+    }
+  }
+
+  private static class OutputFileBuilder {
+    Iterable<String> imports = ImmutableList.of();
+    List<String> fieldAnnotations = new ArrayList<>();
+    List<String> methodAnnotations = new ArrayList<>();
+
+    OutputFileBuilder setImports(Iterable<String> imports) {
+      this.imports = imports;
+      return this;
+    }
+
+    OutputFileBuilder addFieldAnnotations(String... annotations) {
+      this.fieldAnnotations.addAll(ImmutableList.copyOf(annotations));
+      return this;
+    }
+
+    OutputFileBuilder addMethodAnnotations(String... innerTypes) {
+      this.methodAnnotations.addAll(ImmutableList.copyOf(innerTypes));
+      return this;
+    }
+
+    OutputFileBuilder addMethodAnnotations(Iterable<String> innerTypes) {
+      this.methodAnnotations.addAll(ImmutableList.copyOf(innerTypes));
+      return this;
+    }
+
+    JavaFileObject build() {
+      String nullable = methodAnnotations.contains("@Nullable") ? "@Nullable " : "";
+      ImmutableSortedSet<String> allImports =
+          ImmutableSortedSet.<String>naturalOrder()
+              .add(GeneratedImport.importGeneratedAnnotationType())
+              .addAll(imports)
+              .build();
+      ImmutableList<String> list =
+          ImmutableList.<String>builder()
+              .add("package foo.bar;", "")
+              .addAll(allImports)
+              .add(
+                  "",
+                  "@Generated(\"" + AutoValueProcessor.class.getName() + "\")",
+                  "final class AutoValue_Baz extends Baz {")
+              .addAll(fieldAnnotations)
+              .add(
+                  "  private final int buh;",
+                  "  AutoValue_Baz(" + nullable + "int buh) {",
+                  "    this.buh = buh;",
+                  "  }",
+                  "")
+              .addAll(methodAnnotations)
+              .add(
+                  "  @Override public int buh() {",
+                  "    return buh;",
+                  "  }",
+                  "",
+                  "  @Override public String toString() {",
+                  "    return \"Baz{\"",
+                  "        + \"buh=\" + buh",
+                  "        + \"}\";",
+                  "  }",
+                  "",
+                  "  @Override public boolean equals(Object o) {",
+                  "    if (o == this) {",
+                  "      return true;",
+                  "    }",
+                  "    if (o instanceof Baz) {",
+                  "      Baz that = (Baz) o;",
+                  "      return this.buh == that.buh();",
+                  "    }",
+                  "    return false;",
+                  "  }",
+                  "",
+                  "  @Override public int hashCode() {",
+                  "    int h$ = 1;",
+                  "    h$ *= 1000003;",
+                  "    h$ ^= buh;",
+                  "    return h$;",
+                  "  }",
+                  "}")
+              .build();
+
+      String[] lines = list.toArray(new String[list.size()]);
+      return JavaFileObjects.forSourceLines("foo.bar.AutoValue_Baz", lines);
+    }
+  }
+
+  private ImmutableSet<String> getImports(Class<?>... classes) {
+    ImmutableSet.Builder<String> stringBuilder = ImmutableSortedSet.naturalOrder();
+    for (Class<?> clazz : classes) {
+      stringBuilder.add("import " + clazz.getName() + ";");
+    }
+    return stringBuilder.build();
+  }
+
+  private void assertGeneratedMatches(
+      Iterable<String> imports,
+      Iterable<String> annotations,
+      Iterable<String> expectedMethodAnnotations) {
+
+    JavaFileObject javaFileObject =
+        new InputFileBuilder().setImports(imports).addAnnotations(annotations).build();
+
+    JavaFileObject expectedOutput =
+        new OutputFileBuilder()
+            .setImports(imports)
+            .addMethodAnnotations(expectedMethodAnnotations)
+            .build();
+
+    assertAbout(javaSource())
+        .that(javaFileObject)
+        .processedWith(new AutoValueProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(expectedOutput);
+  }
+
+  @Test
+  public void testSimpleAnnotation() {
+    assertGeneratedMatches(
+        ImmutableList.of(), ImmutableList.of("@Deprecated"), ImmutableList.of("@Deprecated"));
+  }
+
+  @Test
+  public void testSingleStringValueAnnotation() {
+    assertGeneratedMatches(
+        ImmutableList.of(),
+        ImmutableList.of("@SuppressWarnings(\"a\")"),
+        ImmutableList.of("@SuppressWarnings(\"a\")"));
+  }
+
+  @Test
+  public void testMultiStringValueAnnotation() {
+    assertGeneratedMatches(
+        ImmutableList.of(),
+        ImmutableList.of("@SuppressWarnings({\"a\", \"b\"})"),
+        ImmutableList.of("@SuppressWarnings({\"a\", \"b\"})"));
+  }
+
+  @Test
+  public void testNumberValueAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(TEST_ANNOTATION + "(testShort = 1, testInt = 2, testLong = 3L)"),
+        ImmutableList.of(TEST_ANNOTATION + "(testShort = 1, testInt = 2, testLong = 3L)"));
+  }
+
+  @Test
+  public void testByteValueAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(TEST_ANNOTATION + "(testByte = 0)"),
+        ImmutableList.of(TEST_ANNOTATION + "(testByte = 0)"));
+  }
+
+  @Test
+  public void testDecimalValueAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(TEST_ANNOTATION + "(testDouble = 1.2d, testFloat = 3.4f)"),
+        ImmutableList.of(TEST_ANNOTATION + "(testDouble = 1.2d, testFloat = 3.4f)"));
+  }
+
+  @Test
+  public void testOtherValuesAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ANNOTATION + "(testBoolean = true, testString = \"hallo\", testChar = 'a')"),
+        ImmutableList.of(
+            TEST_ANNOTATION + "(testBoolean = true, testString = \"hallo\", testChar = 'a')"));
+  }
+
+  @Test
+  public void testClassAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(TEST_ANNOTATION + "(testClass = String.class)"),
+        ImmutableList.of(TEST_ANNOTATION + "(testClass = String.class)"));
+  }
+
+  @Test
+  public void testEnumAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ANNOTATION
+                + "(testEnum = "
+                + PropertyAnnotationsTest.class.getName()
+                + ".TestEnum.A)"),
+        ImmutableList.of(TEST_ANNOTATION + "(testEnum = PropertyAnnotationsTest.TestEnum.A)"));
+  }
+
+  @Test
+  public void testEmptyAnnotationAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ANNOTATION + "(testAnnotation = @PropertyAnnotationsTest.OtherAnnotation)"),
+        ImmutableList.of(
+            TEST_ANNOTATION + "(testAnnotation = @PropertyAnnotationsTest.OtherAnnotation)"));
+  }
+
+  @Test
+  public void testValuedAnnotationAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ANNOTATION
+                + "(testAnnotation = @PropertyAnnotationsTest.OtherAnnotation(foo=999))"),
+        ImmutableList.of(
+            TEST_ANNOTATION
+                + "(testAnnotation = @PropertyAnnotationsTest.OtherAnnotation(foo=999))"));
+  }
+
+  @Test
+  public void testNumberArrayAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testShorts = {2, 3}, testInts = {4, 5}, testLongs = {6L, 7L})"),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testShorts = {2, 3}, testInts = {4, 5}, testLongs = {6L, 7L})"));
+  }
+
+  @Test
+  public void testByteArrayAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(TEST_ARRAY_ANNOTATION + "(testBytes = {0, 1})"),
+        ImmutableList.of(TEST_ARRAY_ANNOTATION + "(testBytes = {0, 1})"));
+  }
+
+  @Test
+  public void testDecimalArrayAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION + "(testDoubles = {1.2d, 3.4d}, testFloats = {5.6f, 7.8f})"),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION + "(testDoubles = {1.2d, 3.4d}, testFloats = {5.6f, 7.8f})"));
+  }
+
+  @Test
+  public void testOtherArrayAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testBooleans = {false, false},"
+                + " testStrings = {\"aaa\", \"bbb\"}, testChars={'x', 'y'})"),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testBooleans = {false, false},"
+                + " testStrings = {\"aaa\", \"bbb\"}, testChars={'x', 'y'})"));
+  }
+
+  @Test
+  public void testClassArrayAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(TEST_ARRAY_ANNOTATION + "(testClasses = {String.class, Long.class})"),
+        ImmutableList.of(TEST_ARRAY_ANNOTATION + "(testClasses = {String.class, Long.class})"));
+  }
+
+  @Test
+  public void testImportedClassArrayAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class, Nullable.class),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testClasses = {javax.annotation.Nullable.class, Long.class})"),
+        ImmutableList.of(TEST_ARRAY_ANNOTATION + "(testClasses = {Nullable.class, Long.class})"));
+  }
+
+  @Test
+  public void testEnumArrayAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION + "(testEnums = {PropertyAnnotationsTest.TestEnum.A,"
+                + " PropertyAnnotationsTest.TestEnum.B})"),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION + "(testEnums = {PropertyAnnotationsTest.TestEnum.A,"
+                + " PropertyAnnotationsTest.TestEnum.B})"));
+  }
+
+  @Test
+  public void testArrayOfEmptyAnnotationAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testAnnotations = {@PropertyAnnotationsTest.OtherAnnotation})"),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testAnnotations = @PropertyAnnotationsTest.OtherAnnotation)"));
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testAnnotations = {@PropertyAnnotationsTest.OtherAnnotation,"
+                + " @PropertyAnnotationsTest.OtherAnnotation})"),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testAnnotations = {@PropertyAnnotationsTest.OtherAnnotation,"
+                + " @PropertyAnnotationsTest.OtherAnnotation})"));
+  }
+
+  @Test
+  public void testArrayOfValuedAnnotationAnnotation() {
+    assertGeneratedMatches(
+        getImports(PropertyAnnotationsTest.class),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testAnnotations = {@PropertyAnnotationsTest.OtherAnnotation(foo = 999)})"),
+        ImmutableList.of(
+            TEST_ARRAY_ANNOTATION
+                + "(testAnnotations = @PropertyAnnotationsTest.OtherAnnotation(foo = 999))"));
+  }
+
+  /**
+   * Tests that when CopyAnnotations is present on a method, all non-inherited annotations (except
+   * those appearing in CopyAnnotations.exclude) are copied to the method implementation in the
+   * generated class.
+   */
+  @Test
+  public void testCopyingMethodAnnotations() {
+    ImmutableSet<String> imports = getImports(PropertyAnnotationsTest.class);
+    JavaFileObject inputFile =
+        new InputFileBuilder()
+            .setImports(imports)
+            .addAnnotations(
+                "@AutoValue.CopyAnnotations(exclude="
+                    + "{PropertyAnnotationsTest.TestAnnotation.class})",
+                "@Deprecated",
+                "@PropertyAnnotationsTest.TestAnnotation",
+                "@PropertyAnnotationsTest.InheritedAnnotation")
+            .build();
+
+    JavaFileObject outputFile =
+        new OutputFileBuilder()
+            .setImports(imports)
+            .addMethodAnnotations("@Deprecated", "@PropertyAnnotationsTest.InheritedAnnotation")
+            .addFieldAnnotations("@Deprecated", "@PropertyAnnotationsTest.InheritedAnnotation")
+            .build();
+
+    assertAbout(javaSource())
+        .that(inputFile)
+        .processedWith(new AutoValueProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(outputFile);
+  }
+
+  /**
+   * Tests that when CopyAnnotationsToGeneratedField is present on a method, all non-inherited
+   * annotations (except those appearing in CopyAnnotationsToGeneratedField.exclude) are copied to
+   * the method implementation in the generated class.
+   */
+  @Test
+  public void testCopyingMethodAnnotationsToGeneratedFields() {
+    JavaFileObject inputFile =
+        new InputFileBuilder()
+            .setImports(getImports(PropertyAnnotationsTest.class, Target.class, ElementType.class))
+            .addAnnotations(
+                "@AutoValue.CopyAnnotations(exclude={PropertyAnnotationsTest."
+                    + "TestAnnotation.class})",
+                "@Deprecated",
+                "@PropertyAnnotationsTest.TestAnnotation",
+                "@PropertyAnnotationsTest.InheritedAnnotation",
+                "@MethodsOnly")
+            .addInnerTypes("@Target(ElementType.METHOD) @interface MethodsOnly {}")
+            .build();
+
+    JavaFileObject outputFile =
+        new OutputFileBuilder()
+            .setImports(getImports(PropertyAnnotationsTest.class))
+            .addFieldAnnotations("@Deprecated", "@PropertyAnnotationsTest.InheritedAnnotation")
+            .addMethodAnnotations(
+                "@Deprecated",
+                "@PropertyAnnotationsTest.InheritedAnnotation",
+                "@Baz.MethodsOnly")
+            .build();
+
+    assertAbout(javaSource())
+        .that(inputFile)
+        .processedWith(new AutoValueProcessor())
+        .compilesWithoutError()
+        .and()
+        .generatesSources(outputFile);
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/PropertyNamesTest.java b/value/src/test/java/com/google/auto/value/processor/PropertyNamesTest.java
new file mode 100644
index 0000000..7af240c
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/PropertyNamesTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2018 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.truth.Expect;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class PropertyNamesTest {
+  @Rule public Expect expect = Expect.create();
+
+  private static final ImmutableMap<String, String> NORMAL_CASES =
+      ImmutableMap.<String, String>builder()
+          .put("Foo", "foo")
+          .put("foo", "foo")
+          .put("X", "x")
+          .put("x", "x")
+          .put("", "")
+          .build();
+  
+  @Test
+  public void decapitalizeLikeJavaBeans() {
+    NORMAL_CASES
+        .forEach(
+            (input, output) -> {
+              expect.that(PropertyNames.decapitalizeLikeJavaBeans(input)).isEqualTo(output);
+            });
+    expect.that(PropertyNames.decapitalizeLikeJavaBeans(null)).isNull();
+    expect.that(PropertyNames.decapitalizeLikeJavaBeans("HTMLPage")).isEqualTo("HTMLPage");
+    expect.that(PropertyNames.decapitalizeLikeJavaBeans("OAuth")).isEqualTo("OAuth");
+  }
+
+  @Test
+  public void decapitalizeNormally() {
+    NORMAL_CASES
+        .forEach(
+            (input, output) -> {
+              expect.that(PropertyNames.decapitalizeNormally(input)).isEqualTo(output);
+            });
+    expect.that(PropertyNames.decapitalizeNormally(null)).isNull();
+    expect.that(PropertyNames.decapitalizeNormally("HTMLPage")).isEqualTo("hTMLPage");
+    expect.that(PropertyNames.decapitalizeNormally("OAuth")).isEqualTo("oAuth");
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/ReformatterTest.java b/value/src/test/java/com/google/auto/value/processor/ReformatterTest.java
new file mode 100644
index 0000000..98d31b4
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/ReformatterTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Unit tests for {@link Reformatter}.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class ReformatterTest {
+  @Test
+  public void testSimple() {
+    String input =
+        "\n"
+            + "package com.latin.declension;  \n"
+            + "\n"
+            + "\n"
+            + "public  class  Idem  {  \n"
+            + "  \n"
+            + "  Eadem   idem  ;  \n"
+            + "\n"
+            + "  Eundem eandem ( Idem  eiusdem  )  {\n"
+            + "\n"
+            + "    eiusdem (   eiusdem  )  ;  \n"
+            + "\n"
+            + "    eidem_eidem_eidem( ) ;\n"
+            + "\n"
+            + "  }\n"
+            + "\n"
+            + "\n"
+            + "  Eodem ( Eadem eodem ) { }\n";
+    String output =
+            "package com.latin.declension;\n"
+            + "\n"
+            + "public class Idem {\n"
+            + "\n"
+            + "  Eadem idem;\n"
+            + "\n"
+            + "  Eundem eandem (Idem eiusdem) {\n"
+            + "    eiusdem (eiusdem);\n"
+            + "    eidem_eidem_eidem();\n"
+            + "  }\n"
+            + "\n"
+            + "  Eodem (Eadem eodem) { }\n";
+    assertEquals(output, Reformatter.fixup(input));
+  }
+
+  @Test
+  public void testSpecialSpaces() {
+    String input =
+        "\n"
+            + "package com.example.whatever;\n"
+            + "\n"
+            + "public class SomeClass {\n"
+            + "  static final String STRING = \"  hello  world  \\n\";  \n"
+            + "  static final String STRING_WITH_QUOTES = \" \\\"quote  me  now  \\\"  \"  ;\n"
+            + "  static final int INT = /* not a string \" */  23  ;\n"
+            + "  static final char QUOTE = '\"'  ;\n"
+            + "  static final char QUOTE2 = '\\\"'  ;\n"
+            + "}\n";
+    String output =
+            "package com.example.whatever;\n"
+            + "\n"
+            + "public class SomeClass {\n"
+            + "  static final String STRING = \"  hello  world  \\n\";\n"
+            + "  static final String STRING_WITH_QUOTES = \" \\\"quote  me  now  \\\"  \";\n"
+            + "  static final int INT = /* not a string \" */ 23;\n"
+            + "  static final char QUOTE = '\"';\n"
+            + "  static final char QUOTE2 = '\\\"';\n"
+            + "}\n";
+    assertEquals(output, Reformatter.fixup(input));
+  }
+
+  @Test
+  public void noTrailingNewline() {
+    String input = "package com.example.whatever;\n\npublic class SomeClass {}";
+    String output = input + "\n";
+    assertEquals(output, Reformatter.fixup(input));
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/SimpleServiceLoaderTest.java b/value/src/test/java/com/google/auto/value/processor/SimpleServiceLoaderTest.java
new file mode 100644
index 0000000..fab1805
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/SimpleServiceLoaderTest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+import static java.util.stream.Collectors.toList;
+import static org.junit.Assert.fail;
+
+import com.google.common.collect.ImmutableList;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.charset.StandardCharsets;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.ServiceConfigurationError;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public final class SimpleServiceLoaderTest {
+  @Test
+  public void loadOnce() throws Exception {
+    ClassLoader loader =
+        loaderForJarWithEntries(
+            CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName());
+
+    ImmutableList<CharSequence> providers = SimpleServiceLoader.load(CharSequence.class, loader);
+
+    // The provider entry for java.lang.String should have caused us to call new String(), which
+    // will produce this "" in the providers.
+    assertThat(providers).contains("");
+    List<Class<?>> classes = providers.stream().map(Object::getClass).collect(toList());
+    assertThat(classes).containsExactly(String.class, StringBuilder.class).inOrder();
+  }
+
+  @Test
+  public void blankLinesAndComments() throws Exception {
+    ClassLoader loader =
+        loaderForJarWithEntries(
+            CharSequence.class.getName(),
+            "",
+            "# this is a comment",
+            "   # this is also a comment",
+            "  java.lang.String  # this is a comment after a class name");
+
+    ImmutableList<CharSequence> providers = SimpleServiceLoader.load(CharSequence.class, loader);
+
+    assertThat(providers).containsExactly("");
+  }
+
+  @Test
+  public void loadTwiceFromSameLoader() throws Exception {
+    ClassLoader loader =
+        loaderForJarWithEntries(
+            CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName());
+
+    ImmutableList<CharSequence> providers1 = SimpleServiceLoader.load(CharSequence.class, loader);
+    ImmutableList<CharSequence> providers2 = SimpleServiceLoader.load(CharSequence.class, loader);
+
+    List<Class<?>> classes1 = providers1.stream().map(Object::getClass).collect(toList());
+    List<Class<?>> classes2 = providers2.stream().map(Object::getClass).collect(toList());
+    assertThat(classes2).containsExactlyElementsIn(classes1).inOrder();
+  }
+
+  @Test
+  public void loadTwiceFromDifferentLoaders() throws Exception {
+    URL jarUrl =
+        urlForJarWithEntries(
+            CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName());
+    ClassLoader loader1 = new URLClassLoader(new URL[] {jarUrl});
+
+    ImmutableList<CharSequence> providers1 = SimpleServiceLoader.load(CharSequence.class, loader1);
+    // We should have called `new String()`, so the result should contain "".
+    assertThat(providers1).contains("");
+
+    ClassLoader loader2 = new URLClassLoader(new URL[] {jarUrl});
+    ImmutableList<CharSequence> providers2 = SimpleServiceLoader.load(CharSequence.class, loader2);
+
+    List<Class<?>> classes1 = providers1.stream().map(Object::getClass).collect(toList());
+    List<Class<?>> classes2 = providers2.stream().map(Object::getClass).collect(toList());
+    assertThat(classes2).containsExactlyElementsIn(classes1).inOrder();
+  }
+
+  @Test
+  public void noProviders() throws Exception {
+    ClassLoader loader = loaderForJarWithEntries(CharSequence.class.getName());
+
+    ImmutableList<CharSequence> providers = SimpleServiceLoader.load(CharSequence.class, loader);
+
+    assertThat(providers).isEmpty();
+  }
+
+  @Test
+  public void classNotFound() throws Exception {
+    ClassLoader loader =
+        loaderForJarWithEntries(CharSequence.class.getName(), "this.is.not.a.Class");
+
+    try {
+      SimpleServiceLoader.load(CharSequence.class, loader);
+      fail();
+    } catch (ServiceConfigurationError expected) {
+      assertThat(expected).hasMessageThat().startsWith("Could not load ");
+    }
+  }
+
+  @Test
+  public void wrongTypeClass() throws Exception {
+    ClassLoader loader = loaderForJarWithEntries(CharSequence.class.getName(), "java.lang.Thread");
+
+    try {
+      SimpleServiceLoader.load(CharSequence.class, loader);
+      fail();
+    } catch (ServiceConfigurationError expected) {
+      assertThat(expected).hasMessageThat().startsWith("Class java.lang.Thread is not assignable");
+    }
+  }
+
+  @Test
+  public void couldNotConstruct() throws Exception {
+    ClassLoader loader = loaderForJarWithEntries("java.lang.System", "java.lang.System");
+
+    try {
+      SimpleServiceLoader.load(System.class, loader);
+      fail();
+    } catch (ServiceConfigurationError expected) {
+      assertThat(expected).hasMessageThat().startsWith("Could not construct");
+    }
+  }
+
+  @Test
+  public void brokenLoader() {
+    ClassLoader loader =
+        new URLClassLoader(new URL[0]) {
+          @Override
+          public Enumeration<URL> getResources(String name) throws IOException {
+            throw new IOException("bang");
+          }
+        };
+
+    try {
+      SimpleServiceLoader.load(CharSequence.class, loader);
+      fail();
+    } catch (ServiceConfigurationError expected) {
+      assertThat(expected).hasMessageThat().startsWith("Could not look up");
+      assertThat(expected).hasCauseThat().hasMessageThat().isEqualTo("bang");
+    }
+  }
+
+  private static ClassLoader loaderForJarWithEntries(String service, String... lines)
+      throws IOException {
+    URL jarUrl = urlForJarWithEntries(service, lines);
+    return new URLClassLoader(new URL[] {jarUrl});
+  }
+
+  private static URL urlForJarWithEntries(String service, String... lines) throws IOException {
+    File jar = File.createTempFile("SimpleServiceLoaderTest", "jar");
+    jar.deleteOnExit();
+    try (JarOutputStream out = new JarOutputStream(new FileOutputStream(jar))) {
+      JarEntry jarEntry = new JarEntry("META-INF/services/" + service);
+      out.putNextEntry(jarEntry);
+      // It would be bad practice to use try-with-resources below, because closing the PrintWriter
+      // would close the JarOutputStream.
+      PrintWriter writer = new PrintWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
+      for (String line : lines) {
+        writer.println(line);
+      }
+      writer.flush();
+    }
+    return jar.toURI().toURL();
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/SimplifyWithAnnotationsTest.java b/value/src/test/java/com/google/auto/value/processor/SimplifyWithAnnotationsTest.java
new file mode 100644
index 0000000..39e2dc0
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/SimplifyWithAnnotationsTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.collect.MoreCollectors.onlyElement;
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+import static javax.lang.model.util.ElementFilter.fieldsIn;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.truth.Expect;
+import com.google.testing.compile.JavaFileObjects;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.tools.JavaFileObject;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * This test verifies the method {@link TypeEncoder#encodeWithAnnotations(TypeMirror).
+ * It takes a list of "type spellings", like {@code @Nullable String}, and compiles a class
+ * with one field for each spelling. So there might be a field {@code @Nullable String x2;}.
+ * Then it examines each compiled field to extract its {@code TypeMirror}, and uses the
+ * {@code TypeSimplifier} method to reconvert that into a string. It should get back the same
+ * type spelling in each case.
+ *
+ * <p>I originally tried to write a less convoluted test using compile-testing. In my test,
+ * each type to be tested was an actual type in the test class (the type of a field, or the
+ * return type of a method). However, I found that if I examined these types by looking up a class
+ * with {@link javax.lang.model.util.Elements#getTypeElement} and following through to the type
+ * of interest, it never had any type annotations.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class SimplifyWithAnnotationsTest {
+  @Rule public final Expect expect = Expect.create();
+
+  /**
+   * The types that we will compile and then recreate. They are referenced in a context where {@code
+   * Set} is unambiguous but not {@code List}, which allows us to test the placement of annotations
+   * in unqualified types like {@code Set<T>} and qualified types like {@code java.util.List<T>}.
+   */
+  private static final ImmutableList<String> TYPE_SPELLINGS =
+      ImmutableList.of(
+          "Object",
+          "Set",
+          "String",
+          "Nullable",
+          "@Nullable String",
+          "String[]",
+          "@Nullable String[]",
+          "String @Nullable []",
+          "String @Nullable [] @Nullable []",
+          "java.awt.List",
+          "java.util.List<String>",
+          "Set<@Nullable String>",
+          "@Nullable Set<String>",
+          "int",
+          "@Nullable int", // whatever that might mean
+          "@Nullable int[]",
+          "int @Nullable []",
+          "T",
+          "@Nullable T",
+          "Set<@Nullable T>",
+          "Set<? extends @Nullable T>",
+          "Set<? extends @Nullable String>",
+          "Set<? extends @Nullable String @Nullable []>",
+          "java.util.@Nullable List<@Nullable T>",
+          "java.util.@Nullable List<java.util.@Nullable List<T>>");
+
+  private static final JavaFileObject NULLABLE_FILE_OBJECT =
+      JavaFileObjects.forSourceLines(
+          "pkg.Nullable",
+          "package pkg;",
+          "",
+          "import java.lang.annotation.ElementType;",
+          "import java.lang.annotation.Target;",
+          "",
+          "@Target(ElementType.TYPE_USE)",
+          "public @interface Nullable {}");
+
+  private static final JavaFileObject TEST_CLASS_FILE_OBJECT =
+      JavaFileObjects.forSourceLines("pkg.TestClass", buildTestClass());
+
+  private static ImmutableList<String> buildTestClass() {
+    // Some older versions of javac don't handle type annotations at all well in annotation
+    // processors. The `witness` method in the generated class is there to detect that, and
+    // skip the test if it is the case.
+    ImmutableList.Builder<String> builder = ImmutableList.builder();
+    builder.add(
+        "package pkg;",
+        "",
+        "import java.util.Set;",
+        "",
+        "public abstract class TestClass<T> {",
+        "  abstract @Nullable T witness();");
+    int i = 0;
+    for (String typeSpelling : TYPE_SPELLINGS) {
+      builder.add(String.format("  %s x%d;\n", typeSpelling, i++));
+    }
+    builder.add("}");
+    return builder.build();
+  }
+
+  @Test
+  public void testSimplifyWithAnnotations() {
+    // The real test happens inside the .compile(...), by virtue of TestProcessor.
+    assertThat(
+            javac()
+                .withOptions("-proc:only")
+                .withProcessors(new TestProcessor())
+                .compile(NULLABLE_FILE_OBJECT, TEST_CLASS_FILE_OBJECT))
+        .succeededWithoutWarnings();
+  }
+
+  @SupportedAnnotationTypes("*")
+  private static class TestProcessor extends AbstractProcessor {
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latest();
+    }
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      if (roundEnv.processingOver()) {
+        TypeElement testClass = processingEnv.getElementUtils().getTypeElement("pkg.TestClass");
+        testTypeSpellings(testClass);
+      }
+      return false;
+    }
+
+    void testTypeSpellings(TypeElement testClass) {
+      ExecutableElement witness =
+          ElementFilter.methodsIn(testClass.getEnclosedElements())
+              .stream()
+              .filter(m -> m.getSimpleName().contentEquals("witness"))
+              .collect(onlyElement());
+      if (witness.getReturnType().getAnnotationMirrors().isEmpty()) {
+        System.err.println("SKIPPING TEST BECAUSE OF BUGGY COMPILER");
+        return;
+      }
+      ImmutableMap<String, TypeMirror> typeSpellingToType = typesFromTestClass(testClass);
+      assertThat(typeSpellingToType).isNotEmpty();
+      StringBuilder text = new StringBuilder();
+      StringBuilder expected = new StringBuilder();
+      // Build up a fake source text with the encodings for the types in it, and decode it to
+      // ensure the type spellings are what we expect.
+      typeSpellingToType.forEach(
+          (typeSpelling, type) -> {
+            text.append("{").append(TypeEncoder.encodeWithAnnotations(type)).append("}");
+            expected.append("{").append(typeSpelling).append("}");
+          });
+      String decoded = TypeEncoder.decode(text.toString(), processingEnv, "pkg", null);
+      assertThat(decoded).isEqualTo(expected.toString());
+    }
+
+    private static ImmutableMap<String, TypeMirror> typesFromTestClass(TypeElement type) {
+      // Reads the types of the fields from the compiled TestClass and uses them to produce
+      // a map from type spellings to types. This method depends on type.getEnclosedElements()
+      // returning the fields in source order, which it is specified to do.
+      ImmutableMap.Builder<String, TypeMirror> typeSpellingToTypeBuilder = ImmutableMap.builder();
+      int i = 0;
+      for (VariableElement field : fieldsIn(type.getEnclosedElements())) {
+        String spelling = TYPE_SPELLINGS.get(i);
+        typeSpellingToTypeBuilder.put(spelling, field.asType());
+        i++;
+      }
+      return typeSpellingToTypeBuilder.build();
+    }
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/TemplateVarsTest.java b/value/src/test/java/com/google/auto/value/processor/TemplateVarsTest.java
new file mode 100644
index 0000000..bca7bca
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/TemplateVarsTest.java
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2014 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_PATH;
+import static com.google.common.base.StandardSystemProperty.PATH_SEPARATOR;
+import static com.google.common.truth.Truth.assertThat;
+import static java.util.logging.Level.WARNING;
+import static org.junit.Assert.fail;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.reflect.Reflection;
+import com.google.escapevelocity.Template;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.Callable;
+import java.util.logging.Logger;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for FieldReader.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class TemplateVarsTest {
+  static class HappyVars extends TemplateVars {
+    Integer integer;
+    String string;
+    List<Integer> list;
+    private static final String IGNORED_STATIC_FINAL = "hatstand";
+
+    @Override
+    Template parsedTemplate() {
+      return parsedTemplateForString("integer=$integer string=$string list=$list");
+    }
+  }
+
+  static Template parsedTemplateForString(String string) {
+    try {
+      Reader reader = new StringReader(string);
+      return Template.parseFrom(reader);
+    } catch (IOException e) {
+      throw new AssertionError(e);
+    }
+  }
+
+  @Test
+  public void testHappy() {
+    HappyVars happy = new HappyVars();
+    happy.integer = 23;
+    happy.string = "wibble";
+    happy.list = ImmutableList.of(5, 17, 23);
+    assertThat(HappyVars.IGNORED_STATIC_FINAL).isEqualTo("hatstand"); // avoids unused warning
+    String expectedText = "integer=23 string=wibble list=[5, 17, 23]";
+    String actualText = happy.toText();
+    assertThat(actualText).isEqualTo(expectedText);
+  }
+
+  @Test
+  public void testUnset() {
+    HappyVars sad = new HappyVars();
+    sad.integer = 23;
+    sad.list = ImmutableList.of(23);
+    try {
+      sad.toText();
+      fail("Did not get expected exception");
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  static class SubHappyVars extends HappyVars {
+    Character character;
+
+    @Override
+    Template parsedTemplate() {
+      return parsedTemplateForString(
+          "integer=$integer string=$string list=$list character=$character");
+    }
+  }
+
+  @Test
+  public void testSubSub() {
+    SubHappyVars vars = new SubHappyVars();
+    vars.integer = 23;
+    vars.string = "wibble";
+    vars.list = ImmutableList.of(5, 17, 23);
+    vars.character = 'ß';
+    String expectedText = "integer=23 string=wibble list=[5, 17, 23] character=ß";
+    String actualText = vars.toText();
+    assertThat(actualText).isEqualTo(expectedText);
+  }
+
+  static class Private extends TemplateVars {
+    Integer integer;
+    private String unusedString;
+
+    @Override
+    Template parsedTemplate() {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  @Test
+  public void testPrivate() {
+    try {
+      new Private();
+      fail("Did not get expected exception");
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  static class Static extends TemplateVars {
+    Integer integer;
+    static String string;
+
+    @Override
+    Template parsedTemplate() {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  @Test
+  public void testStatic() {
+    try {
+      new Static();
+      fail("Did not get expected exception");
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  static class Primitive extends TemplateVars {
+    int integer;
+    String string;
+
+    @Override
+    Template parsedTemplate() {
+      throw new UnsupportedOperationException();
+    }
+  }
+
+  @Test
+  public void testPrimitive() {
+    try {
+      new Primitive();
+      fail("Did not get expected exception");
+    } catch (IllegalArgumentException expected) {
+    }
+  }
+
+  @Test
+  public void testBrokenInputStream_IOException() throws Exception {
+    doTestBrokenInputStream(new IOException("BrokenInputStream"));
+  }
+
+  @Test
+  public void testBrokenInputStream_NullPointerException() throws Exception {
+    doTestBrokenInputStream(new NullPointerException("BrokenInputStream"));
+  }
+
+  @Test
+  public void testBrokenInputStream_IllegalStateException() throws Exception {
+    doTestBrokenInputStream(new IllegalStateException("BrokenInputStream"));
+  }
+
+  // This is a complicated test that tries to simulates the failures that are worked around in
+  // Template.parsedTemplateForResource. Those failures means that the InputStream returned by
+  // ClassLoader.getResourceAsStream sometimes throws IOException or NullPointerException or
+  // IllegalStateException while it is being read. To simulate that, we make a second ClassLoader
+  // with the same configuration as the one that runs this test, and we override getResourceAsStream
+  // so that it wraps the returned InputStream in a BrokenInputStream, which throws an exception
+  // after a certain number of characters. We check that that exception was indeed seen, and that
+  // we did indeed try to read the resource we're interested in, and that we succeeded in loading a
+  // Template nevertheless.
+  private void doTestBrokenInputStream(Exception exception) throws Exception {
+    URLClassLoader shadowLoader = new ShadowLoader(getClass().getClassLoader(), exception);
+    Runnable brokenInputStreamTest =
+        (Runnable)
+            shadowLoader
+                .loadClass(BrokenInputStreamTest.class.getName())
+                .getConstructor()
+                .newInstance();
+    brokenInputStreamTest.run();
+  }
+
+  private static class ShadowLoader extends URLClassLoader implements Callable<Set<String>> {
+
+    private static final Logger logger = Logger.getLogger(ShadowLoader.class.getName());
+
+    private final Exception exception;
+    private final Set<String> result = new TreeSet<String>();
+
+    ShadowLoader(ClassLoader original, Exception exception) {
+      super(getClassPathUrls(original), original.getParent());
+      this.exception = exception;
+    }
+
+    private static URL[] getClassPathUrls(ClassLoader original) {
+      return original instanceof URLClassLoader
+          ? ((URLClassLoader) original).getURLs()
+          : parseJavaClassPath();
+    }
+
+    /**
+     * Returns the URLs in the class path specified by the {@code java.class.path} {@linkplain
+     * System#getProperty system property}.
+     */
+    // TODO(b/65488446): Use a new public API.
+    private static URL[] parseJavaClassPath() {
+      ImmutableList.Builder<URL> urls = ImmutableList.builder();
+      for (String entry : Splitter.on(PATH_SEPARATOR.value()).split(JAVA_CLASS_PATH.value())) {
+        try {
+          try {
+            urls.add(new File(entry).toURI().toURL());
+          } catch (SecurityException e) { // File.toURI checks to see if the file is a directory
+            urls.add(new URL("file", null, new File(entry).getAbsolutePath()));
+          }
+        } catch (MalformedURLException e) {
+          logger.log(WARNING, "malformed classpath entry: " + entry, e);
+        }
+      }
+      return urls.build().toArray(new URL[0]);
+    }
+
+    @Override
+    public Set<String> call() throws Exception {
+      return result;
+    }
+
+    @Override
+    public InputStream getResourceAsStream(String resource) {
+      // Make sure this is actually the resource we are expecting. If we're using JaCoCo or the
+      // like, we might end up reading some other resource, and we don't want to break that.
+      if (resource.startsWith("com/google/auto")) {
+        result.add(resource);
+        return new BrokenInputStream(super.getResourceAsStream(resource));
+      } else {
+        return super.getResourceAsStream(resource);
+      }
+    }
+
+    private class BrokenInputStream extends InputStream {
+      private final InputStream original;
+      private int count = 0;
+
+      BrokenInputStream(InputStream original) {
+        this.original = original;
+      }
+
+      @Override
+      public int read() throws IOException {
+        if (++count > 10) {
+          result.add("threw");
+          if (exception instanceof IOException) {
+            throw (IOException) exception;
+          }
+          throw (RuntimeException) exception;
+        }
+        return original.read();
+      }
+    }
+  }
+
+  public static class BrokenInputStreamTest implements Runnable {
+    @Override
+    public void run() {
+      Template template = TemplateVars.parsedTemplateForResource("autovalue.vm");
+      assertThat(template).isNotNull();
+      String resourceName =
+          Reflection.getPackageName(getClass()).replace('.', '/') + "/autovalue.vm";
+      @SuppressWarnings("unchecked")
+      Callable<Set<String>> myLoader = (Callable<Set<String>>) getClass().getClassLoader();
+      try {
+        Set<String> result = myLoader.call();
+        assertThat(result).contains(resourceName);
+        assertThat(result).contains("threw");
+      } catch (Exception e) {
+        throw new AssertionError(e);
+      }
+    }
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/TypeEncoderTest.java b/value/src/test/java/com/google/auto/value/processor/TypeEncoderTest.java
new file mode 100644
index 0000000..c31f711
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/TypeEncoderTest.java
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2017 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.testing.compile.CompilationSubject.assertThat;
+import static com.google.testing.compile.Compiler.javac;
+import static java.util.stream.Collectors.joining;
+
+import com.google.auto.common.MoreTypes;
+import com.google.auto.value.processor.MissingTypes.MissingTypeException;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.testing.compile.Compilation;
+import com.google.testing.compile.CompilationRule;
+import com.google.testing.compile.JavaFileObjects;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.ErrorType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for {@link TypeEncoder}.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class TypeEncoderTest {
+  @Rule public final CompilationRule compilationRule = new CompilationRule();
+
+  private Types typeUtils;
+  private Elements elementUtils;
+
+  @Before
+  public void setUp() {
+    typeUtils = compilationRule.getTypes();
+    elementUtils = compilationRule.getElements();
+  }
+
+  /**
+   * Assert that the fake program returned by fakeProgramForTypes has the given list of imports and
+   * the given list of spellings. Here, "spellings" means the way each type is referenced in the
+   * decoded program, for example {@code Timer} if {@code java.util.Timer} can be imported, or
+   * {@code java.util.Timer} if not.
+   *
+   * <p>We construct a fake program that references each of the given types in turn.
+   * TypeEncoder.decode doesn't have any real notion of Java syntax, so our program just consists of
+   * START and END markers around the {@code `import`} tag, followed by each type in braces, as
+   * encoded by TypeEncoder.encode. Once decoded, the program should consist of the appropriate
+   * imports (inside START...END) and each type in braces, spelled appropriately.
+   *
+   * @param fakePackage the package that TypeEncoder should consider the fake program to be in.
+   *     Classes in the same package don't usually need to be imported.
+   */
+  private void assertTypeImportsAndSpellings(
+      Set<TypeMirror> types, String fakePackage, List<String> imports, List<String> spellings) {
+    String fakeProgram =
+        "START\n`import`\nEND\n"
+            + types.stream().map(TypeEncoder::encode).collect(joining("}\n{", "{", "}"));
+    String decoded =
+        TypeEncoder.decode(
+            fakeProgram, elementUtils, typeUtils, fakePackage, baseWithoutContainedTypes());
+    String expected =
+        "START\n"
+            + imports.stream().map(s -> "import " + s + ";\n").collect(joining())
+            + "\nEND\n"
+            + spellings.stream().collect(joining("}\n{", "{", "}"));
+    assertThat(decoded).isEqualTo(expected);
+  }
+
+  private static class MultipleBounds<K extends List<V> & Comparable<K>, V> {}
+
+  @Test
+  public void testImportsForNoTypes() {
+    assertTypeImportsAndSpellings(
+        typeMirrorSet(), "foo.bar", ImmutableList.of(), ImmutableList.of());
+  }
+
+  @Test
+  public void testImportsForImplicitlyImportedTypes() {
+    Set<TypeMirror> types =
+        typeMirrorSet(
+            typeMirrorOf(java.lang.String.class),
+            typeMirrorOf(javax.management.MBeanServer.class), // Same package, so no import.
+            typeUtils.getPrimitiveType(TypeKind.INT),
+            typeUtils.getPrimitiveType(TypeKind.BOOLEAN));
+    assertTypeImportsAndSpellings(
+        types,
+        "javax.management",
+        ImmutableList.of(),
+        ImmutableList.of("String", "MBeanServer", "int", "boolean"));
+  }
+
+  @Test
+  public void testImportsForPlainTypes() {
+    Set<TypeMirror> types =
+        typeMirrorSet(
+            typeUtils.getPrimitiveType(TypeKind.INT),
+            typeMirrorOf(java.lang.String.class),
+            typeMirrorOf(java.net.Proxy.class),
+            typeMirrorOf(java.net.Proxy.Type.class),
+            typeMirrorOf(java.util.regex.Pattern.class),
+            typeMirrorOf(javax.management.MBeanServer.class));
+    assertTypeImportsAndSpellings(
+        types,
+        "foo.bar",
+        ImmutableList.of(
+            "java.net.Proxy", "java.util.regex.Pattern", "javax.management.MBeanServer"),
+        ImmutableList.of("int", "String", "Proxy", "Proxy.Type", "Pattern", "MBeanServer"));
+  }
+
+  @Test
+  public void testImportsForComplicatedTypes() {
+    TypeElement list = typeElementOf(java.util.List.class);
+    TypeElement map = typeElementOf(java.util.Map.class);
+    Set<TypeMirror> types =
+        typeMirrorSet(
+            typeUtils.getPrimitiveType(TypeKind.INT),
+            typeMirrorOf(java.util.regex.Pattern.class),
+            typeUtils.getDeclaredType(
+                list, // List<Timer>
+                typeMirrorOf(java.util.Timer.class)),
+            typeUtils.getDeclaredType(
+                map, // Map<? extends Timer, ? super BigInteger>
+                typeUtils.getWildcardType(typeMirrorOf(java.util.Timer.class), null),
+                typeUtils.getWildcardType(null, typeMirrorOf(java.math.BigInteger.class))));
+    // Timer is referenced twice but should obviously only be imported once.
+    assertTypeImportsAndSpellings(
+        types,
+        "foo.bar",
+        ImmutableList.of(
+            "java.math.BigInteger",
+            "java.util.List",
+            "java.util.Map",
+            "java.util.Timer",
+            "java.util.regex.Pattern"),
+        ImmutableList.of(
+            "int", "Pattern", "List<Timer>", "Map<? extends Timer, ? super BigInteger>"));
+  }
+
+  @Test
+  public void testImportsForArrayTypes() {
+    TypeElement list = typeElementOf(java.util.List.class);
+    TypeElement set = typeElementOf(java.util.Set.class);
+    Set<TypeMirror> types =
+        typeMirrorSet(
+            typeUtils.getArrayType(typeUtils.getPrimitiveType(TypeKind.INT)),
+            typeUtils.getArrayType(typeMirrorOf(java.util.regex.Pattern.class)),
+            typeUtils.getArrayType( // Set<Matcher[]>[]
+                typeUtils.getDeclaredType(
+                    set, typeUtils.getArrayType(typeMirrorOf(java.util.regex.Matcher.class)))),
+            typeUtils.getDeclaredType(
+                list, // List<Timer[]>
+                typeUtils.getArrayType(typeMirrorOf(java.util.Timer.class))));
+    // Timer is referenced twice but should obviously only be imported once.
+    assertTypeImportsAndSpellings(
+        types,
+        "foo.bar",
+        ImmutableList.of(
+            "java.util.List",
+            "java.util.Set",
+            "java.util.Timer",
+            "java.util.regex.Matcher",
+            "java.util.regex.Pattern"),
+        ImmutableList.of("int[]", "Pattern[]", "Set<Matcher[]>[]", "List<Timer[]>"));
+  }
+
+  @Test
+  public void testImportNestedType() {
+    Set<TypeMirror> types = typeMirrorSet(typeMirrorOf(java.net.Proxy.Type.class));
+    assertTypeImportsAndSpellings(
+        types, "foo.bar", ImmutableList.of("java.net.Proxy"), ImmutableList.of("Proxy.Type"));
+  }
+
+  @Test
+  public void testImportsForAmbiguousNames() {
+    TypeMirror wildcard = typeUtils.getWildcardType(null, null);
+    Set<TypeMirror> types =
+        typeMirrorSet(
+            typeUtils.getPrimitiveType(TypeKind.INT),
+            typeMirrorOf(java.awt.List.class),
+            typeMirrorOf(java.lang.String.class),
+            typeUtils.getDeclaredType( // List<?>
+                typeElementOf(java.util.List.class), wildcard),
+            typeUtils.getDeclaredType( // Map<?, ?>
+                typeElementOf(java.util.Map.class), wildcard, wildcard));
+    assertTypeImportsAndSpellings(
+        types,
+        "foo.bar",
+        ImmutableList.of("java.util.Map"),
+        ImmutableList.of("int", "java.awt.List", "String", "java.util.List<?>", "Map<?, ?>"));
+  }
+
+  @Test
+  public void testSimplifyJavaLangString() {
+    Set<TypeMirror> types = typeMirrorSet(typeMirrorOf(java.lang.String.class));
+    assertTypeImportsAndSpellings(types, "foo.bar", ImmutableList.of(), ImmutableList.of("String"));
+  }
+
+  @Test
+  public void testSimplifyJavaLangThreadState() {
+    Set<TypeMirror> types = typeMirrorSet(typeMirrorOf(java.lang.Thread.State.class));
+    assertTypeImportsAndSpellings(
+        types, "foo.bar", ImmutableList.of(), ImmutableList.of("Thread.State"));
+  }
+
+  @Test
+  public void testSimplifyJavaLangNamesake() {
+    TypeMirror javaLangType = typeMirrorOf(java.lang.RuntimePermission.class);
+    TypeMirror notJavaLangType =
+        typeMirrorOf(com.google.auto.value.processor.testclasses.RuntimePermission.class);
+    Set<TypeMirror> types = typeMirrorSet(javaLangType, notJavaLangType);
+    assertTypeImportsAndSpellings(
+        types,
+        "foo.bar",
+        ImmutableList.of(),
+        ImmutableList.of(javaLangType.toString(), notJavaLangType.toString()));
+  }
+
+  @Test
+  public void testSimplifyComplicatedTypes() {
+    // This test constructs a set of types and feeds them to TypeEncoder. Then it verifies that
+    // the resultant rewrites of those types are what we would expect.
+    TypeElement list = typeElementOf(java.util.List.class);
+    TypeElement map = typeElementOf(java.util.Map.class);
+    TypeMirror string = typeMirrorOf(java.lang.String.class);
+    TypeMirror integer = typeMirrorOf(java.lang.Integer.class);
+    TypeMirror pattern = typeMirrorOf(java.util.regex.Pattern.class);
+    TypeMirror timer = typeMirrorOf(java.util.Timer.class);
+    TypeMirror bigInteger = typeMirrorOf(java.math.BigInteger.class);
+    ImmutableMap<TypeMirror, String> typeMap =
+        ImmutableMap.<TypeMirror, String>builder()
+            .put(typeUtils.getPrimitiveType(TypeKind.INT), "int")
+            .put(typeUtils.getArrayType(typeUtils.getPrimitiveType(TypeKind.BYTE)), "byte[]")
+            .put(pattern, "Pattern")
+            .put(typeUtils.getArrayType(pattern), "Pattern[]")
+            .put(typeUtils.getArrayType(typeUtils.getArrayType(pattern)), "Pattern[][]")
+            .put(typeUtils.getDeclaredType(list, typeUtils.getWildcardType(null, null)), "List<?>")
+            .put(typeUtils.getDeclaredType(list, timer), "List<Timer>")
+            .put(typeUtils.getDeclaredType(map, string, integer), "Map<String, Integer>")
+            .put(
+                typeUtils.getDeclaredType(
+                    map,
+                    typeUtils.getWildcardType(timer, null),
+                    typeUtils.getWildcardType(null, bigInteger)),
+                "Map<? extends Timer, ? super BigInteger>")
+            .build();
+    assertTypeImportsAndSpellings(
+        typeMap.keySet(),
+        "foo.bar",
+        ImmutableList.of(
+            "java.math.BigInteger",
+            "java.util.List",
+            "java.util.Map",
+            "java.util.Timer",
+            "java.util.regex.Pattern"),
+        ImmutableList.copyOf(typeMap.values()));
+  }
+
+  @Test
+  public void testSimplifyMultipleBounds() {
+    TypeElement multipleBoundsElement = typeElementOf(MultipleBounds.class);
+    TypeMirror multipleBoundsMirror = multipleBoundsElement.asType();
+    String text = "`import`\n";
+    text += "{" + TypeEncoder.encode(multipleBoundsMirror) + "}";
+    text += "{" + TypeEncoder.formalTypeParametersString(multipleBoundsElement) + "}";
+    String myPackage = getClass().getPackage().getName();
+    String decoded =
+        TypeEncoder.decode(text, elementUtils, typeUtils, myPackage, baseWithoutContainedTypes());
+    String expected =
+        "import java.util.List;\n\n"
+            + "{TypeEncoderTest.MultipleBounds<K, V>}"
+            + "{<K extends List<V> & Comparable<K>, V>}";
+    assertThat(decoded).isEqualTo(expected);
+  }
+
+  @SuppressWarnings("ClassCanBeStatic")
+  static class Outer<T extends Number> {
+    class InnerWithoutTypeParam {}
+    class Middle<U> {
+      class InnerWithTypeParam<V> {}
+    }
+  }
+
+  @Test
+  public void testOuterParameterizedInnerNot() {
+    TypeElement outerElement = typeElementOf(Outer.class);
+    DeclaredType doubleMirror = typeMirrorOf(Double.class);
+    DeclaredType outerOfDoubleMirror = typeUtils.getDeclaredType(outerElement, doubleMirror);
+    TypeElement innerWithoutTypeParamElement = typeElementOf(Outer.InnerWithoutTypeParam.class);
+    DeclaredType parameterizedInnerWithoutTypeParam =
+        typeUtils.getDeclaredType(outerOfDoubleMirror, innerWithoutTypeParamElement);
+    String encoded = TypeEncoder.encode(parameterizedInnerWithoutTypeParam);
+    String myPackage = getClass().getPackage().getName();
+    String decoded =
+        TypeEncoder.decode(
+            encoded, elementUtils, typeUtils, myPackage, baseWithoutContainedTypes());
+    String expected = "TypeEncoderTest.Outer<Double>.InnerWithoutTypeParam";
+    assertThat(decoded).isEqualTo(expected);
+  }
+
+  @Test
+  public void testOuterParameterizedInnerAlso() {
+    TypeElement outerElement = typeElementOf(Outer.class);
+    DeclaredType doubleMirror = typeMirrorOf(Double.class);
+    DeclaredType outerOfDoubleMirror = typeUtils.getDeclaredType(outerElement, doubleMirror);
+    TypeElement middleElement = typeElementOf(Outer.Middle.class);
+    DeclaredType stringMirror = typeMirrorOf(String.class);
+    DeclaredType middleOfStringMirror =
+        typeUtils.getDeclaredType(outerOfDoubleMirror, middleElement, stringMirror);
+    TypeElement innerWithTypeParamElement = typeElementOf(Outer.Middle.InnerWithTypeParam.class);
+    DeclaredType integerMirror = typeMirrorOf(Integer.class);
+    DeclaredType parameterizedInnerWithTypeParam =
+        typeUtils.getDeclaredType(middleOfStringMirror, innerWithTypeParamElement, integerMirror);
+    String encoded = TypeEncoder.encode(parameterizedInnerWithTypeParam);
+    String myPackage = getClass().getPackage().getName();
+    String decoded =
+        TypeEncoder.decode(
+            encoded, elementUtils, typeUtils, myPackage, baseWithoutContainedTypes());
+    String expected = "TypeEncoderTest.Outer<Double>.Middle<String>.InnerWithTypeParam<Integer>";
+    assertThat(decoded).isEqualTo(expected);
+  }
+
+  private static Set<TypeMirror> typeMirrorSet(TypeMirror... typeMirrors) {
+    Set<TypeMirror> set = new TypeMirrorSet();
+    for (TypeMirror typeMirror : typeMirrors) {
+      assertThat(set.add(typeMirror)).isTrue();
+    }
+    return set;
+  }
+
+  private TypeElement typeElementOf(Class<?> c) {
+    return elementUtils.getTypeElement(c.getCanonicalName());
+  }
+
+  private DeclaredType typeMirrorOf(Class<?> c) {
+    return MoreTypes.asDeclared(typeElementOf(c).asType());
+  }
+
+  /**
+   * Returns a "base type" for TypeSimplifier that does not contain any nested types. The point
+   * being that every {@code TypeSimplifier} has a base type that the class being generated is going
+   * to extend, and if that class has nested types they will be in scope, and therefore a possible
+   * source of ambiguity.
+   */
+  private TypeMirror baseWithoutContainedTypes() {
+    return typeMirrorOf(Object.class);
+  }
+
+  // This test checks that we correctly throw MissingTypeException if there is an ErrorType anywhere
+  // inside a type we are asked to simplify. There's no way to get an ErrorType from typeUtils or
+  // elementUtils, so we need to fire up the compiler with an erroneous source file and use an
+  // annotation processor to capture the resulting ErrorType. Then we can run tests within that
+  // annotation processor, and propagate any failures out of this test.
+  @Test
+  public void testErrorTypes() {
+    JavaFileObject source =
+        JavaFileObjects.forSourceString(
+            "ExtendsUndefinedType", "class ExtendsUndefinedType extends UndefinedParent {}");
+    Compilation compilation = javac().withProcessors(new ErrorTestProcessor()).compile(source);
+    assertThat(compilation).failed();
+    assertThat(compilation).hadErrorContaining("UndefinedParent");
+    assertThat(compilation).hadErrorCount(1);
+  }
+
+  @SupportedAnnotationTypes("*")
+  private static class ErrorTestProcessor extends AbstractProcessor {
+    Types typeUtils;
+    Elements elementUtils;
+
+    @Override
+    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+      if (roundEnv.processingOver()) {
+        typeUtils = processingEnv.getTypeUtils();
+        elementUtils = processingEnv.getElementUtils();
+        test();
+      }
+      return false;
+    }
+
+    private void test() {
+      TypeElement extendsUndefinedType = elementUtils.getTypeElement("ExtendsUndefinedType");
+      ErrorType errorType = (ErrorType) extendsUndefinedType.getSuperclass();
+      TypeElement list = elementUtils.getTypeElement("java.util.List");
+      TypeMirror listOfError = typeUtils.getDeclaredType(list, errorType);
+      TypeMirror queryExtendsError = typeUtils.getWildcardType(errorType, null);
+      TypeMirror listOfQueryExtendsError = typeUtils.getDeclaredType(list, queryExtendsError);
+      TypeMirror querySuperError = typeUtils.getWildcardType(null, errorType);
+      TypeMirror listOfQuerySuperError = typeUtils.getDeclaredType(list, querySuperError);
+      TypeMirror arrayOfError = typeUtils.getArrayType(errorType);
+      testErrorType(errorType);
+      testErrorType(listOfError);
+      testErrorType(listOfQueryExtendsError);
+      testErrorType(listOfQuerySuperError);
+      testErrorType(arrayOfError);
+    }
+
+    @SuppressWarnings("MissingFail") // error message gets converted into assertion failure
+    private void testErrorType(TypeMirror typeWithError) {
+      try {
+        TypeEncoder.encode(typeWithError);
+        processingEnv
+            .getMessager()
+            .printMessage(Diagnostic.Kind.ERROR, "Expected exception for type: " + typeWithError);
+      } catch (MissingTypeException expected) {
+      }
+    }
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+      return SourceVersion.latestSupported();
+    }
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/TypeSimplifierTest.java b/value/src/test/java/com/google/auto/value/processor/TypeSimplifierTest.java
new file mode 100644
index 0000000..73c7159
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/TypeSimplifierTest.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright 2012 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import com.google.testing.compile.CompilationRule;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.TypeParameterElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.type.TypeVariable;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for {@link TypeSimplifier}.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+@RunWith(JUnit4.class)
+public class TypeSimplifierTest {
+  @Rule public final CompilationRule compilationRule = new CompilationRule();
+
+  private Types typeUtils;
+  private Elements elementUtils;
+
+  @Before
+  public void setUp() {
+    typeUtils = compilationRule.getTypes();
+    elementUtils = compilationRule.getElements();
+  }
+
+  private static class Erasure<T> {
+    int intNo;
+    boolean booleanNo;
+    int[] intArrayNo;
+    String stringNo;
+    String[] stringArrayNo;
+
+    @SuppressWarnings("rawtypes")
+    List rawListNo;
+
+    List<?> listOfQueryNo;
+    List<? extends Object> listOfQueryExtendsObjectNo;
+    Map<?, ?> mapQueryToQueryNo;
+
+    List<String> listOfStringYes;
+    List<? extends String> listOfQueryExtendsStringYes;
+    List<? super String> listOfQuerySuperStringYes;
+    List<T> listOfTypeVarYes;
+    List<? extends T> listOfQueryExtendsTypeVarYes;
+    List<? super T> listOfQuerySuperTypeVarYes;
+  }
+
+  private abstract static class Wildcards {
+    abstract <T extends V, U extends T, V> Map<? extends T, ? super U> one();
+
+    abstract <T extends V, U extends T, V> Map<? extends T, ? super U> two();
+  }
+
+  /**
+   * This test shows why we need to have TypeMirrorSet. The mirror of java.lang.Object obtained from
+   * {@link Elements#getTypeElement Elements.getTypeElement("java.lang.Object")} does not compare
+   * equal to the mirror of the return type of Object.clone(), even though that is also
+   * java.lang.Object and {@link Types#isSameType} considers them the same.
+   *
+   * <p>There's no requirement that this test must pass and if it starts failing or doesn't work in
+   * another test environment then we can delete it. The specification of {@link TypeMirror#equals}
+   * explicitly says that it cannot be used for type equality, so even if this particular case stops
+   * being a problem (which means this test would fail), we would need TypeMirrorSet for complete
+   * correctness.
+   */
+  @Test
+  public void testQuirkyTypeMirrors() {
+    TypeMirror objectMirror = objectMirror();
+    TypeMirror cloneReturnTypeMirror = cloneReturnTypeMirror();
+    assertThat(objectMirror).isNotEqualTo(cloneReturnTypeMirror);
+    assertThat(typeUtils.isSameType(objectMirror, cloneReturnTypeMirror)).isTrue();
+  }
+
+  @Test
+  @SuppressWarnings("TypeEquals") // We want to test the equals method invocation on TypeMirror.
+  public void testTypeMirrorSet() {
+    // Test the TypeMirrorSet methods. Resist the temptation to rewrite these in terms of
+    // Truth operations! For example, don't change assertThat(set.size()).isEqualTo(0) into
+    // assertThat(set).isEmpty(), because then we wouldn't be testing size().
+    TypeMirror objectMirror = objectMirror();
+    TypeMirror otherObjectMirror = cloneReturnTypeMirror();
+    Set<TypeMirror> set = new TypeMirrorSet();
+    assertThat(set.size()).isEqualTo(0);
+    assertThat(set.isEmpty()).isTrue();
+    boolean added = set.add(objectMirror);
+    assertThat(added).isTrue();
+    assertThat(set.size()).isEqualTo(1);
+
+    Set<TypeMirror> otherSet = typeMirrorSet(otherObjectMirror);
+    assertThat(otherSet).isEqualTo(set);
+    assertThat(set).isEqualTo(otherSet);
+    assertThat(otherSet.hashCode()).isEqualTo(set.hashCode());
+
+    assertThat(set.add(otherObjectMirror)).isFalse();
+    assertThat(set.contains(otherObjectMirror)).isTrue();
+
+    assertThat(set.contains(null)).isFalse();
+    assertThat(set.contains((Object) "foo")).isFalse();
+    assertThat(set.remove(null)).isFalse();
+    assertThat(set.remove((Object) "foo")).isFalse();
+
+    TypeElement list = typeElementOf(java.util.List.class);
+    TypeMirror listOfObjectMirror = typeUtils.getDeclaredType(list, objectMirror);
+    TypeMirror listOfOtherObjectMirror = typeUtils.getDeclaredType(list, otherObjectMirror);
+    assertThat(listOfObjectMirror.equals(listOfOtherObjectMirror)).isFalse();
+    assertThat(typeUtils.isSameType(listOfObjectMirror, listOfOtherObjectMirror)).isTrue();
+    added = set.add(listOfObjectMirror);
+    assertThat(added).isTrue();
+    assertThat(set.size()).isEqualTo(2);
+    assertThat(set.add(listOfOtherObjectMirror)).isFalse();
+    assertThat(set.contains(listOfOtherObjectMirror)).isTrue();
+
+    boolean removed = set.remove(listOfOtherObjectMirror);
+    assertThat(removed).isTrue();
+    assertThat(set.contains(listOfObjectMirror)).isFalse();
+
+    set.removeAll(otherSet);
+    assertThat(set.isEmpty()).isTrue();
+  }
+
+  @Test
+  public void testTypeMirrorSetWildcardCapture() {
+    // TODO(emcmanus): this test should really be in MoreTypesTest.
+    // This test checks the assumption made by MoreTypes that you can find the
+    // upper bounds of a TypeVariable tv like this:
+    //   TypeParameterElement tpe = (TypeParameterElement) tv.asElement();
+    //   List<? extends TypeMirror> bounds = tpe.getBounds();
+    // There was some doubt as to whether this would be true in exotic cases involving
+    // wildcard capture, but apparently it is.
+    // The methods one and two here have identical signatures:
+    //   abstract <T extends V, U extends T, V> Map<? extends T, ? super U> name();
+    // Their return types should be considered equal by TypeMirrorSet. The capture of
+    // each return type is different from the original return type, but the two captures
+    // should compare equal to each other. We also add various other types like ? super U
+    // to the set to ensure that the implied calls to the equals and hashCode visitors
+    // don't cause a ClassCastException for TypeParameterElement.
+    TypeElement wildcardsElement = typeElementOf(Wildcards.class);
+    List<? extends ExecutableElement> methods =
+        ElementFilter.methodsIn(wildcardsElement.getEnclosedElements());
+    assertThat(methods).hasSize(2);
+    ExecutableElement one = methods.get(0);
+    ExecutableElement two = methods.get(1);
+    assertThat(one.getSimpleName().toString()).isEqualTo("one");
+    assertThat(two.getSimpleName().toString()).isEqualTo("two");
+    TypeMirrorSet typeMirrorSet = new TypeMirrorSet();
+    assertThat(typeMirrorSet.add(one.getReturnType())).isTrue();
+    assertThat(typeMirrorSet.add(two.getReturnType())).isFalse();
+    DeclaredType captureOne = (DeclaredType) typeUtils.capture(one.getReturnType());
+    assertThat(typeMirrorSet.add(captureOne)).isTrue();
+    DeclaredType captureTwo = (DeclaredType) typeUtils.capture(two.getReturnType());
+    assertThat(typeMirrorSet.add(captureTwo)).isFalse();
+    // Reminder: captureOne is Map<?#123 extends T, ?#456 super U>
+    TypeVariable extendsT = (TypeVariable) captureOne.getTypeArguments().get(0);
+    assertThat(typeMirrorSet.add(extendsT)).isTrue();
+    assertThat(typeMirrorSet.add(extendsT.getLowerBound())).isTrue(); // NoType
+    for (TypeMirror bound : ((TypeParameterElement) extendsT.asElement()).getBounds()) {
+      assertThat(typeMirrorSet.add(bound)).isTrue();
+    }
+    TypeVariable superU = (TypeVariable) captureOne.getTypeArguments().get(1);
+    assertThat(typeMirrorSet.add(superU)).isTrue();
+    assertThat(typeMirrorSet.add(superU.getLowerBound())).isTrue();
+  }
+
+  @Test
+  public void testPackageNameOfString() {
+    assertThat(TypeSimplifier.packageNameOf(typeElementOf(java.lang.String.class)))
+        .isEqualTo("java.lang");
+  }
+
+  @Test
+  public void testPackageNameOfMapEntry() {
+    assertThat(TypeSimplifier.packageNameOf(typeElementOf(java.util.Map.Entry.class)))
+        .isEqualTo("java.util");
+  }
+
+  // Test TypeSimplifier.isCastingUnchecked. We do this by examining the fields of the Erasure
+  // class. A field whose name ends with Yes has a type where
+  // isCastingUnchecked should return true, and one whose name ends with No has a type where
+  // isCastingUnchecked should return false.
+  @Test
+  public void testIsCastingUnchecked() {
+    TypeElement erasureClass = typeElementOf(Erasure.class);
+    List<VariableElement> fields = ElementFilter.fieldsIn(erasureClass.getEnclosedElements());
+    assertThat(fields).isNotEmpty();
+    for (VariableElement field : fields) {
+      String fieldName = field.getSimpleName().toString();
+      boolean expectUnchecked;
+      if (fieldName.endsWith("Yes")) {
+        expectUnchecked = true;
+      } else if (fieldName.endsWith("No")) {
+        expectUnchecked = false;
+      } else {
+        throw new AssertionError("Fields in Erasure class must end with Yes or No: " + fieldName);
+      }
+      TypeMirror fieldType = field.asType();
+      boolean actualUnchecked = TypeSimplifier.isCastingUnchecked(fieldType);
+      assertWithMessage("Unchecked-cast status for " + fieldType)
+          .that(actualUnchecked)
+          .isEqualTo(expectUnchecked);
+    }
+  }
+
+  private static Set<TypeMirror> typeMirrorSet(TypeMirror... typeMirrors) {
+    Set<TypeMirror> set = new TypeMirrorSet();
+    for (TypeMirror typeMirror : typeMirrors) {
+      assertThat(set.add(typeMirror)).isTrue();
+    }
+    return set;
+  }
+
+  private TypeMirror objectMirror() {
+    return typeMirrorOf(Object.class);
+  }
+
+  private TypeMirror cloneReturnTypeMirror() {
+    TypeElement object = typeElementOf(Object.class);
+    ExecutableElement clone = null;
+    for (Element element : object.getEnclosedElements()) {
+      if (element.getSimpleName().contentEquals("clone")) {
+        clone = (ExecutableElement) element;
+        break;
+      }
+    }
+    return clone.getReturnType();
+  }
+
+  private TypeElement typeElementOf(Class<?> c) {
+    return elementUtils.getTypeElement(c.getCanonicalName());
+  }
+
+  private TypeMirror typeMirrorOf(Class<?> c) {
+    return typeElementOf(c).asType();
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/TypeVariablesTest.java b/value/src/test/java/com/google/auto/value/processor/TypeVariablesTest.java
new file mode 100644
index 0000000..078ef51
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/TypeVariablesTest.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2019 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.truth.Expect;
+import com.google.testing.compile.CompilationRule;
+import java.util.List;
+import java.util.Map;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import org.junit.BeforeClass;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class TypeVariablesTest {
+  @ClassRule public static final CompilationRule compilationRule = new CompilationRule();
+  @Rule public final Expect expect = Expect.create();
+
+  private static Elements elementUtils;
+  private static Types typeUtils;
+
+  @BeforeClass
+  public static void setUpClass() {
+    elementUtils = compilationRule.getElements();
+    typeUtils = compilationRule.getTypes();
+  }
+
+  abstract static class Source1 {
+    abstract String getFoo();
+  }
+
+  abstract static class Target1 {}
+
+  @Test
+  public void noTypeParameters() {
+    TypeElement source1 = elementUtils.getTypeElement(Source1.class.getCanonicalName());
+    TypeElement target1 = elementUtils.getTypeElement(Target1.class.getCanonicalName());
+    List<ExecutableElement> sourceMethods = ElementFilter.methodsIn(source1.getEnclosedElements());
+    Map<ExecutableElement, TypeMirror> types =
+        TypeVariables.rewriteReturnTypes(elementUtils, typeUtils, sourceMethods, source1, target1);
+    assertThat(types).containsExactly(sourceMethods.get(0), sourceMethods.get(0).getReturnType());
+  }
+
+  abstract static class Source2<T> {
+    abstract List<T> getFoo();
+  }
+
+  abstract static class Target2<T> {
+    abstract void setFoo(List<T> list);
+  }
+
+  @Test
+  public void simpleTypeParameter() {
+    TypeElement source2 = elementUtils.getTypeElement(Source2.class.getCanonicalName());
+    TypeElement target2 = elementUtils.getTypeElement(Target2.class.getCanonicalName());
+    List<ExecutableElement> sourceMethods = ElementFilter.methodsIn(source2.getEnclosedElements());
+    Map<ExecutableElement, TypeMirror> types =
+        TypeVariables.rewriteReturnTypes(elementUtils, typeUtils, sourceMethods, source2, target2);
+    List<ExecutableElement> targetMethods = ElementFilter.methodsIn(target2.getEnclosedElements());
+    TypeMirror setFooParameter = targetMethods.get(0).getParameters().get(0).asType();
+    ExecutableElement getFoo = sourceMethods.get(0);
+    TypeMirror originalGetFooReturn = getFoo.getReturnType();
+    TypeMirror rewrittenGetFooReturn = types.get(getFoo);
+    assertThat(typeUtils.isAssignable(setFooParameter, originalGetFooReturn)).isFalse();
+    assertThat(typeUtils.isAssignable(setFooParameter, rewrittenGetFooReturn)).isTrue();
+  }
+
+  abstract static class Source3<T extends Comparable<T>, U> {
+    abstract Map<T, ? extends U> getFoo();
+  }
+
+  abstract static class Target3<T extends Comparable<T>, U> {
+    abstract void setFoo(Map<T, ? extends U> list);
+  }
+
+  @Test
+  public void hairyTypeParameters() {
+    TypeElement source3 = elementUtils.getTypeElement(Source3.class.getCanonicalName());
+    TypeElement target3 = elementUtils.getTypeElement(Target3.class.getCanonicalName());
+    List<ExecutableElement> sourceMethods = ElementFilter.methodsIn(source3.getEnclosedElements());
+    Map<ExecutableElement, TypeMirror> types =
+        TypeVariables.rewriteReturnTypes(elementUtils, typeUtils, sourceMethods, source3, target3);
+    List<ExecutableElement> targetMethods = ElementFilter.methodsIn(target3.getEnclosedElements());
+    TypeMirror setFooParameter = targetMethods.get(0).getParameters().get(0).asType();
+    ExecutableElement getFoo = sourceMethods.get(0);
+    TypeMirror originalGetFooReturn = getFoo.getReturnType();
+    TypeMirror rewrittenGetFooReturn = types.get(getFoo);
+    assertThat(typeUtils.isAssignable(setFooParameter, originalGetFooReturn)).isFalse();
+    assertThat(typeUtils.isAssignable(setFooParameter, rewrittenGetFooReturn)).isTrue();
+  }
+
+  abstract static class Outer<T, U extends T> {
+    abstract Map<T, U> getFoo();
+    abstract List<? extends T> getBar();
+
+    abstract static class Inner<T, U extends T> {
+      abstract void setFoo(Map<T, U> foo);
+      abstract void setBar(List<? extends T> bar);
+    }
+  }
+
+  @Test
+  public void nestedClasses() {
+    TypeElement outer = elementUtils.getTypeElement(Outer.class.getCanonicalName());
+    TypeElement inner = elementUtils.getTypeElement(Outer.Inner.class.getCanonicalName());
+    List<ExecutableElement> outerMethods = ElementFilter.methodsIn(outer.getEnclosedElements());
+    Map<ExecutableElement, TypeMirror> types =
+        TypeVariables.rewriteReturnTypes(elementUtils, typeUtils, outerMethods, outer, inner);
+    List<ExecutableElement> innerMethods = ElementFilter.methodsIn(inner.getEnclosedElements());
+    ExecutableElement getFoo = methodNamed(outerMethods, "getFoo");
+    ExecutableElement getBar = methodNamed(outerMethods, "getBar");
+    ExecutableElement setFoo = methodNamed(innerMethods, "setFoo");
+    ExecutableElement setBar = methodNamed(innerMethods, "setBar");
+    TypeMirror setFooParameter = setFoo.getParameters().get(0).asType();
+    TypeMirror originalGetFooReturn = getFoo.getReturnType();
+    TypeMirror rewrittenGetFooReturn = types.get(getFoo);
+    assertThat(typeUtils.isAssignable(setFooParameter, originalGetFooReturn)).isFalse();
+    assertThat(typeUtils.isAssignable(setFooParameter, rewrittenGetFooReturn)).isTrue();
+    TypeMirror setBarParameter = setBar.getParameters().get(0).asType();
+    TypeMirror originalGetBarReturn = getBar.getReturnType();
+    TypeMirror rewrittenGetBarReturn = types.get(getBar);
+    assertThat(typeUtils.isAssignable(setBarParameter, originalGetBarReturn)).isFalse();
+    assertThat(typeUtils.isAssignable(setBarParameter, rewrittenGetBarReturn)).isTrue();
+  }
+
+  @Test
+  public void canAssignStaticMethodResult() {
+    TypeElement immutableMap = elementUtils.getTypeElement(ImmutableMap.class.getCanonicalName());
+    TypeElement string = elementUtils.getTypeElement(String.class.getCanonicalName());
+    TypeElement integer = elementUtils.getTypeElement(Integer.class.getCanonicalName());
+    TypeElement number = elementUtils.getTypeElement(Number.class.getCanonicalName());
+    TypeMirror immutableMapStringNumber =
+        typeUtils.getDeclaredType(immutableMap, string.asType(), number.asType());
+    TypeMirror immutableMapStringInteger =
+        typeUtils.getDeclaredType(immutableMap, string.asType(), integer.asType());
+    TypeElement map = elementUtils.getTypeElement(Map.class.getCanonicalName());
+    TypeMirror erasedMap = typeUtils.erasure(map.asType());
+    // If the target type is ImmutableMap<String, Number> then we should be able to use
+    //   static <K, V> ImmutableMap<K, V> ImmutableMap.copyOf(Map<? extends K, ? extends V>)
+    // with a parameter of type ImmutableMap<String, Integer>.
+    List<ExecutableElement> immutableMapMethods =
+        ElementFilter.methodsIn(immutableMap.getEnclosedElements());
+    ExecutableElement copyOf = methodNamed(immutableMapMethods, "copyOf", erasedMap);
+    expect.that(
+        TypeVariables.canAssignStaticMethodResult(
+            copyOf, immutableMapStringInteger, immutableMapStringNumber, typeUtils))
+        .isTrue();
+    expect.that(
+        TypeVariables.canAssignStaticMethodResult(
+            copyOf, immutableMapStringNumber, immutableMapStringInteger, typeUtils))
+        .isFalse();
+  }
+
+  private static ExecutableElement methodNamed(List<ExecutableElement> methods, String name) {
+    return methods.stream().filter(m -> m.getSimpleName().contentEquals(name)).findFirst().get();
+  }
+
+  private static ExecutableElement methodNamed(
+      List<ExecutableElement> methods, String name, TypeMirror erasedParameterType) {
+    return methods.stream()
+        .filter(m -> m.getSimpleName().contentEquals(name))
+        .filter(m -> m.getParameters().size() == 1)
+        .filter(m -> typeUtils.isSameType(
+                    erasedParameterType, typeUtils.erasure(m.getParameters().get(0).asType())))
+        .findFirst()
+        .get();
+  }
+}
diff --git a/value/src/test/java/com/google/auto/value/processor/testclasses/RuntimePermission.java b/value/src/test/java/com/google/auto/value/processor/testclasses/RuntimePermission.java
new file mode 100644
index 0000000..f9b4bda
--- /dev/null
+++ b/value/src/test/java/com/google/auto/value/processor/testclasses/RuntimePermission.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * 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 com.google.auto.value.processor.testclasses;
+
+/**
+ * This class just exists to test import behaviour when referencing a class which has the same name
+ * as a class in java.lang.
+ *
+ * @author emcmanus@google.com (Éamonn McManus)
+ */
+public class RuntimePermission {}
diff --git a/value/userguide/builders-howto.md b/value/userguide/builders-howto.md
new file mode 100644
index 0000000..00038e7
--- /dev/null
+++ b/value/userguide/builders-howto.md
@@ -0,0 +1,602 @@
+# How do I... (Builder edition)
+
+
+This page answers common how-to questions that may come up when using AutoValue
+**with the builder option**. You should read and understand [AutoValue with
+builders](builders.md) first.
+
+If you are not using a builder, see [Introduction](index.md) and
+[How do I...](howto.md) instead.
+
+## Contents
+
+How do I...
+
+*   ... [use (or not use) `set` **prefixes**?](#beans)
+*   ... [use different **names** besides
+    `builder()`/`Builder`/`build()`?](#build_names)
+*   ... [specify a **default** value for a property?](#default)
+*   ... [initialize a builder to the same property values as an **existing**
+    value instance](#to_builder)
+*   ... [include `with-` methods on my value class for creating slightly
+    **altered** instances?](#withers)
+*   ... [**validate** property values?](#validate)
+*   ... [**normalize** (modify) a property value at `build` time?](#normalize)
+*   ... [expose **both** a builder and a factory method?](#both)
+*   ... [handle `Optional` properties?](#optional)
+*   ... [use a **collection**-valued property?](#collection)
+    *   ... [let my builder **accumulate** values for a collection-valued
+        property (not require them all at once)?](#accumulate)
+    *   ... [accumulate values for a collection-valued property, without
+        **"breaking the chain"**?](#add)
+    *   ... [offer **both** accumulation and set-at-once methods for the same
+        collection-valued property?](#collection_both)
+*   ... [access nested builders while building?](#nested_builders)
+
+## <a name="beans"></a>... use (or not use) `set` prefixes?
+
+Just as you can choose whether to use JavaBeans-style names for property getters
+(`getFoo()` or just `foo()`) in your value class, you have the same choice for
+setters in builders too (`setFoo(value)` or just `foo(value)`). As with getters,
+you must use these prefixes consistently or not at all.
+
+Using `get`/`is` prefixes for getters and using the `set` prefix for setters are
+independent choices. For example, it is fine to use the `set` prefixes on all
+your builder methods, but omit the `get`/`is` prefixes from all your accessors.
+
+Here is the `Animal` example using `get` prefixes but not `set` prefixes:
+
+```java
+@AutoValue
+abstract class Animal {
+  abstract String getName();
+  abstract int getNumberOfLegs();
+
+  static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  abstract static class Builder {
+    abstract Builder name(String value);
+    abstract Builder numberOfLegs(int value);
+    abstract Animal build();
+  }
+}
+```
+
+## <a name="build_names"></a>... use different names besides `builder()`/`Builder`/`build()`?
+
+Use whichever names you like; AutoValue doesn't actually care.
+
+(We would gently recommend these names as conventional.)
+
+## <a name="default"></a>... specify a default value for a property?
+
+What should happen when a caller does not supply a value for a property before
+calling `build()`? If the property in question is [nullable](howto.md#nullable),
+it will simply default to `null` as you would expect. And if it is
+[Optional](#optional) it will default to an empty `Optional` as you might also
+expect. But if it isn't either of those things (including if it is a
+primitive-valued property, which *can't* be null), then `build()` will throw an
+unchecked exception.
+
+But this presents a problem, since one of the main *advantages* of a builder in
+the first place is that callers can specify only the properties they care about!
+
+The solution is to provide a default value for such properties. Fortunately this
+is easy: just set it on the newly-constructed builder instance before returning
+it from the `builder()` method.
+
+Here is the `Animal` example with the default number of legs being 4:
+
+```java
+@AutoValue
+abstract class Animal {
+  abstract String name();
+  abstract int numberOfLegs();
+
+  static Builder builder() {
+    return new AutoValue_Animal.Builder()
+        .setNumberOfLegs(4);
+  }
+
+  @AutoValue.Builder
+  abstract static class Builder {
+    abstract Builder setName(String value);
+    abstract Builder setNumberOfLegs(int value);
+    abstract Animal build();
+  }
+}
+```
+
+Occasionally you may want to supply a default value, but only if the property is
+not set explicitly. This is covered in the section on
+[normalization](#normalize).
+
+## <a name="to_builder"></a>... initialize a builder to the same property values as an existing value instance
+
+Suppose your caller has an existing instance of your value class, and wants to
+change only one or two of its properties. Of course, it's immutable, but it
+would be convenient if they could easily get a `Builder` instance representing
+the same property values, which they could then modify and use to create a new
+value instance.
+
+To give them this ability, just add an abstract `toBuilder` method, returning
+your abstract builder type, to your value class. AutoValue will implement it.
+
+```java
+  public abstract Builder toBuilder();
+```
+
+## <a name="withers"></a>... include `with-` methods on my value class for creating slightly altered instances?
+
+This is a somewhat common pattern among immutable classes. You can't have
+setters, but you can have methods that act similarly to setters by returning a
+new immutable instance that has one property changed.
+
+If you're already using the builder option, you can add these methods by hand:
+
+```java
+@AutoValue
+public abstract class Animal {
+  public abstract String name();
+  public abstract int numberOfLegs();
+
+  public static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  abstract Builder toBuilder();
+
+  public Animal withName(String name) {
+    return toBuilder().setName(name).build();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setName(String value);
+    public abstract Builder setNumberOfLegs(int value);
+    public abstract Animal build();
+  }
+}
+```
+
+Note that it's your free choice what to make public (`toBuilder`, `withName`,
+neither, or both).
+
+## <a name="validate"></a>... validate property values?
+
+Validating properties is a little less straightforward than it is in the
+[non-builder case](howto.md#validate).
+
+What you need to do is *split* your "build" method into two methods:
+
+*   the non-visible, abstract method that AutoValue implements
+*   and the visible, *concrete* method you provide, which calls the generated
+    method and performs validation.
+
+We recommend naming these methods `autoBuild` and `build`, but any names will
+work. It ends up looking like this:
+
+```java
+@AutoValue
+public abstract class Animal {
+  public abstract String name();
+  public abstract int numberOfLegs();
+
+  public static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setName(String value);
+    public abstract Builder setNumberOfLegs(int value);
+
+    abstract Animal autoBuild();  // not public
+
+    public Animal build() {
+      Animal animal = autoBuild();
+      Preconditions.checkState(animal.numberOfLegs() >= 0, "Negative legs");
+      return animal;
+    }
+  }
+}
+```
+
+## <a name="normalize"></a>... normalize (modify) a property value at `build` time?
+
+Suppose you want to convert the animal's name to lower case.
+
+You'll need to add a *getter* to your builder, as shown:
+
+```java
+@AutoValue
+public abstract class Animal {
+  public abstract String name();
+  public abstract int numberOfLegs();
+
+  public static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setName(String value);
+    public abstract Builder setNumberOfLegs(int value);
+
+    abstract String name(); // must match method name in Animal
+
+    abstract Animal autoBuild(); // not public
+
+    public Animal build() {
+      setName(name().toLowerCase());
+      return autoBuild();
+    }
+  }
+}
+```
+
+The getter in your builder must have the same signature as the abstract property
+accessor method in the value class. It will return the value that has been set
+on the `Builder`. If no value has been set for a
+non-[nullable](howto.md#nullable) property, `IllegalStateException` is thrown.
+
+Getters should generally only be used within the `Builder` as shown, so they are
+not public.
+
+As an alternative to returning the same type as the property accessor method,
+the builder getter can return an Optional wrapping of that type. This can be
+used if you want to supply a default, but only if the property has not been set.
+(The [usual way](#default) of supplying defaults means that the property always
+appears to have been set.) For example, suppose you wanted the default name of
+your Animal to be something like "4-legged creature", where 4 is the
+`numberOfLegs()` property. You might write this:
+
+```java
+@AutoValue
+public abstract class Animal {
+  public abstract String name();
+  public abstract int numberOfLegs();
+
+  public static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setName(String value);
+    public abstract Builder setNumberOfLegs(int value);
+
+    abstract Optional<String> name();
+    abstract int numberOfLegs();
+
+    abstract Animal autoBuild(); // not public
+
+    public Animal build() {
+      if (!name().isPresent()) {
+        setName(numberOfLegs() + "-legged creature");
+      }
+      return autoBuild();
+    }
+  }
+}
+```
+
+Notice that this will throw `IllegalStateException` if the `numberOfLegs`
+property hasn't been set either.
+
+The Optional wrapping can be any of the Optional types mentioned in the
+[section](#optional) on `Optional` properties. If your property has type `int`
+it can be wrapped as either `Optional<Integer>` or `OptionalInt`, and likewise
+for `long` and `double`.
+
+## <a name="both"></a>... expose *both* a builder *and* a factory method?
+
+If you use the builder option, AutoValue will not generate a visible constructor
+for the generated concrete value class. If it's important to offer your caller
+the choice of a factory method as well as the builder, then your factory method
+implementation will have to invoke the builder itself.
+
+## <a name="optional"></a>... handle `Optional` properties?
+
+Properties of type `Optional` benefit from special treatment. If you have a
+property of type `Optional<String>`, say, then it will default to an empty
+`Optional` without needing to [specify](#default) a default explicitly. And,
+instead of or as well as the normal `setFoo(Optional<String>)` method, you can
+have `setFoo(String)`. Then `setFoo(s)` is equivalent to
+`setFoo(Optional.of(s))`.
+
+Here, `Optional` means either [`java.util.Optional`] from Java (Java 8 or
+later), or [`com.google.common.base.Optional`] from Guava. Java 8 also
+introduced related classes in `java.util` called [`OptionalInt`],
+[`OptionalLong`], and [`OptionalDouble`]. You can use those in the same way. For
+example a property of type `OptionalInt` will default to `OptionalInt.empty()`
+and you can set it with either `setFoo(OptionalInt)` or `setFoo(int)`.
+
+```java
+@AutoValue
+public abstract class Animal {
+  public abstract Optional<String> name();
+
+  public static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    // You can have either or both of these two methods:
+    public abstract Builder setName(Optional<String> value);
+    public abstract Builder setName(String value);
+    public abstract Animal build();
+  }
+}
+```
+
+[`java.util.Optional`]: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
+[`com.google.common.base.Optional`]: https://guava.dev/releases/snapshot/api/docs/com/google/common/base/Optional.html
+[`OptionalDouble`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalDouble.html
+[`OptionalInt`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalInt.html
+[`OptionalLong`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalLong.html
+
+## <a name="collection"></a>... use a collection-valued property?
+
+Value objects should be immutable, so if a property of one is a collection then
+that collection should be immutable too. We recommend using Guava's [immutable
+collections] to make that explicit. AutoValue's builder support includes a few
+special arrangements to make this more convenient.
+
+In the examples here we use `ImmutableSet`, but the same principles apply to all
+of Guava's immutable collection types, like `ImmutableList`,
+`ImmutableMultimap`, and so on.
+
+We recommend using the immutable type (like `ImmutableSet<String>`) as your
+actual property type. However, it can be a pain for callers to always have to
+construct `ImmutableSet` instances to pass into your builder. So AutoValue
+allows your builder method to accept an argument of any type that
+`ImmutableSet.copyOf` accepts.
+
+If our `Animal` acquires an `ImmutableSet<String>` that is the countries it
+lives in, that can be set from a `Set<String>` or a `Collection<String>` or an
+`Iterable<String>` or a `String[]` or any other compatible type. You can even
+offer multiple choices, as in this example:
+
+```java
+@AutoValue
+public abstract class Animal {
+  public abstract String name();
+  public abstract int numberOfLegs();
+  public abstract ImmutableSet<String> countries();
+
+  public static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setName(String value);
+    public abstract Builder setNumberOfLegs(int value);
+    public abstract Builder setCountries(Set<String> value);
+    public abstract Builder setCountries(String... value);
+    public abstract Animal build();
+  }
+}
+```
+
+[immutable collections]: https://github.com/google/guava/wiki/ImmutableCollectionsExplained
+
+### <a name="accumulate"></a>... let my builder *accumulate* values for a collection-valued property (not require them all at once)?
+
+Instead of defining a setter for an immutable collection `foos`, you can define
+a method `foosBuilder()` that returns the associated builder type for that
+collection. In this example, we have an `ImmutableSet<String>` which can be
+built using the `countriesBuilder()` method:
+
+```java
+@AutoValue
+public abstract class Animal {
+  public abstract String name();
+  public abstract int numberOfLegs();
+  public abstract ImmutableSet<String> countries();
+
+  public static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setName(String value);
+    public abstract Builder setNumberOfLegs(int value);
+    public abstract ImmutableSet.Builder<String> countriesBuilder();
+    public abstract Animal build();
+  }
+}
+```
+
+The name of this method must be exactly the property name (`countries` here)
+followed by the string `Builder`. Even if the properties follow the
+`getCountries()` convention, the builder method must be `countriesBuilder()`
+and not `getCountriesBuilder()`.
+
+You may notice a small problem with this example: the caller can no longer
+create their instance in a single chained statement:
+
+```java
+  // This DOES NOT work!
+  Animal dog = Animal.builder()
+      .setName("dog")
+      .setNumberOfLegs(4)
+      .countriesBuilder()
+          .add("Guam")
+          .add("Laos")
+      .build();
+```
+
+Instead they are forced to hold the builder itself in a temporary variable:
+
+```java
+  // This DOES work... but we have to "break the chain"!
+  Animal.Builder builder = Animal.builder()
+      .setName("dog")
+      .setNumberOfLegs(4);
+  builder.countriesBuilder()
+      .add("Guam")
+      .add("Laos");
+  Animal dog = builder.build();
+```
+
+One solution for this problem is just below.
+
+### <a name="add"></a>... accumulate values for a collection-valued property, without "breaking the chain"?
+
+Another option is to keep `countriesBuilder()` itself non-public, and only use
+it to implement a public `addCountry` method:
+
+```java
+@AutoValue
+public abstract class Animal {
+  public abstract String name();
+  public abstract int numberOfLegs();
+  public abstract ImmutableSet<String> countries();
+
+  public static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setName(String value);
+    public abstract Builder setNumberOfLegs(int value);
+
+    abstract ImmutableSet.Builder<String> countriesBuilder();
+    public Builder addCountry(String value) {
+      countriesBuilder().add(value);
+      return this;
+    }
+
+    public abstract Animal build();
+  }
+}
+```
+
+Now the caller can do this:
+
+```java
+  // This DOES work!
+  Animal dog = Animal.builder()
+      .setName("dog")
+      .setNumberOfLegs(4)
+      .addCountry("Guam")
+      .addCountry("Laos") // however many times needed
+      .build();
+```
+
+### <a name="collection_both"></a>... offer both accumulation and set-at-once methods for the same collection-valued property?
+
+Yes, you can provide both methods, letting your caller choose the style they
+prefer.
+
+The same caller can mix the two styles only in limited ways; once `foosBuilder`
+has been called, any subsequent call to `setFoos` will throw an unchecked
+exception. On the other hand, calling `setFoos` first is okay; a later call to
+`foosBuilder` will return a builder already populated with the
+previously-supplied elements.
+
+## <a name="nested_builders"></a>... access nested builders while building?
+
+Often a property of an `@AutoValue` class is itself an immutable class,
+perhaps another `@AutoValue`. In such cases your builder can expose a builder
+for that nested class. This is very similar to exposing a builder for a
+collection property, as described [earlier](#accumulate).
+
+Suppose the `Animal` class has a property of type `Species`:
+
+```java
+@AutoValue
+public abstract class Animal {
+  public abstract String name();
+  public abstract Species species();
+
+  public static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setName(String name);
+    public abstract Species.Builder speciesBuilder();
+    public abstract Animal build();
+  }
+}
+
+@AutoValue
+public abstract class Species {
+  public abstract String genus();
+  public abstract String epithet();
+
+  public static Builder builder() {
+    return new AutoValue_Species.Builder();
+  }
+
+  @AutoValue.Builder
+  public abstract static class Builder {
+    public abstract Builder setGenus(String genus);
+    public abstract Builder setEpithet(String epithet);
+    public abstract Species build();
+  }
+}
+```
+
+Now you can access the builder of the nested `Species` while you are building
+the `Animal`:
+
+```java
+  Animal.Builder catBuilder = Animal.builder()
+      .setName("cat");
+  catBuilder.speciesBuilder()
+      .setGenus("Felis")
+      .setEpithet("catus");
+  Animal cat = catBuilder.build();
+```
+
+Although the nested class in the example (`Species`) is also an `@AutoValue`
+class, it does not have to be. For example, it could be a [protobuf]. The
+requirements are:
+
+* The nested class must have a way to make a new builder. This can be
+  `new Species.Builder()`, or `Species.builder()`, or `Species.newBuilder()`.
+
+* There must be a way to build an instance from the builder: `Species.Builder`
+  must have a method `Species build()`.
+
+* If there is a need to convert `Species` back into its builder, then `Species`
+  must have a method `Species.Builder toBuilder()`.
+
+  In the example, if `Animal` has an abstract [`toBuilder()`](#to_builder)
+  method then `Species` must also have a `toBuilder()` method. That also applies
+  if there is an abstract `setSpecies` method in addition to the
+  `speciesBuilder` method.
+
+  As an alternative to having a method `Species.Builder toBuilder()` in
+  `Species`, `Species.Builder` can have a method called `addAll` or `putAll`
+  that accepts an argument of type `Species`. This is how AutoValue handles
+  `ImmutableSet` for example. `ImmutableSet` does not have a `toBuilder()`
+  method, but `ImmutableSet.Builder` does have an `addAll` method that accepts
+  an `ImmutableSet`. So given `ImmutableSet<String> strings`, we can achieve the
+  effect of `strings.toBuilder()` by doing:
+
+  ```
+  ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+  builder.addAll(strings);
+  ```
+
+There are no requirements on the name of the builder class. Instead of
+`Species.Builder`, it could be `Species.Factory` or `SpeciesBuilder`.
+
+If `speciesBuilder()` is never called then the final `species()` property will
+be set as if by `speciesBuilder().build()`. In the example, that would result
+in an exception because the required properties of `Species` have not been set.
+
+
+[protobuf]: https://developers.google.com/protocol-buffers/docs/reference/java-generated#builders
diff --git a/value/userguide/builders.md b/value/userguide/builders.md
new file mode 100644
index 0000000..11c68c6
--- /dev/null
+++ b/value/userguide/builders.md
@@ -0,0 +1,101 @@
+# AutoValue with Builders
+
+
+The [introduction](index.md) of this User Guide covers the basic usage of
+AutoValue using a static factory method as your public creation API. But in many
+circumstances (such as those laid out in *Effective Java, 2nd Edition* Item 2),
+you may prefer to let your callers use a *builder* instead.
+
+Fortunately, AutoValue can generate builder classes too! This page explains how.
+Note that we recommend reading and understanding the basic usage shown in the
+[introduction](index.md) first.
+
+
+## How to use AutoValue with Builders<a name="howto"></a>
+
+As explained in the introduction, the AutoValue concept is that **you write an
+abstract value class, and AutoValue implements it**. Builder generation works in
+the exact same way: you also create an abstract builder class, nesting it inside
+your abstract value class, and AutoValue generates implementations for both.
+
+### In `Animal.java`<a name="example_java"></a>
+
+```java
+import com.google.auto.value.AutoValue;
+
+@AutoValue
+abstract class Animal {
+  abstract String name();
+  abstract int numberOfLegs();
+
+  static Builder builder() {
+    return new AutoValue_Animal.Builder();
+  }
+
+  @AutoValue.Builder
+  abstract static class Builder {
+    abstract Builder setName(String value);
+    abstract Builder setNumberOfLegs(int value);
+    abstract Animal build();
+  }
+}
+```
+
+Note that in real life, some classes and methods would presumably be public and
+have **Javadoc**. We're leaving these off in the User Guide only to keep the
+examples clean and short.
+
+### Usage<a name="usage"></a>
+
+```java
+public void testAnimal() {
+  Animal dog = Animal.builder().setName("dog").setNumberOfLegs(4).build();
+  assertEquals("dog", dog.name());
+  assertEquals(4, dog.numberOfLegs());
+
+  // You probably don't need to write assertions like these; just illustrating.
+  assertTrue(
+      Animal.builder().setName("dog").setNumberOfLegs(4).build().equals(dog));
+  assertFalse(
+      Animal.builder().setName("cat").setNumberOfLegs(4).build().equals(dog));
+  assertFalse(
+      Animal.builder().setName("dog").setNumberOfLegs(2).build().equals(dog));
+
+  assertEquals("Animal{name=dog, numberOfLegs=4}", dog.toString());
+}
+```
+
+### What does AutoValue generate?<a name="generated"></a>
+
+For the `Animal` example shown above, here is [typical code AutoValue might
+generate](generated-builder-example.md).
+
+## Warnings<a name="warnings"></a>
+
+Be sure to put the static `builder()` method directly in your value class (e.g.,
+`Animal`) and not the nested abstract `Builder` class. That ensures that the
+`Animal` class is always initialized before `Builder`. Otherwise you may be
+exposing yourself to initialization-order problems.
+
+## <a name="howto"></a>How do I...
+
+*   ... [use (or not use) `set` **prefixes**?](builders-howto.md#beans)
+*   ... [use different **names** besides
+    `builder()`/`Builder`/`build()`?](builders-howto.md#build_names)
+*   ... [specify a **default** value for a property?](builders-howto.md#default)
+*   ... [initialize a builder to the same property values as an **existing**
+    value instance](builders-howto.md#to_builder)
+*   ... [include `with-` methods on my value class for creating slightly
+    **altered** instances?](builders-howto.md#withers)
+*   ... [**validate** property values?](builders-howto.md#validate)
+*   ... [**normalize** (modify) a property value at `build`
+    time?](builders-howto.md#normalize)
+*   ... [expose **both** a builder and a factory
+    method?](builders-howto.md#both)
+*   ... [use a **collection**-valued property?](builders-howto.md#collection)
+    *   ... [let my builder **accumulate** values for a collection-valued
+        property (not require them all at once)?](builders-howto.md#accumulate)
+    *   ... [accumulate values for a collection-valued property, without
+        **breaking the chain**?](builders-howto.md#add)
+    *   ... [offer **both** accumulation and set-at-once methods for the same
+        collection-valued property?](builders-howto.md#collection_both)
diff --git a/value/userguide/design-faq.md b/value/userguide/design-faq.md
new file mode 100644
index 0000000..7c18312
--- /dev/null
+++ b/value/userguide/design-faq.md
@@ -0,0 +1,5 @@
+# Design FAQ
+
+
+TODO. This page will contain various explanations of *why* AutoValue's features
+were designed as they are.
diff --git a/value/userguide/extensions.md b/value/userguide/extensions.md
new file mode 100644
index 0000000..ec6c467
--- /dev/null
+++ b/value/userguide/extensions.md
@@ -0,0 +1,43 @@
+# Extensions
+
+
+AutoValue can be extended to implement new features for classes annotated with
+`@AutoValue`.
+
+## Using extensions
+
+Each extension is a class. If that class is on the `processorpath` when you
+compile your `@AutoValue` class, the extension can run.
+
+
+Some extensions are triggered by their own annotations, which you add to your
+class; others may be triggered in other ways. Consult the extension's
+documentation for usage instructions.
+
+## Writing an extension
+
+To add a feature, write a class that extends [`AutoValueExtension`], and put
+that class on the `processorpath` along with `AutoValueProcessor`.
+
+`AutoValueExtension` uses the [`ServiceLoader`] mechanism, which means:
+
+*   Your class must be public and have a public no-argument constructor.
+*   Its fully-qualified name must appear in a file called
+    `META-INF/services/com.google.auto.value.extension.AutoValueExtension` in a
+    JAR that is on the compiler's `classpath` or `processorpath`.
+
+You can use [AutoService] to make implementing the `ServiceLoader` pattern easy.
+
+Without extensions, AutoValue generates a subclass of the `@AutoValue` class.
+Extensions can work by generating a chain of subclasses, each of which alters
+behavior by overriding or implementing new methods.
+
+## TODO
+
+*   How to distribute extensions.
+*   List of known extensions.
+
+[AutoService]: https://github.com/google/auto/tree/master/service
+[`AutoValueExtension`]: https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/extension/AutoValueExtension.java
+[`ServiceLoader`]: http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html
+
diff --git a/value/userguide/generated-builder-example.md b/value/userguide/generated-builder-example.md
new file mode 100644
index 0000000..70301c8
--- /dev/null
+++ b/value/userguide/generated-builder-example.md
@@ -0,0 +1,103 @@
+# Generated builder example
+
+
+For the code shown in the [builder documentation](builders.md), the following is
+typical code AutoValue might generate:
+
+```java
+import javax.annotation.Generated;
+
+@Generated("com.google.auto.value.processor.AutoValueProcessor")
+final class AutoValue_Animal extends Animal {
+  private final String name;
+  private final int numberOfLegs;
+
+  private AutoValue_Animal(
+      String name,
+      int numberOfLegs) {
+    this.name = name;
+    this.numberOfLegs = numberOfLegs;
+  }
+
+  @Override
+  String name() {
+    return name;
+  }
+
+  @Override
+  int numberOfLegs() {
+    return numberOfLegs;
+  }
+
+  @Override
+  public String toString() {
+    return "Animal{"
+        + "name=" + name + ", "
+        + "numberOfLegs=" + numberOfLegs
+        + "}";
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
+    if (o instanceof Animal) {
+      Animal that = (Animal) o;
+      return (this.name.equals(that.name()))
+           && (this.numberOfLegs == that.numberOfLegs());
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    int h = 1;
+    h *= 1000003;
+    h ^= this.name.hashCode();
+    h *= 1000003;
+    h ^= this.numberOfLegs;
+    return h;
+  }
+
+  static final class Builder extends Animal.Builder {
+    private String name;
+    private Integer numberOfLegs;
+
+    Builder() {
+    }
+
+    @Override
+    Animal.Builder setName(String name) {
+      if (name == null) {
+        throw new NullPointerException("Null name");
+      }
+      this.name = name;
+      return this;
+    }
+
+    @Override
+    Animal.Builder setNumberOfLegs(int numberOfLegs) {
+      this.numberOfLegs = numberOfLegs;
+      return this;
+    }
+
+    @Override
+    Animal build() {
+      String missing = "";
+      if (this.name == null) {
+        missing += " name";
+      }
+      if (this.numberOfLegs == null) {
+        missing += " numberOfLegs";
+      }
+      if (!missing.isEmpty()) {
+        throw new IllegalStateException("Missing required properties:" + missing);
+      }
+      return new AutoValue_Animal(
+          this.name,
+          this.numberOfLegs);
+    }
+  }
+}
+```
diff --git a/value/userguide/generated-example.md b/value/userguide/generated-example.md
new file mode 100644
index 0000000..c514d52
--- /dev/null
+++ b/value/userguide/generated-example.md
@@ -0,0 +1,63 @@
+# Generated example
+
+
+For the code shown in the [introduction](index.md), the following is typical
+code AutoValue might generate:
+
+```java
+import javax.annotation.Generated;
+
+@Generated("com.google.auto.value.processor.AutoValueProcessor")
+final class AutoValue_Animal extends Animal {
+  private final String name;
+  private final int numberOfLegs;
+
+  AutoValue_Animal(String name, int numberOfLegs) {
+    if (name == null) {
+      throw new NullPointerException("Null name");
+    }
+    this.name = name;
+    this.numberOfLegs = numberOfLegs;
+  }
+
+  @Override
+  String name() {
+    return name;
+  }
+
+  @Override
+  int numberOfLegs() {
+    return numberOfLegs;
+  }
+
+  @Override
+  public String toString() {
+    return "Animal{"
+        + "name=" + name + ", "
+        + "numberOfLegs=" + numberOfLegs + "}";
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (o == this) {
+      return true;
+    }
+    if (o instanceof Animal) {
+      Animal that = (Animal) o;
+      return this.name.equals(that.name())
+          && this.numberOfLegs == that.numberOfLegs();
+    }
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    int h = 1;
+    h *= 1000003;
+    h ^= this.name.hashCode();
+    h *= 1000003;
+    h ^= this.numberOfLegs;
+    return h;
+  }
+}
+```
diff --git a/value/userguide/howto.md b/value/userguide/howto.md
new file mode 100644
index 0000000..1dbc561
--- /dev/null
+++ b/value/userguide/howto.md
@@ -0,0 +1,678 @@
+# How do I...
+
+
+This page answers common how-to questions that may come up when using AutoValue.
+You should read and understand the [Introduction](index.md) first.
+
+Questions specific to usage of the **builder option** are documented separately;
+for this, start by reading [AutoValue with builders](builders.md).
+
+## Contents
+
+How do I...
+
+*   ... [also generate a **builder** for my value class?](#builder)
+*   ... [use AutoValue with a **nested** class?](#nested)
+*   ... [use (or not use) JavaBeans-style name **prefixes**?](#beans)
+*   ... [use **nullable** properties?](#nullable)
+*   ... [perform other **validation**?](#validate)
+*   ... [use a property of a **mutable** type?](#mutable_property)
+*   ... [use a **custom** implementation of `equals`, etc.?](#custom)
+*   ... [have AutoValue implement a concrete or default method?](#concrete)
+*   ... [have multiple **`create`** methods, or name it/them
+    differently?](#create)
+*   ... [**ignore** certain properties in `equals`, etc.?](#ignore)
+*   ... [have AutoValue also implement abstract methods from my
+    **supertypes**?](#supertypes)
+*   ... [use AutoValue with a **generic** class?](#generic)
+*   ... [make my class Java- or GWT\-**serializable**?](#serialize)
+*   ... [use AutoValue to **implement** an **annotation** type?](#annotation)
+*   ... [also include **setter** (mutator) methods?](#setters)
+*   ... [also generate **`compareTo`**?](#compareTo)
+*   ... [use a **primitive array** for a property value?](#primitive_array)
+*   ... [use an **object array** for a property value?](#object_array)
+*   ... [have one `@AutoValue` class **extend** another?](#inherit)
+*   ... [keep my accessor methods **private**?](#private_accessors)
+*   ... [expose a **constructor**, not factory method, as my public creation
+    API?](#public_constructor)
+*   ... [use AutoValue on an **interface**, not abstract class?](#interface)
+*   ... [**memoize** ("cache") derived properties?](#memoize)
+*   ... [memoize the result of `hashCode` or
+    `toString`?](#memoize_hash_tostring)
+*   ... [make a class where only one of its properties is ever set?](#oneof)
+*   ... [copy annotations from a class/method to the implemented
+    class/method/field?](#copy_annotations)
+
+## <a name="builder"></a>... also generate a builder for my value class?
+
+Please see [AutoValue with builders](builders.md).
+
+## <a name="nested"></a>... use AutoValue with a nested class?
+
+AutoValue composes the generated class name in the form
+`AutoValue_`*`Outer_Middle_Inner`*.
+As many of these segments will be used in the generated name as required.
+Only the simple class name will appear in `toString` output.
+
+```java
+class Outer {
+  static class Middle {
+    @AutoValue
+    abstract static class Inner {
+      static Inner create(String foo) {
+        return new AutoValue_Outer_Middle_Inner(foo);
+      }
+      ...
+```
+
+## <a name="beans"></a>... use (or not use) JavaBeans-style name prefixes?
+
+Some developers prefer to name their accessors with a `get-` or `is-` prefix,
+but would prefer that only the "bare" property name be used in `toString` and
+for the generated constructor's parameter names.
+
+AutoValue will do exactly this, but only if you are using these prefixes
+*consistently*. In that case, it infers your intended property name by first
+stripping the `get-` or `is-` prefix, then adjusting the case of what remains as
+specified by
+[Introspector.decapitalize](http://docs.oracle.com/javase/8/docs/api/java/beans/Introspector.html#decapitalize).
+
+Note that, in keeping with the JavaBeans specification, the `is-` prefix is only
+allowed on `boolean`-returning methods. `get-` is allowed on any type of
+accessor.
+
+## <a name="nullable"></a>... use nullable properties?
+
+Ordinarily the generated constructor will reject any null values. If you want to
+accept null, simply apply any annotation named `@Nullable` to the appropriate
+accessor methods. This causes AutoValue to remove the null checks and generate
+null-friendly code for `equals`, `hashCode` and `toString`. Example:
+
+```java
+@AutoValue
+public abstract class Foo {
+  public static Foo create(@Nullable Bar bar) {
+    return new AutoValue_Foo(bar);
+  }
+
+  @Nullable abstract Bar bar();
+}
+```
+
+This example also shows annotating the corresponding `create` parameter with
+`@Nullable`. AutoValue does not actually require this annotation, only the one
+on the accessor, but we recommended it as useful documentation to your caller.
+Conversely, if `@Nullable` is only added to the parameter in `create` (or
+similarly the setter method of [AutoValue.Builder](builders)), but not the
+corresponding accessor method, it won't have any effect.
+
+## <a name="validate"></a>... perform other validation?
+
+Null checks are added automatically (as [above](#nullable)). For other types of
+precondition checks or pre-processing, just add them to your factory method:
+
+```java
+static MyType create(String first, String second) {
+  checkArgument(!first.isEmpty());
+  return new AutoValue_MyType(first, second.trim());
+}
+```
+
+## <a name="mutable_property"></a>... use a property of a mutable type?
+
+AutoValue classes are meant and expected to be immutable. But sometimes you
+would want to take a mutable type and use it as a property. In these cases:
+
+First, check if the mutable type has a corresponding immutable cousin. For
+example, the types `List<String>` and `String[]` have the immutable counterpart
+`ImmutableList<String>` in [Guava](http://github.com/google/guava). If so, use
+the immutable type for your property, and only accept the mutable type during
+construction:
+
+```java
+@AutoValue
+public abstract class ListExample {
+  public static ListExample create(String[] mutableNames) {
+    return new AutoValue_ListExample(ImmutableList.copyOf(mutableNames));
+  }
+
+  public abstract ImmutableList<String> names();
+}
+```
+
+Note: this is a perfectly sensible practice, not an ugly workaround!
+
+If there is no suitable immutable type to use, you'll need to proceed with
+caution. Your static factory method should pass a *clone* of the passed object
+to the generated constructor. Your accessor method should document a very loud
+warning never to mutate the object returned.
+
+```java
+@AutoValue
+public abstract class MutableExample {
+  public static MutableExample create(MutablePropertyType ouch) {
+    // Replace `MutablePropertyType.copyOf()` below with the right copying code for this type
+    return new AutoValue_MutableExample(MutablePropertyType.copyOf(ouch));
+  }
+
+  /**
+   * Returns the ouch associated with this object; <b>do not mutate</b> the
+   * returned object.
+   */
+  public abstract MutablePropertyType ouch();
+}
+```
+
+Warning: this is an ugly workaround, not a perfectly sensible practice! Callers
+can trivially break the invariants of the immutable class by mutating the
+accessor's return value. An example where something can go wrong: AutoValue
+objects can be used as keys in Maps.
+
+## <a name="custom"></a>... use a custom implementation of `equals`, etc.?
+
+Simply write your custom implementation; AutoValue will notice this and will
+skip generating its own. Your hand-written logic will thus be inherited on the
+concrete implementation class. We call this *underriding* the method.
+
+Remember when doing this that you are losing AutoValue's protections. Be careful
+to follow the basic rules of hash codes: equal objects must have equal hash
+codes *always*, and equal hash codes should imply equal objects *almost always*.
+You should now test your class more thoroughly, ideally using
+[`EqualsTester`](http://static.javadoc.io/com.google.guava/guava-testlib/19.0/com/google/common/testing/EqualsTester.html)
+from [guava-testlib](http://github.com/google/guava).
+
+Best practice: mark your underriding methods `final` to make it clear to future
+readers that these methods aren't overridden by AutoValue.
+
+## <a name="concrete"></a>... have AutoValue implement a concrete or default method?
+
+If a parent class defines a concrete (non-abstract) method that you would like
+AutoValue to implement, you can *redeclare* it as abstract. This applies to
+`Object` methods like `toString()`, but also to property methods that you would
+like to have AutoValue implement. It also applies to default methods in
+interfaces.
+
+```java
+@AutoValue
+class PleaseOverrideExample extends SuperclassThatDefinesToString {
+  ...
+
+  // cause AutoValue to generate this even though the superclass has it
+  @Override public abstract String toString();
+}
+```
+
+```java
+@AutoValue
+class PleaseReimplementDefaultMethod implements InterfaceWithDefaultMethod {
+  ...
+
+  // cause AutoValue to implement this even though the interface has a default
+  // implementation
+  @Override public abstract int numberOfLegs();
+}
+```
+
+## <a name="create"></a>... have multiple `create` methods, or name it/them differently?
+
+Just do it! AutoValue doesn't actually care. This
+[best practice item](practices.md#one_reference) may be relevant.
+
+## <a name="ignore"></a>... ignore certain properties in `equals`, etc.?
+
+Suppose your value class has an extra field that shouldn't be included in
+`equals` or `hashCode` computations.
+
+If this is because it is a derived value based on other properties, see [How do
+I memoize derived properties?](#memoize).
+
+Otherwise, first make certain that you really want to do this. It is often, but
+not always, a mistake. Remember that libraries will treat two equal instances as
+absolutely *interchangeable* with each other. Whatever information is present in
+this extra field could essentially "disappear" when you aren't expecting it, for
+example when your value is stored and retrieved from certain collections.
+
+If you're sure, here is how to do it:
+
+```java
+@AutoValue
+abstract class IgnoreExample {
+  static IgnoreExample create(String normalProperty, String ignoredProperty) {
+    IgnoreExample ie = new AutoValue_IgnoreExample(normalProperty);
+    ie.ignoredProperty = ignoredProperty;
+    return ie;
+  }
+
+  abstract String normalProperty();
+
+  private String ignoredProperty; // sadly, it can't be `final`
+
+  final String ignoredProperty() {
+    return ignoredProperty;
+  }
+}
+```
+
+Note that this means the field is also ignored by `toString`; to AutoValue
+it simply doesn't exist.
+
+## <a name="supertypes"></a>... have AutoValue also implement abstract methods from my supertypes?
+
+AutoValue will recognize every abstract accessor method whether it is defined
+directly in your own hand-written class or in a supertype.
+
+These abstract methods can come from more than one place, for example from an
+interface and from the superclass. It may not then be obvious what order they
+are in, even though you need to know this order if you want to call the
+generated `AutoValue_Foo` constructor. You might find it clearer to use a
+[builder](builders.md) instead. But the order is deterministic: within a class
+or interface, methods are in the order they appear in the source code; methods
+in ancestors come before methods in descendants; methods in interfaces come
+before methods in classes; and in a class or interface that has more than one
+superinterface, the interfaces are in the order of their appearance in
+`implements` or `extends`.
+
+## <a name="generic"></a>... use AutoValue with a generic class?
+
+There's nothing to it: just add type parameters to your class and to your call
+to the generated constructor.
+
+## <a name="serialize"></a>... make my class Java- or GWT\-serializable?
+
+Just add `implements Serializable` or the `@GwtCompatible(serializable = true)`
+annotation (respectively) to your hand-written class; it (as well as any
+`serialVersionUID`) will be duplicated on the generated class, and you'll be
+good to go.
+
+## <a name="annotation"></a>... use AutoValue to implement an annotation type?
+
+Most users should never have the need to programmatically create "fake"
+annotation instances. But if you do, using `@AutoValue` in the usual way will
+fail because the `Annotation.hashCode` specification is incompatible with
+AutoValue's behavior.
+
+However, we've got you covered anyway! Suppose this annotation definition:
+
+```java
+public @interface Named {
+  String value();
+}
+```
+
+All you need is this:
+
+```java
+public class Names {
+  @AutoAnnotation public static Named named(String value) {
+    return new AutoAnnotation_Names_named(value);
+  }
+}
+```
+
+For more details, see the [`AutoAnnotation`
+javadoc](http://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/AutoAnnotation.java#L24).
+
+## <a name="setters"></a>... also include setter (mutator) methods?
+
+You can't; AutoValue only generates immutable value classes.
+
+Note that giving value semantics to a mutable type is widely considered a
+questionable practice in the first place. Equal instances of a value class are
+treated as *interchangeable*, but they can't truly be interchangeable if one
+might be mutated and the other not.
+
+## <a name="compareTo"></a>... also generate `compareTo`?
+
+AutoValue intentionally does not provide this feature. It is better for you to
+roll your own comparison logic using the new methods added to
+[`Comparator`](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html)
+in Java 8, or
+[`ComparisonChain`](https://guava.dev/releases/snapshot/api/docs/com/google/common/collect/ComparisonChain.html)
+from [Guava](http://github.com/google/guava).
+
+Since these mechanisms are easy to use, require very little code, and give you
+the flexibility you need, there's really no way for AutoValue to improve on
+them!
+
+## <a name="primitive_array"></a>... use a primitive array for a property value?
+
+Go right ahead! AutoValue will generate code that acts on the *values* stored
+the array, not the object identity of the array itself, which is (with virtual
+certainty) what you want. Heed the warnings given above about [mutable
+properties](#mutable_property).
+
+## <a name="object_array"></a>... use an object array for a property value?
+
+This is not allowed. Object arrays are very badly-behaved and unlike primitive
+arrays, they can be replaced with a proper `List` implementation for very little
+added cost.
+
+
+If it's important to accept an object array at construction time, refer to the
+*first* example shown [here](#mutable_property).
+
+## <a name="inherit"></a>... have one `@AutoValue` class extend another?
+
+This ability is intentionally not supported, because there is no way to do it
+correctly. See *Effective Java, 2nd Edition* Item 8: "Obey the general contract
+when overriding equals".
+
+## <a name="private_accessors"></a>... keep my accessor methods private?
+
+We're sorry. This is one of the rare and unfortunate restrictions AutoValue's
+approach places on your API. Your accessor methods don't have to be *public*,
+but they must be at least package-visible.
+
+## <a name="public_constructor"></a>... expose a constructor, not factory method, as my public creation API?
+
+We're sorry. This is one of the rare restrictions AutoValue's approach places on
+your API. However, note that static factory methods are recommended over public
+constructors by *Effective Java*, Item 1.
+
+## <a name="interface"></a>... use AutoValue on an interface, not abstract class?
+
+AutoValue classes can certainly implement an interface, however an interface may
+not be used in lieu of an abstract class. The only advantage of interfaces we're
+aware of is that you can omit `public abstract` from the methods. That's not
+much. On the other hand, you would lose the immutability guarantee, and you'd
+also invite more of the kind of bad behavior described in
+[this best-practices item](practices.md#simple). On balance, we don't think it's
+worth it.
+
+## <a name="memoize"></a>... memoize ("cache") derived properties?
+
+Sometimes your class has properties that are derived from the ones that
+AutoValue implements. You'd typically implement them with a concrete method that
+uses the other properties:
+
+```java
+@AutoValue
+abstract class Foo {
+  abstract Bar barProperty();
+
+  String derivedProperty() {
+    return someFunctionOf(barProperty());
+  }
+}
+```
+
+But what if `someFunctionOf(Bar)` is expensive? You'd like to calculate it only
+one time, then cache and reuse that value for all future calls. Normally,
+thread-safe lazy initialization involves a lot of tricky boilerplate.
+
+Instead, just write the derived-property accessor method as above, and
+annotate it with [`@Memoized`]. Then AutoValue will override that method to
+return a stored value after the first call:
+
+```java
+@AutoValue
+abstract class Foo {
+  abstract Bar barProperty();
+
+  @Memoized
+  String derivedProperty() {
+    return someFunctionOf(barProperty());
+  }
+}
+```
+
+Then your method will be called at most once, even if multiple threads attempt
+to access the property concurrently.
+
+The annotated method must have the usual form of an accessor method, and may not
+be `abstract`, `final`, or `private`.
+
+The stored value will not be used in the implementation of `equals`, `hashCode`,
+or `toString`.
+
+If a `@Memoized` method is also annotated with `@Nullable`, then `null` values
+will be stored; if not, then the overriding method throws `NullPointerException`
+when the annotated method returns `null`.
+
+[`@Memoized`]: https://github.com/google/auto/blob/master/value/src/main/java/com/google/auto/value/extension/memoized/Memoized.java
+
+## <a name="memoize_hash_tostring"></a>... memoize the result of `hashCode` or `toString`?
+
+You can also make your class remember and reuse the result of `hashCode`,
+`toString`, or both, like this:
+
+```java
+@AutoValue
+abstract class Foo {
+  abstract Bar barProperty();
+
+  @Memoized
+  @Override
+  public abstract int hashCode();
+
+  @Memoized
+  @Override
+  public abstract String toString();
+}
+```
+
+## <a name="oneof"></a>... make a class where only one of its properties is ever set?
+
+Often, the best way to do this is using inheritance. Although one
+`@AutoValue` class can't inherit from another, two `@AutoValue` classes can
+inherit from a common parent.
+
+```java
+public abstract class StringOrInteger {
+  public abstract String representation();
+
+  public static StringOrInteger ofString(String s) {
+    return new AutoValue_StringOrInteger_StringValue(s);
+  }
+
+  public static StringOrInteger ofInteger(int i) {
+    return new AutoValue_StringOrInteger_IntegerValue(i);
+  }
+
+  @AutoValue
+  abstract class StringValue extends StringOrInteger {
+    abstract String string();
+
+    @Override
+    public String representation() {
+      return '"' + string() + '"';
+    }
+  }
+
+  @AutoValue
+  abstract class IntegerValue extends StringOrInteger {
+    abstract int integer();
+
+    @Override
+    public String representation() {
+      return Integer.toString(integer());
+    }
+  }
+}
+```
+
+So any `StringOrInteger` instance is actually either a `StringValue` or an
+`IntegerValue`. Clients only care about the `representation()` method, so they
+don't need to know which it is.
+
+But if clients of your class may want to take different actions depending on
+which property is set, there is an alternative to `@AutoValue` called
+`@AutoOneOf`. This effectively creates a
+[*tagged union*](https://en.wikipedia.org/wiki/Tagged_union).
+Here is `StringOrInteger` written using `@AutoOneOf`, with the
+`representation()` method moved to a separate client class:
+
+```java
+@AutoOneOf(StringOrInteger.Kind.class)
+public abstract class StringOrInteger {
+  public enum Kind {STRING, INTEGER}
+  public abstract Kind getKind();
+
+  public abstract String string();
+
+  public abstract int integer();
+
+  public static StringOrInteger ofString(String s) {
+    return AutoOneOf_StringOrInteger.string(s);
+  }
+
+  public static StringOrInteger ofInteger(int i) {
+    return AutoOneOf_StringOrInteger.integer(i);
+  }
+}
+
+public class Client {
+  public String representation(StringOrInteger stringOrInteger) {
+    switch (stringOrInteger.getKind()) {
+      case STRING:
+        return '"' + stringOrInteger.string() + '"';
+      case INTEGER:
+        return Integer.toString(stringOrInteger.integer());
+    }
+    throw new AssertionError(stringOrInteger.getKind());
+  }
+}
+```
+
+Switching on an enum like this can lead to more robust code than using
+`instanceof` checks, especially if a tool like [Error
+Prone](https://errorprone.info/bugpattern/MissingCasesInEnumSwitch) can alert you
+if you add a new variant without updating all your switches. (On the other hand,
+if nothing outside your class references `getKind()`, you should consider if a
+solution using inheritance might be better.)
+
+There must be an enum such as `Kind`, though it doesn't have to be called `Kind`
+and it doesn't have to be nested inside the `@AutoOneOf` class. There must be an
+abstract method returning the enum, though it doesn't have to be called
+`getKind()`. For every value of the enum, there must be an abstract method with
+the same name (ignoring case and underscores). An `@AutoOneOf` class called
+`Foo` will then get a generated class called `AutoOneOf_Foo` that has a static
+factory method for each property, with the same name. In the example, the
+`STRING` value in the enum corresponds to the `string()` property and to the
+`AutoOneOf_StringOrInteger.string` factory method.
+
+Properties in an `@AutoOneOf` class can be `void` to indicate that the
+corresponding variant has no data. In that case, the factory method for that
+variant has no parameters:
+
+```java
+@AutoOneOf(Transform.Kind.class)
+public abstract class Transform {
+  public enum Kind {NONE, CIRCLE_CROP, BLUR}
+  public abstract Kind getKind();
+
+  abstract void none();
+
+  abstract void circleCrop();
+
+  public abstract BlurTransformParameters blur();
+
+  public static Transform ofNone() {
+    return AutoOneOf_Transform.none();
+  }
+
+  public static Transform ofCircleCrop() {
+    return AutoOneOf_Transform.circleCrop();
+  }
+
+  public static Transform ofBlur(BlurTransformParmeters params) {
+    return AutoOneOf_Transform.blur(params);
+  }
+}
+```
+
+Here, the `NONE` and `CIRCLE_CROP` variants have no associated data but are
+distinct from each other. The `BLUR` variant does have data. The `none()`
+and `circleCrop()` methods are package-private; they must exist to configure
+`@AutoOneOf`, but calling them is not very useful. (It does nothing if the
+instance is of the correct variant, or throws an exception otherwise.)
+
+The `AutoOneOf_Transform.none()` and `AutoOneOf_Transform.circleCrop()` methods
+return the same instance every time they are called.
+
+If one of the `void` variants means "none", consider using an `Optional<Transform>` or
+a `@Nullable Transform` instead of that variant.
+
+Properties in an `@AutoOneOf` class cannot be null. Instead of a
+`StringOrInteger` with a `@Nullable String`, you probably want a
+`@Nullable StringOrInteger` or an `Optional<StringOrInteger>`, or an empty
+variant as just described.
+
+## <a name="copy_annotations"></a>... copy annotations from a class/method to the implemented class/method/field?
+
+### Copying to the generated class
+
+If you want to copy annotations from your `@AutoValue`-annotated class to the
+generated `AutoValue_...` implemention, annotate your class with
+[`@AutoValue.CopyAnnotations`].
+
+For example, if `Example.java` is:
+
+```java
+@AutoValue
+@AutoValue.CopyAnnotations
+@SuppressWarnings("Immutable") // justification ...
+abstract class Example {
+  // details ...
+}
+```
+
+Then `@AutoValue` will generate `AutoValue_Example.java`:
+
+```java
+@SuppressWarnings("Immutable")
+final class AutoValue_Example extends Example {
+  // implementation ...
+}
+```
+
+Applying `@AutoValue.CopyAnnotations` to an `@AutoValue.Builder` class like
+`Foo.Builder` similarly causes annotations on that class to be copied to the
+generated subclass `AutoValue_Foo.Builder`.
+
+### Copying to the generated method
+
+For historical reasons, annotations on methods of an `@AutoValue`-annotated
+class are copied to the generated implementation class's methods. However, if
+you want to exclude some annotations from being copied, you can use
+[`@AutoValue.CopyAnnotations`]'s `exclude` method to stop this behavior.
+
+### Copying to the generated field
+
+If you want to copy annotations from your `@AutoValue`-annotated class's methods
+to the generated fields in the `AutoValue_...` implementation, annotate your
+method with [`@AutoValue.CopyAnnotations`].
+
+For example, if `Example.java` is:
+
+```java
+@Immutable
+@AutoValue
+abstract class Example {
+  @CopyAnnotations
+  @SuppressWarnings("Immutable") // justification ...
+  abstract Object getObject();
+
+  // other details ...
+}
+```
+
+Then `@AutoValue` will generate `AutoValue_Example.java`:
+
+```java
+final class AutoValue_Example extends Example {
+  @SuppressWarnings("Immutable")
+  private final Object object;
+
+  @SuppressWarnings("Immutable")
+  @Override
+  Object getObject() {
+    return object;
+  }
+
+  // other details ...
+}
+```
+
+[`@AutoValue.CopyAnnotations`]: http://static.javadoc.io/com.google.auto.value/auto-value/1.6/com/google/auto/value/AutoValue.CopyAnnotations.html
+
diff --git a/value/userguide/index.md b/value/userguide/index.md
new file mode 100644
index 0000000..8cbe75f
--- /dev/null
+++ b/value/userguide/index.md
@@ -0,0 +1,271 @@
+# AutoValue
+
+
+*Generated immutable value classes for Java 7+* <br />
+***Éamonn McManus, Kevin Bourrillion*** <br />
+**Google, Inc.**
+
+> "AutoValue is a great tool for eliminating the drudgery of writing mundane
+> value classes in Java. It encapsulates much of the advice in Effective Java
+> Chapter 2, and frees you to concentrate on the more interesting aspects of
+> your program. The resulting program is likely to be shorter, clearer, and
+> freer of bugs. Two thumbs up."
+>
+> -- *Joshua Bloch, author, Effective Java*
+
+
+## <a name="background"></a>Background
+
+**Value classes** are extremely common in Java projects. These are classes for
+which you want to treat any two instances with suitably equal field values as
+interchangeable. That's right: we're talking about those classes where you wind
+up implementing `equals`, `hashCode` and `toString` in a bloated, repetitive,
+formulaic yet error-prone fashion.
+
+Writing these methods the first time is not too bad, with the aid of a few
+helper methods and IDE templates. But once written they continue to burden
+reviewers, editors and future readers. Their wide expanses of boilerplate
+sharply decrease the signal-to-noise ratio of your code... and they love to
+harbor hard-to-spot bugs.
+
+AutoValue provides an easier way to create immutable value classes, with a lot
+less code and less room for error, while **not restricting your freedom** to
+code almost any aspect of your class exactly the way you want it.
+
+This page will walk you through how to use AutoValue. Looking for a little more
+persuasion? Please see [Why AutoValue?](why.md).
+
+## <a name="howto"></a>How to use AutoValue
+
+The AutoValue concept is extremely simple: **You write an abstract class, and
+AutoValue implements it.** That is all there is to it; there is literally *no*
+configuration.
+
+**Note:** Below, we will illustrate an AutoValue class *without* a generated
+builder class. If you're more interested in the builder support, continue
+reading at [AutoValue with Builders](builders.md) instead.
+
+### <a name="example_java"></a>In your value class
+
+Create your value class as an *abstract* class, with an abstract accessor method
+for each desired property, and bearing the `@AutoValue` annotation.
+
+```java
+import com.google.auto.value.AutoValue;
+
+@AutoValue
+abstract class Animal {
+  static Animal create(String name, int numberOfLegs) {
+    return new AutoValue_Animal(name, numberOfLegs);
+  }
+
+  abstract String name();
+  abstract int numberOfLegs();
+}
+```
+
+The constructor parameters correspond, in order, to the abstract accessor
+methods.
+
+**For a nested class**, see ["How do I use AutoValue with a nested class"](howto.md#nested).
+
+Note that in real life, some classes and methods would presumably be public and
+have Javadoc. We're leaving these off in the User Guide only to keep the
+examples short and simple.
+
+
+### With Maven
+
+You will need `auto-value-annotations-${auto-value.version}.jar` in your
+compile-time classpath, and you will need `auto-value-${auto-value.version}.jar`
+in your annotation-processor classpath.
+
+For `auto-value-annotations`, you can write this in `pom.xml`:
+
+```xml
+<dependencies>
+  <dependency>
+    <groupId>com.google.auto.value</groupId>
+    <artifactId>auto-value-annotations</artifactId>
+    <version>${auto-value.version}</version>
+  </dependency>
+</dependencies>
+```
+
+For `auto-value` (the annotation processor), you can write this:
+
+```xml
+<build>
+  <plugins>
+    <plugin>
+      <artifactId>maven-compiler-plugin</artifactId>
+      <configuration>
+        <annotationProcessorPaths>
+          <path>
+            <groupId>com.google.auto.value</groupId>
+            <artifactId>auto-value</artifactId>
+            <version>${auto-value.version}</version>
+          </path>
+        </annotationProcessorPaths>
+      </configuration>
+    </plugin>
+  </plugins>
+</build>
+```
+
+Alternatively, you can include the processor itself in your compile-time
+classpath. Doing so may pull unnecessary classes into your runtime classpath.
+
+```xml
+<dependencies>
+  <dependency>
+    <groupId>com.google.auto.value</groupId>
+    <artifactId>auto-value</artifactId>
+    <version>${auto-value.version}</version>
+    <optional>true</optional>
+  </dependency>
+</dependencies>
+```
+
+### With Gradle
+
+Gradle users can declare the dependencies in their `build.gradle` script:
+
+```groovy
+dependencies {
+  // Use 'api' rather than 'compile' for Android or java-library projects.
+  compile             "com.google.auto.value:auto-value-annotations:${autoValueVersion}"
+  annotationProcessor "com.google.auto.value:auto-value:${autoValueVersion}"
+}
+```
+
+Note: If you are using a version of Gradle prior to 4.6, you must apply an
+annotation processing plugin [as described in these instructions][tbroyer-apt].
+
+[tbroyer-apt]: https://plugins.gradle.org/plugin/net.ltgt.apt
+
+
+### <a name="usage"></a>Usage
+
+Your choice to use AutoValue is essentially *API-invisible*. This means that, to
+the consumer of your class, your class looks and functions like any other. The
+simple test below illustrates that behavior. Note that in real life, you would
+write tests that actually *do something interesting* with the object, instead of
+only checking field values going in and out.
+
+```java
+public void testAnimal() {
+  Animal dog = Animal.create("dog", 4);
+  assertEquals("dog", dog.name());
+  assertEquals(4, dog.numberOfLegs());
+
+  // You probably don't need to write assertions like these; just illustrating.
+  assertTrue(Animal.create("dog", 4).equals(dog));
+  assertFalse(Animal.create("cat", 4).equals(dog));
+  assertFalse(Animal.create("dog", 2).equals(dog));
+
+  assertEquals("Animal{name=dog, numberOfLegs=4}", dog.toString());
+}
+```
+
+### <a name="whats_going_on"></a>What's going on here?
+
+AutoValue runs inside `javac` as a standard annotation processor. It reads your
+abstract class and infers what the implementation class should look like. It
+generates source code, in your package, of a concrete implementation class
+which extends your abstract class, having:
+
+*   package visibility (non-public)
+*   one field for each of your abstract accessor methods
+*   a constructor that sets these fields
+*   a concrete implementation of each accessor method returning the associated
+    field value
+*   an `equals` implementation that compares these values in the usual way
+*   an appropriate corresponding `hashCode`
+*   a `toString` implementation returning a useful (but unspecified) string
+    representation of the instance
+
+Your hand-written code, as shown above, delegates its factory method call to the
+generated constructor and voilà!
+
+For the `Animal` example shown above, here is [typical code AutoValue might
+generate](generated-example.md).
+
+Note that *consumers* of your value class *don't need to know any of this*. They
+just invoke your provided factory method and get a well-behaved instance back.
+
+## <a name="warnings"></a>Warnings
+
+Be careful that you don't accidentally pass parameters to the generated
+constructor in the wrong order. You must ensure that **your tests are
+sufficient** to catch any field ordering problem. In most cases this should be
+the natural outcome from testing whatever actual purpose this value class was
+created for! In other cases a very simple test like the one shown above is
+enough. Consider switching to use the [builder option](builders.md) to avoid
+this problem.
+
+We reserve the right to **change the `hashCode` implementation** at any time.
+Never persist the result of `hashCode` or use it for any other unintended
+purpose, and be careful never to depend on the order your values appear in
+unordered collections like `HashSet`.
+
+## <a name="why"></a>Why should I use AutoValue?
+
+See [Why AutoValue?](why.md).
+
+## <a name="versions"></a>What Java versions does it work with?
+
+AutoValue requires that your compiler be at least Java 8. However, the code that
+it generates is compatible with Java 7. That means that you can use it with
+`-source 7 -target 7` or (for Java 9+) `--release 7`.
+
+## <a name="more_howto"></a>How do I...
+
+How do I...
+
+*   ... [also generate a **builder** for my value class?](howto.md#builder)
+*   ... [use AutoValue with a **nested** class?](howto.md#nested)
+*   ... [use (or not use) JavaBeans-style name **prefixes**?](howto.md#beans)
+*   ... [use **nullable** properties?](howto.md#nullable)
+*   ... [perform other **validation**?](howto.md#validate)
+*   ... [use a property of a **mutable** type?](howto.md#mutable_property)
+*   ... [use a **custom** implementation of `equals`, etc.?](howto.md#custom)
+*   ... [have AutoValue implement a concrete or default
+    method?](howto.md#concrete)
+*   ... [have multiple **`create`** methods, or name it/them
+    differently?](howto.md#create)
+*   ... [**ignore** certain properties in `equals`, etc.?](howto.md#ignore)
+*   ... [have AutoValue also implement abstract methods from my
+    **supertypes**?](howto.md#supertypes)
+*   ... [use AutoValue with a **generic** class?](howto.md#generic)
+*   ... [make my class Java- or GWT\-**serializable**?](howto.md#serialize)
+*   ... [use AutoValue to **implement** an **annotation**
+    type?](howto.md#annotation)
+*   ... [also include **setter** (mutator) methods?](howto.md#setters)
+*   ... [also generate **`compareTo`**?](howto.md#compareTo)
+*   ... [use a **primitive array** for a property
+    value?](howto.md#primitive_array)
+*   ... [use an **object array** for a property value?](howto.md#object_array)
+*   ... [have one `@AutoValue` class **extend** another?](howto.md#inherit)
+*   ... [keep my accessor methods **private**?](howto.md#private_accessors)
+*   ... [expose a **constructor**, not factory method, as my public creation
+    API?](howto.md#public_constructor)
+*   ... [use AutoValue on an **interface**, not abstract
+    class?](howto.md#interface)
+*   ... [**memoize** ("cache") derived properties?](howto.md#memoize)
+*   ... [memoize the result of `hashCode` or
+    `toString`?](howto.md#memoize_hash_tostring)
+*   ... [make a class where only one of its properties is ever
+    set?](howto.md#oneof)
+*   ... [copy annotations from a class/method to the implemented
+    class/method/field?](howto.md#copy_annotations)
+
+<!-- TODO(kevinb): should the above be only a selected subset? -->
+
+## <a name="more"></a>More information
+
+See the links in the sidebar at the top left.
+
+<!-- TODO(kevinb): there are some tidbits of information that don't seem to
+     belong anywhere yet; such as how it implements floating-point equality -->
+
diff --git a/value/userguide/performance.md b/value/userguide/performance.md
new file mode 100644
index 0000000..ee7a8fc
--- /dev/null
+++ b/value/userguide/performance.md
@@ -0,0 +1,9 @@
+# Performance notes
+
+
+TODO: write a real page
+
+*   should perform like a hand-written class after HotSpot compiles it
+    (generated accessors can be inlined)
+*   what does proguard do with it
+*   hash codes are not cached
diff --git a/value/userguide/practices.md b/value/userguide/practices.md
new file mode 100644
index 0000000..0121bd8
--- /dev/null
+++ b/value/userguide/practices.md
@@ -0,0 +1,64 @@
+# Best practices
+
+
+
+## <a name="interchangeable"></a>"Equals means interchangeable"
+
+Don't use AutoValue to implement value semantics unless you really want value
+semantics. In particular, you should never care about the difference between two
+equal instances.
+
+## <a name="mutable_properties"></a>Avoid mutable property types
+
+Avoid mutable types, including arrays, for your properties, especially if you
+make your accessor methods `public`. The generated accessors don't copy the
+field value on its way out, so you'd be exposing your internal state.
+
+Note that this doesn't mean your factory method can't *accept* mutable types as
+input parameters. Example:
+
+```java
+@AutoValue
+public abstract class ListExample {
+  abstract ImmutableList<String> names();
+
+  public static ListExample create(List<String> mutableNames) {
+    return new AutoValue_ListExample(ImmutableList.copyOf(mutableNames));
+  }
+}
+```
+
+## <a name="simple"></a>Keep behavior simple and dependency-free
+
+Your class can (and should) contain *simple* intrinsic behavior. But it
+shouldn't require complex dependencies and shouldn't access static state.
+
+You should essentially *never* need an alternative implementation of your
+hand-written abstract class, whether hand-written or generated by a mocking
+framework. If your behavior has enough complexity (or dependencies) that it
+actually needs to be mocked or faked, split it into a separate type that is
+*not* a value type. Otherwise it permits an instance with "real" behavior and
+one with "mock/fake" behavior to be `equals`, which does not make sense.
+
+## <a name="one_reference"></a>One reference only
+
+Other code in the same package will be able to directly access the generated
+class, but *should not*. It's best if each generated class has one and only one
+reference from your source code: the call from your static factory method to the
+generated constructor. If you have multiple factory methods, have them all
+delegate to the same hand-written method, so there is still only one point of
+contact with the generated code. This way, you have only one place to insert
+precondition checks or other pre- or postprocessing.
+
+## <a name="final"></a>Mark all concrete methods `final`
+
+Consider that other developers will try to read and understand your value class
+while looking only at your hand-written class, not the actual (generated)
+implementation class. If you mark your concrete methods `final`, they won't have
+to wonder whether the generated subclass might be overriding them. This is
+especially helpful if you are *[underriding](howto.md#custom)* `equals`,
+`hashCode` or `toString`!
+
+## <a name="constructor"></a>Maybe add an explicit, inaccessible constructor
+
+There are a few small advantages to adding a package-private, parameterless constructor to your abstract class. It prevents unwanted subclasses, and prevents an undocumented public constructor showing up in your generated API documentation. Whether these benefits are worth the extra noise in the file is a matter of your judgment.
diff --git a/value/userguide/trouble.md b/value/userguide/trouble.md
new file mode 100644
index 0000000..162041f
--- /dev/null
+++ b/value/userguide/trouble.md
@@ -0,0 +1,12 @@
+# Troubleshooting
+
+
+TODO
+
+## `equals()` is not returning what I expect
+
+This is usually a sign that one of your field types is not implementing `equals`
+as you expect. A typical offending class is [`JSONObject`]
+(https://developer.android.com/reference/org/json/JSONObject.html), which
+doesn't override `Object.equals()` and thus compromises your class's `equals`
+behavior as well.
diff --git a/value/userguide/why.md b/value/userguide/why.md
new file mode 100644
index 0000000..603abb8
--- /dev/null
+++ b/value/userguide/why.md
@@ -0,0 +1,19 @@
+# Why use AutoValue?
+
+
+AutoValue is the only solution to the value class problem in Java having all of
+the following characteristics:
+
+*   **API-invisible** (callers cannot become dependent on your choice to use it)
+*   No runtime dependencies
+*   Negligible cost to performance
+*   Very few limitations on what your class can do
+*   Extralinguistic "magic" kept to an absolute minimum (uses only standard Java
+    platform technologies, in the manner they were intended)
+
+This
+[slide presentation] compares AutoValue to numerous alternatives and explains
+why we think it is better.
+
+
+[slide presentation]: https://docs.google.com/presentation/d/14u_h-lMn7f1rXE1nDiLX0azS3IkgjGl5uxp5jGJ75RE/edit
