diff --git a/java/com/google/devtools/build/android/desugar/ClassReaderFactory.java b/java/com/google/devtools/build/android/desugar/ClassReaderFactory.java
index 56f99a3..2b44d76 100644
--- a/java/com/google/devtools/build/android/desugar/ClassReaderFactory.java
+++ b/java/com/google/devtools/build/android/desugar/ClassReaderFactory.java
@@ -15,19 +15,16 @@
 
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
 import javax.annotation.Nullable;
 import org.objectweb.asm.ClassReader;
 
 class ClassReaderFactory {
-  private final IndexedJars indexedJars;
+  private final IndexedInputs indexedInputs;
   private final CoreLibraryRewriter rewriter;
 
-  public ClassReaderFactory(IndexedJars indexedJars, CoreLibraryRewriter rewriter) {
+  public ClassReaderFactory(IndexedInputs indexedInputs, CoreLibraryRewriter rewriter) {
     this.rewriter = rewriter;
-    this.indexedJars = indexedJars;
+    this.indexedInputs = indexedInputs;
   }
 
   /**
@@ -38,23 +35,19 @@
   @Nullable
   public ClassReader readIfKnown(String internalClassName) {
     String filename = rewriter.unprefix(internalClassName) + ".class";
-    JarFile jarFile = indexedJars.getJarFile(filename);
+    InputFileProvider inputFileProvider = indexedInputs.getInputFileProvider(filename);
 
-    if (jarFile != null) {
-      return getClassReader(internalClassName, jarFile, jarFile.getEntry(filename));
+    if (inputFileProvider != null) {
+      try (InputStream bytecode = inputFileProvider.getInputStream(filename)) {
+        // ClassReader doesn't take ownership and instead eagerly reads the stream's contents
+        return rewriter.reader(bytecode);
+      } catch (IOException e) {
+        // We should've already read through all files in the Jar once at this point, so we don't
+        // expect failures reading some files a second time.
+        throw new IllegalStateException("Couldn't load " + internalClassName, e);
+      }
     }
 
     return null;
   }
-
-  private ClassReader getClassReader(String internalClassName, ZipFile jar, ZipEntry entry) {
-    try (InputStream bytecode = jar.getInputStream(entry)) {
-      // ClassReader doesn't take ownership and instead eagerly reads the stream's contents
-      return rewriter.reader(bytecode);
-    } catch (IOException e) {
-      // We should've already read through all files in the Jar once at this point, so we don't
-      // expect failures reading some files a second time.
-      throw new IllegalStateException("Couldn't load " + internalClassName, e);
-    }
-  }
 }
diff --git a/java/com/google/devtools/build/android/desugar/Desugar.java b/java/com/google/devtools/build/android/desugar/Desugar.java
index 6f9e0f0..22780ea 100644
--- a/java/com/google/devtools/build/android/desugar/Desugar.java
+++ b/java/com/google/devtools/build/android/desugar/Desugar.java
@@ -18,14 +18,14 @@
 
 import com.google.auto.value.AutoValue;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.io.ByteStreams;
+import com.google.common.io.Closer;
 import com.google.devtools.build.android.Converters.ExistingPathConverter;
 import com.google.devtools.build.android.Converters.PathConverter;
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionsBase;
 import com.google.devtools.common.options.OptionsParser;
-import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.FileVisitResult;
@@ -34,14 +34,9 @@
 import java.nio.file.Paths;
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
-import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.zip.CRC32;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipOutputStream;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.ClassWriter;
@@ -62,8 +57,8 @@
       converter = ExistingPathConverter.class,
       abbrev = 'i',
       help =
-          "Input Jar with classes to desugar (required, the n-th input is paired with the n-th "
-              + "output)."
+        "Input Jar or directory with classes to desugar (required, the n-th input is paired with"
+        + "the n-th output)."
     )
     public List<Path> inputJars;
 
@@ -96,6 +91,15 @@
     public boolean allowEmptyBootclasspath;
 
     @Option(
+      name = "only_desugar_javac9_for_lint",
+      defaultValue = "false",
+      help =
+          "A temporary flag specifically for android lint, subject to removal anytime (DO NOT USE)",
+      category = "undocumented"
+    )
+    public boolean onlyDesugarJavac9ForLint;
+
+    @Option(
       name = "output",
       allowMultiple = true,
       defaultValue = "",
@@ -103,8 +107,8 @@
       converter = PathConverter.class,
       abbrev = 'o',
       help =
-          "Output Jar to write desugared classes into (required, the n-th output is paired with "
-              + "the n-th input)."
+          "Output Jar or directory to write desugared classes into (required, the n-th output is "
+              + "paired with the n-th input, output must be a Jar if input is a Jar)."
     )
     public List<Path> outputJars;
 
@@ -171,7 +175,12 @@
         "Desugar requires the same number of inputs and outputs to pair them");
     checkState(!options.bootclasspath.isEmpty() || options.allowEmptyBootclasspath,
         "At least one --bootclasspath_entry is required");
-
+    for (Path path : options.classpath) {
+      checkState(!Files.isDirectory(path), "Classpath entry must be a jar file: %s", path);
+    }
+    for (Path path : options.bootclasspath) {
+      checkState(!Files.isDirectory(path), "Bootclasspath entry must be a jar file: %s", path);
+    }
     if (options.verbose) {
       System.out.printf("Lambda classes will be written under %s%n", dumpDirectory);
     }
@@ -186,72 +195,86 @@
 
     // Process each input separately
     for (InputOutputPair inputOutputPair : toInputOutputPairs(options)) {
-      Path inputJar = inputOutputPair.getInput();
-      IndexedJars appIndexedJar = new IndexedJars(ImmutableList.of(inputJar));
-      IndexedJars appAndClasspathIndexedJars = new IndexedJars(options.classpath, appIndexedJar);
-      ClassLoader loader =
-          createClassLoader(rewriter, options.bootclasspath, appAndClasspathIndexedJars);
+      Path inputPath = inputOutputPair.getInput();
+      Path outputPath = inputOutputPair.getOutput();
+      checkState(
+          Files.isDirectory(inputPath) || !Files.isDirectory(outputPath),
+          "Input jar file requires an output jar file");
+      
+      try (Closer closer = Closer.create();
+          OutputFileProvider outputFileProvider = toOutputFileProvider(outputPath)) {
+        InputFileProvider appInputFiles = toInputFileProvider(closer, inputPath);
+        List<InputFileProvider> classpathInputFiles =
+            toInputFileProvider(closer, options.classpath);
+        IndexedInputs appIndexedInputs = new IndexedInputs(ImmutableList.of(appInputFiles));
+        IndexedInputs appAndClasspathIndexedInputs =
+            new IndexedInputs(classpathInputFiles, appIndexedInputs);
+        ClassLoader loader =
+            createClassLoader(
+                rewriter,
+                toInputFileProvider(closer, options.bootclasspath),
+                appAndClasspathIndexedInputs);
 
-      try (ZipFile in = new ZipFile(inputJar.toFile());
-          ZipOutputStream out =
-              new ZipOutputStream(
-                  new BufferedOutputStream(Files.newOutputStream(inputOutputPair.getOutput())))) {
         ClassReaderFactory readerFactory =
             new ClassReaderFactory(
                 (options.copyBridgesFromClasspath && !allowDefaultMethods)
-                    ? appAndClasspathIndexedJars
-                    : appIndexedJar,
+                    ? appAndClasspathIndexedInputs
+                    : appIndexedInputs,
                 rewriter);
 
         ImmutableSet.Builder<String> interfaceLambdaMethodCollector = ImmutableSet.builder();
 
-        // Process input Jar, desugaring as we go
-        for (Enumeration<? extends ZipEntry> entries = in.entries(); entries.hasMoreElements(); ) {
-          ZipEntry entry = entries.nextElement();
-          try (InputStream content = in.getInputStream(entry)) {
-            // We can write classes uncompressed since they need to be converted to .dex format for
-            // Android anyways. Resources are written as they were in the input jar to avoid any
-            // danger of accidentally uncompressed resources ending up in an .apk.
-            if (entry.getName().endsWith(".class")) {
+        // Process inputs, desugaring as we go
+        for (String filename : appInputFiles) {
+          try (InputStream content = appInputFiles.getInputStream(filename)) {
+            // We can write classes uncompressed since they need to be converted to .dex format
+            // for Android anyways. Resources are written as they were in the input jar to avoid
+            // any danger of accidentally uncompressed resources ending up in an .apk.
+            if (filename.endsWith(".class")) {
               ClassReader reader = rewriter.reader(content);
               CoreLibraryRewriter.UnprefixingClassWriter writer =
                   rewriter.writer(ClassWriter.COMPUTE_MAXS /*for bridge methods*/);
               ClassVisitor visitor = writer;
-              if (!allowDefaultMethods) {
-                visitor = new Java7Compatibility(visitor, readerFactory);
-              }
 
-              visitor =
-                  new LambdaDesugaring(
-                      visitor, loader, lambdas, interfaceLambdaMethodCollector,
-                      allowDefaultMethods);
+              if (!options.onlyDesugarJavac9ForLint) {
+                if (!allowDefaultMethods) {
+                  visitor = new Java7Compatibility(visitor, readerFactory);
+                }
+
+                visitor =
+                    new LambdaDesugaring(
+                        visitor,
+                        loader,
+                        lambdas,
+                        interfaceLambdaMethodCollector,
+                        allowDefaultMethods);
+              }
 
               if (!allowCallsToObjectsNonNull) {
                 visitor = new ObjectsRequireNonNullMethodInliner(visitor);
               }
               reader.accept(visitor, 0);
 
-              writeStoredEntry(out, entry.getName(), writer.toByteArray());
+              outputFileProvider.write(filename, writer.toByteArray());
             } else {
-              // TODO(bazel-team): Avoid de- and re-compressing resource files
-              ZipEntry destEntry = new ZipEntry(entry);
-              destEntry.setCompressedSize(-1);
-              out.putNextEntry(destEntry);
-              ByteStreams.copy(content, out);
-              out.closeEntry();
+              outputFileProvider.copyFrom(filename, appInputFiles);
             }
           }
         }
 
         ImmutableSet<String> interfaceLambdaMethods = interfaceLambdaMethodCollector.build();
-        if (allowDefaultMethods) {
-          checkState(
-              interfaceLambdaMethods.isEmpty(),
-              "Desugaring with default methods enabled moved interface lambdas");
-        }
+        checkState(
+            !allowDefaultMethods || interfaceLambdaMethods.isEmpty(),
+            "Desugaring with default methods enabled moved interface lambdas");
 
         // Write out the lambda classes we generated along the way
-        for (Map.Entry<Path, LambdaInfo> lambdaClass : lambdas.drain().entrySet()) {
+        ImmutableMap<Path, LambdaInfo> lambdaClasses = lambdas.drain();
+        checkState(
+            !options.onlyDesugarJavac9ForLint || lambdaClasses.isEmpty(),
+            "There should be no lambda classes generated: %s",
+            lambdaClasses.keySet());
+
+        for (Map.Entry<Path, LambdaInfo> lambdaClass : lambdaClasses.entrySet()) {
           try (InputStream bytecode =
               Files.newInputStream(dumpDirectory.resolve(lambdaClass.getKey()))) {
             ClassReader reader = rewriter.reader(bytecode);
@@ -282,7 +305,7 @@
             reader.accept(visitor, 0);
             String filename =
                 rewriter.unprefix(lambdaClass.getValue().desiredInternalName()) + ".class";
-            writeStoredEntry(out, filename, writer.toByteArray());
+            outputFileProvider.write(filename, writer.toByteArray());
           }
         }
 
@@ -292,7 +315,7 @@
     }
   }
 
-   private static List<InputOutputPair> toInputOutputPairs(Options options) {
+  private static List<InputOutputPair> toInputOutputPairs(Options options) {
     final ImmutableList.Builder<InputOutputPair> ioPairListbuilder = ImmutableList.builder();
     for (Iterator<Path> inputIt = options.inputJars.iterator(),
                 outputIt = options.outputJars.iterator();
@@ -302,38 +325,22 @@
     return ioPairListbuilder.build();
   }
 
-  private static void writeStoredEntry(ZipOutputStream out, String filename, byte[] content)
+  private static ClassLoader createClassLoader(
+      CoreLibraryRewriter rewriter,
+      List<InputFileProvider> bootclasspath,
+      IndexedInputs appAndClasspathIndexedInputs)
       throws IOException {
-    // Need to pre-compute checksum for STORED (uncompressed) entries)
-    CRC32 checksum = new CRC32();
-    checksum.update(content);
-
-    ZipEntry result = new ZipEntry(filename);
-    result.setTime(0L); // Use stable timestamp Jan 1 1980
-    result.setCrc(checksum.getValue());
-    result.setSize(content.length);
-    result.setCompressedSize(content.length);
-    // Write uncompressed, since this is just an intermediary artifact that we will convert to .dex
-    result.setMethod(ZipEntry.STORED);
-
-    out.putNextEntry(result);
-    out.write(content);
-    out.closeEntry();
-  }
-
-  private static ClassLoader createClassLoader(CoreLibraryRewriter rewriter,
-      List<Path> bootclasspath, IndexedJars appAndClasspathIndexedJars) throws IOException {
     // Use a classloader that as much as possible uses the provided bootclasspath instead of
     // the tool's system classloader.  Unfortunately we can't do that for java. classes.
     ClassLoader parent = new ThrowingClassLoader();
     if (!bootclasspath.isEmpty()) {
-      parent = new HeaderClassLoader(new IndexedJars(bootclasspath), rewriter, parent);
+      parent = new HeaderClassLoader(new IndexedInputs(bootclasspath), rewriter, parent);
     }
     // Prepend classpath with input jar itself so LambdaDesugaring can load classes with lambdas.
     // Note that inputJar and classpath need to be in the same classloader because we typically get
     // the header Jar for inputJar on the classpath and having the header Jar in a parent loader
     // means the header version is preferred over the real thing.
-    return new HeaderClassLoader(appAndClasspathIndexedJars, rewriter, parent);
+    return new HeaderClassLoader(appAndClasspathIndexedInputs, rewriter, parent);
   }
 
   private static class ThrowingClassLoader extends ClassLoader {
@@ -386,6 +393,36 @@
     }
   }
 
+  /** Transform a Path to an {@link OutputFileProvider} */
+  private static OutputFileProvider toOutputFileProvider(Path path)
+      throws IOException {
+    if (Files.isDirectory(path)) {
+      return new DirectoryOutputFileProvider(path);
+    } else {
+      return new ZipOutputFileProvider(path);
+    }
+  }
+
+  /** Transform a Path to an InputFileProvider and register it to close it at the end of desugar */
+  private static InputFileProvider toInputFileProvider(Closer closer, Path path)
+      throws IOException {
+    if (Files.isDirectory(path)) {
+      return closer.register(new DirectoryInputFileProvider(path));
+    } else {
+      return closer.register(new ZipInputFileProvider(path));
+    }
+  }
+
+  private static ImmutableList<InputFileProvider> toInputFileProvider(
+      Closer closer, List<Path> paths) throws IOException {
+    ImmutableList.Builder<InputFileProvider> builder = new ImmutableList.Builder<>();
+    for (Path path : paths) {
+      checkState(!Files.isDirectory(path), "Directory is not supported: %s", path);
+      builder.add(closer.register(new ZipInputFileProvider(path)));
+    }
+    return builder.build();
+  }
+  
   /**
    * Pair input and output.
    */
diff --git a/java/com/google/devtools/build/android/desugar/DirectoryInputFileProvider.java b/java/com/google/devtools/build/android/desugar/DirectoryInputFileProvider.java
new file mode 100644
index 0000000..1c5abc9
--- /dev/null
+++ b/java/com/google/devtools/build/android/desugar/DirectoryInputFileProvider.java
@@ -0,0 +1,81 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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.devtools.build.android.desugar;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOError;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+import java.util.zip.ZipEntry;
+
+/** Input provider is a directory. */
+class DirectoryInputFileProvider implements InputFileProvider {
+
+  private final Path root;
+
+  public DirectoryInputFileProvider(Path root) {
+    this.root = root;
+  }
+
+  @Override
+  public String toString() {
+    return root.getFileName().toString();
+  }
+
+  @Override
+  public InputStream getInputStream(String filename) throws IOException {
+    return new FileInputStream(root.resolve(filename).toFile());
+  }
+
+  @Override
+  public ZipEntry getZipEntry(String filename) {
+    ZipEntry destEntry = new ZipEntry(filename);
+    destEntry.setTime(0L); // Use stable timestamp Jan 1 1980
+    return destEntry;
+  }
+
+  @Override
+  public void close() throws IOException {
+    // Nothing to close
+  }
+
+  @Override
+  public Iterator<String> iterator() {
+    final List<String> entries = new ArrayList<>();
+    try (Stream<Path> paths = Files.walk(root)) {
+      paths.forEach(
+          new Consumer<Path>() {
+            @Override
+            public void accept(Path t) {
+              if (Files.isRegularFile(t)) {
+                // Internally, we use '/' as a common package separator in filename to abstract
+                // that filename can comes from a zip or a directory.
+                entries.add(root.relativize(t).toString().replace(File.separatorChar, '/'));
+              }
+            }
+          });
+    } catch (IOException e) {
+      throw new IOError(e);
+    }
+    return entries.iterator();
+  }
+}
diff --git a/java/com/google/devtools/build/android/desugar/DirectoryOutputFileProvider.java b/java/com/google/devtools/build/android/desugar/DirectoryOutputFileProvider.java
new file mode 100644
index 0000000..782a81e
--- /dev/null
+++ b/java/com/google/devtools/build/android/desugar/DirectoryOutputFileProvider.java
@@ -0,0 +1,59 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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.devtools.build.android.desugar;
+
+import com.google.common.io.ByteStreams;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+/** Output provider is a directory. */
+public class DirectoryOutputFileProvider implements OutputFileProvider {
+
+  private final Path root;
+
+  public DirectoryOutputFileProvider(Path root) {
+    this.root = root;
+  }
+
+  @Override
+  public void copyFrom(String filename, InputFileProvider inputFileProvider) throws IOException {
+    Path path = root.resolve(filename);
+    createParentFolder(path);
+    try (InputStream is = inputFileProvider.getInputStream(filename);
+        OutputStream os = Files.newOutputStream(path)) {
+      ByteStreams.copy(is, os);
+    }
+  }
+
+  @Override
+  public void write(String filename, byte[] content) throws IOException {
+    Path path = root.resolve(filename);
+    createParentFolder(path);
+    Files.write(path, content);
+  }
+
+  @Override
+  public void close() {
+    // Nothing to close
+  }
+
+  private void createParentFolder(Path path) throws IOException {
+    if (!Files.exists(path.getParent())) {
+      Files.createDirectories(path.getParent());
+    }
+  }
+}
diff --git a/java/com/google/devtools/build/android/desugar/HeaderClassLoader.java b/java/com/google/devtools/build/android/desugar/HeaderClassLoader.java
index 44c3932..154b793 100644
--- a/java/com/google/devtools/build/android/desugar/HeaderClassLoader.java
+++ b/java/com/google/devtools/build/android/desugar/HeaderClassLoader.java
@@ -16,8 +16,6 @@
 import java.io.IOError;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
 import org.objectweb.asm.ClassReader;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.ClassWriter;
@@ -35,26 +33,25 @@
  */
 class HeaderClassLoader extends ClassLoader {
 
-  private final IndexedJars indexedJars;
+  private final IndexedInputs indexedInputs;
   private final CoreLibraryRewriter rewriter;
 
   public HeaderClassLoader(
-      IndexedJars indexedJars, CoreLibraryRewriter rewriter, ClassLoader parent) {
+      IndexedInputs indexedInputs, CoreLibraryRewriter rewriter, ClassLoader parent) {
     super(parent);
     this.rewriter = rewriter;
-    this.indexedJars = indexedJars;
+    this.indexedInputs = indexedInputs;
   }
 
   @Override
   protected Class<?> findClass(String name) throws ClassNotFoundException {
     String filename = rewriter.unprefix(name.replace('.', '/') + ".class");
-    JarFile jarfile = indexedJars.getJarFile(filename);
-    if (jarfile == null) {
-      throw new ClassNotFoundException();
+    InputFileProvider inputFileProvider = indexedInputs.getInputFileProvider(filename);
+    if (inputFileProvider == null) {
+      throw new ClassNotFoundException("Class " + name + " not found");
     }
-    ZipEntry entry = jarfile.getEntry(filename);
     byte[] bytecode;
-    try (InputStream content = jarfile.getInputStream(entry)) {
+    try (InputStream content = inputFileProvider.getInputStream(filename)) {
       ClassReader reader = rewriter.reader(content);
       // Have ASM compute maxs so we don't need to figure out how many formal parameters there are
       ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
diff --git a/java/com/google/devtools/build/android/desugar/IndexedInputs.java b/java/com/google/devtools/build/android/desugar/IndexedInputs.java
new file mode 100644
index 0000000..58459cc
--- /dev/null
+++ b/java/com/google/devtools/build/android/desugar/IndexedInputs.java
@@ -0,0 +1,75 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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.devtools.build.android.desugar;
+
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nullable;
+
+/**
+ * Opens the given list of input files and compute an index of all classes in them, to avoid
+ * scanning all inputs over and over for each class to load. An indexed inputs can have a parent
+ * that is firstly used when a file name is searched.
+ */
+class IndexedInputs {
+
+  private final Map<String, InputFileProvider> inputFiles = new HashMap<>();
+
+  /** Parent indexed inputs to use before to search a file name into this indexed inputs. */
+  @Nullable
+  private final IndexedInputs parentIndexedInputs;
+
+  /** Index a list of input files without a parent indexed inputs. */
+  public IndexedInputs(List<InputFileProvider> inputProviders) throws IOException {
+    this(inputProviders, null);
+  }
+
+  /**
+   * Index a list of input files and set a parent indexed inputs that is firstly used during the
+   * search of a file name.
+   */
+  public IndexedInputs(
+      List<InputFileProvider> inputProviders, @Nullable IndexedInputs parentIndexedInputs)
+      throws IOException {
+    this.parentIndexedInputs = parentIndexedInputs;
+    for (InputFileProvider inputProvider : inputProviders) {
+      indexInput(inputProvider);
+    }
+  }
+
+  @Nullable
+  public InputFileProvider getInputFileProvider(String filename) {
+    Preconditions.checkArgument(filename.endsWith(".class"));
+
+    if (parentIndexedInputs != null) {
+      InputFileProvider inputFileProvider = parentIndexedInputs.getInputFileProvider(filename);
+      if (inputFileProvider != null) {
+        return inputFileProvider;
+      }
+    }
+
+    return inputFiles.get(filename);
+  }
+
+  private void indexInput(final InputFileProvider inputFileProvider) throws IOException {
+    for (String relativePath : inputFileProvider) {
+      if (relativePath.endsWith(".class") && !inputFiles.containsKey(relativePath)) {
+        inputFiles.put(relativePath, inputFileProvider);
+      }
+    }
+  }
+}
diff --git a/java/com/google/devtools/build/android/desugar/IndexedJars.java b/java/com/google/devtools/build/android/desugar/IndexedJars.java
deleted file mode 100644
index bdb5b47..0000000
--- a/java/com/google/devtools/build/android/desugar/IndexedJars.java
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2017 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES 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.devtools.build.android.desugar;
-
-import com.google.common.base.Preconditions;
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import javax.annotation.Nullable;
-
-/**
- * Opens the given list of Jar files and compute an index of all classes in them, to avoid
- * scanning all Jars over and over for each class to load. An indexed jars can have a parent
- * that is firstly used when a file name is searched.
- */
-class IndexedJars {
-
-  private final Map<String, JarFile> jarfiles = new HashMap<>();
-
-  /**
-   * Parent indexed jars to use before to search a file name into this indexed jars.
-   */
-  @Nullable
-  private final IndexedJars parentIndexedJar;
-
-  /**
-   * Index a list of Jar files without a parent indexed jars.
-   */
-  public IndexedJars(List<Path> jarFiles) throws IOException {
-    this(jarFiles, null);
-  }
-
-  /**
-   * Index a list of Jar files and set a parent indexed jars that is firstly used during the search
-   * of a file name.
-   */
-  public IndexedJars(List<Path> jarFiles, @Nullable IndexedJars parentIndexedJar)
-      throws IOException {
-    this.parentIndexedJar = parentIndexedJar;
-    for (Path jarfile : jarFiles) {
-      indexJar(jarfile);
-    }
-  }
-
-  @Nullable
-  public JarFile getJarFile(String filename) {
-    Preconditions.checkArgument(filename.endsWith(".class"));
-
-    if (parentIndexedJar != null) {
-      JarFile jarFile = parentIndexedJar.getJarFile(filename);
-      if (jarFile != null) {
-        return jarFile;
-      }
-    }
-
-    return jarfiles.get(filename);
-  }
-
-  private void indexJar(Path jarfile) throws IOException {
-    JarFile jar = new JarFile(jarfile.toFile());
-    for (Enumeration<JarEntry> cur = jar.entries(); cur.hasMoreElements(); ) {
-      JarEntry entry = cur.nextElement();
-      if (entry.getName().endsWith(".class") && !jarfiles.containsKey(entry.getName())) {
-        jarfiles.put(entry.getName(), jar);
-      }
-    }
-  }
-}
diff --git a/java/com/google/devtools/build/android/desugar/InputFileProvider.java b/java/com/google/devtools/build/android/desugar/InputFileProvider.java
new file mode 100644
index 0000000..c2b6353
--- /dev/null
+++ b/java/com/google/devtools/build/android/desugar/InputFileProvider.java
@@ -0,0 +1,36 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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.devtools.build.android.desugar;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+
+/** Input file provider allows to iterate on relative path filename of a directory or a jar file. */
+interface InputFileProvider extends Closeable, Iterable<String> {
+
+  /**
+   * Return a ZipEntry for {@code filename}. If the provider is a {@link ZipInputFileProvider}, the
+   * method returns the existing ZipEntry in order to keep its metadata, otherwise a new one is
+   * created.
+   */
+  ZipEntry getZipEntry(String filename);
+
+  /**
+   * This method returns an input stream allowing to read the file {@code filename}, it is the
+   * responsibility of the caller to close this stream.
+   */
+  InputStream getInputStream(String filename) throws IOException;
+}
diff --git a/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java b/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java
index 2a9f9be..155e323 100644
--- a/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java
+++ b/java/com/google/devtools/build/android/desugar/LambdaClassMaker.java
@@ -57,7 +57,7 @@
    * Returns absolute paths to .class files generated since the last call to this method together
    * with a string descriptor of the factory method.
    */
-  public Map<Path, LambdaInfo> drain() {
+  public ImmutableMap<Path, LambdaInfo> drain() {
     ImmutableMap<Path, LambdaInfo> result = ImmutableMap.copyOf(generatedClasses);
     generatedClasses.clear();
     return result;
diff --git a/java/com/google/devtools/build/android/desugar/OutputFileProvider.java b/java/com/google/devtools/build/android/desugar/OutputFileProvider.java
new file mode 100644
index 0000000..bf3b710
--- /dev/null
+++ b/java/com/google/devtools/build/android/desugar/OutputFileProvider.java
@@ -0,0 +1,29 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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.devtools.build.android.desugar;
+
+import java.io.IOException;
+
+/** Output file provider allows to write files in directory or jar files. */
+interface OutputFileProvider extends AutoCloseable {
+
+  /**
+   * Copy {@code filename} from {@code inputFileProvider} to this output. If input file provider is
+   * a {@link ZipInputFileProvider} then the metadata of the zip entry are kept.
+   */
+  void copyFrom(String filename, InputFileProvider inputFileProvider) throws IOException;
+
+  /** Write {@code content} in {@code filename} to this output */
+  void write(String filename, byte[] content) throws IOException;
+}
diff --git a/java/com/google/devtools/build/android/desugar/ZipInputFileProvider.java b/java/com/google/devtools/build/android/desugar/ZipInputFileProvider.java
new file mode 100644
index 0000000..307c8b8
--- /dev/null
+++ b/java/com/google/devtools/build/android/desugar/ZipInputFileProvider.java
@@ -0,0 +1,64 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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.devtools.build.android.desugar;
+
+import com.google.common.base.Functions;
+import com.google.common.collect.Iterators;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.util.Iterator;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/** Input provider is a zip file. */
+class ZipInputFileProvider implements InputFileProvider {
+
+  private final Path root;
+
+  private final ZipFile zipFile;
+
+  public ZipInputFileProvider(Path root) throws IOException {
+    this.root = root;
+    this.zipFile = new ZipFile(root.toFile());
+  }
+
+  @Override
+  public void close() throws IOException {
+    zipFile.close();
+  }
+
+  @Override
+  public String toString() {
+    return root.getFileName().toString();
+  }
+
+  @Override
+  public ZipEntry getZipEntry(String filename) {
+    ZipEntry zipEntry = zipFile.getEntry(filename);
+    zipEntry.setCompressedSize(-1);
+    return zipEntry;
+  }
+
+  @Override
+  public InputStream getInputStream(String filename) throws IOException {
+    return zipFile.getInputStream(zipFile.getEntry(filename));
+  }
+
+  @Override
+  public Iterator<String> iterator() {
+    return Iterators.transform(
+        Iterators.forEnumeration(zipFile.entries()), Functions.toStringFunction());
+  }
+}
diff --git a/java/com/google/devtools/build/android/desugar/ZipOutputFileProvider.java b/java/com/google/devtools/build/android/desugar/ZipOutputFileProvider.java
new file mode 100644
index 0000000..3f4f344
--- /dev/null
+++ b/java/com/google/devtools/build/android/desugar/ZipOutputFileProvider.java
@@ -0,0 +1,76 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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.devtools.build.android.desugar;
+
+import com.google.common.base.Preconditions;
+import com.google.common.io.ByteStreams;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.zip.CRC32;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/** Output provider is a zip file. */
+public class ZipOutputFileProvider implements OutputFileProvider {
+
+  private final ZipOutputStream out;
+
+  public ZipOutputFileProvider(Path root) throws IOException {
+    out = new ZipOutputStream(new BufferedOutputStream(Files.newOutputStream(root)));
+  }
+
+  @Override
+  public void copyFrom(String filename, InputFileProvider inputFileProvider) throws IOException {
+    // TODO(bazel-team): Avoid de- and re-compressing resource files
+    out.putNextEntry(inputFileProvider.getZipEntry(filename));
+    try (InputStream is = inputFileProvider.getInputStream(filename)) {
+      ByteStreams.copy(is, out);
+    }
+    out.closeEntry();
+  }
+
+  @Override
+  public void write(String filename, byte[] content) throws IOException {
+    Preconditions.checkArgument(filename.endsWith(".class"));
+    writeStoredEntry(out, filename, content);
+  }
+
+  @Override
+  public void close() throws IOException {
+    out.close();
+  }
+
+  private static void writeStoredEntry(ZipOutputStream out, String filename, byte[] content)
+      throws IOException {
+    // Need to pre-compute checksum for STORED (uncompressed) entries)
+    CRC32 checksum = new CRC32();
+    checksum.update(content);
+
+    ZipEntry result = new ZipEntry(filename);
+    result.setTime(0L); // Use stable timestamp Jan 1 1980
+    result.setCrc(checksum.getValue());
+    result.setSize(content.length);
+    result.setCompressedSize(content.length);
+    // Write uncompressed, since this is just an intermediary artifact that
+    // we will convert to .dex
+    result.setMethod(ZipEntry.STORED);
+
+    out.putNextEntry(result);
+    out.write(content);
+    out.closeEntry();
+  }
+}
diff --git a/java/com/google/devtools/common/options/Converters.java b/java/com/google/devtools/common/options/Converters.java
index c8b4d47..0d19029 100644
--- a/java/com/google/devtools/common/options/Converters.java
+++ b/java/com/google/devtools/common/options/Converters.java
@@ -16,7 +16,6 @@
 import com.google.common.base.Splitter;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Maps;
-
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -30,6 +29,171 @@
  */
 public final class Converters {
 
+  /** Standard converter for booleans. Accepts common shorthands/synonyms. */
+  public static class BooleanConverter implements Converter<Boolean> {
+    @Override
+    public Boolean convert(String input) throws OptionsParsingException {
+      if (input == null) {
+        return false;
+      }
+      input = input.toLowerCase();
+      if (input.equals("true")
+          || input.equals("1")
+          || input.equals("yes")
+          || input.equals("t")
+          || input.equals("y")) {
+        return true;
+      }
+      if (input.equals("false")
+          || input.equals("0")
+          || input.equals("no")
+          || input.equals("f")
+          || input.equals("n")) {
+        return false;
+      }
+      throw new OptionsParsingException("'" + input + "' is not a boolean");
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "a boolean";
+    }
+  }
+
+  /** Standard converter for Strings. */
+  public static class StringConverter implements Converter<String> {
+    @Override
+    public String convert(String input) {
+      return input;
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "a string";
+    }
+  }
+
+  /** Standard converter for integers. */
+  public static class IntegerConverter implements Converter<Integer> {
+    @Override
+    public Integer convert(String input) throws OptionsParsingException {
+      try {
+        return Integer.decode(input);
+      } catch (NumberFormatException e) {
+        throw new OptionsParsingException("'" + input + "' is not an int");
+      }
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "an integer";
+    }
+  }
+
+  /** Standard converter for longs. */
+  public static class LongConverter implements Converter<Long> {
+    @Override
+    public Long convert(String input) throws OptionsParsingException {
+      try {
+        return Long.decode(input);
+      } catch (NumberFormatException e) {
+        throw new OptionsParsingException("'" + input + "' is not a long");
+      }
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "a long integer";
+    }
+  }
+
+  /** Standard converter for doubles. */
+  public static class DoubleConverter implements Converter<Double> {
+    @Override
+    public Double convert(String input) throws OptionsParsingException {
+      try {
+        return Double.parseDouble(input);
+      } catch (NumberFormatException e) {
+        throw new OptionsParsingException("'" + input + "' is not a double");
+      }
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "a double";
+    }
+  }
+
+  /** Standard converter for TriState values. */
+  public static class TriStateConverter implements Converter<TriState> {
+    @Override
+    public TriState convert(String input) throws OptionsParsingException {
+      if (input == null) {
+        return TriState.AUTO;
+      }
+      input = input.toLowerCase();
+      if (input.equals("auto")) {
+        return TriState.AUTO;
+      }
+      if (input.equals("true")
+          || input.equals("1")
+          || input.equals("yes")
+          || input.equals("t")
+          || input.equals("y")) {
+        return TriState.YES;
+      }
+      if (input.equals("false")
+          || input.equals("0")
+          || input.equals("no")
+          || input.equals("f")
+          || input.equals("n")) {
+        return TriState.NO;
+      }
+      throw new OptionsParsingException("'" + input + "' is not a boolean");
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "a tri-state (auto, yes, no)";
+    }
+  }
+
+  /**
+   * Standard "converter" for Void. Should not actually be invoked. For instance, expansion flags
+   * are usually Void-typed and do not invoke the converter.
+   */
+  public static class VoidConverter implements Converter<Void> {
+    @Override
+    public Void convert(String input) throws OptionsParsingException {
+      if (input == null) {
+        return null; // expected input, return is unused so null is fine.
+      }
+      throw new OptionsParsingException("'" + input + "' unexpected");
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "";
+    }
+  }
+
+  /**
+   * The converters that are available to the options parser by default. These are used if the
+   * {@code @Option} annotation does not specify its own {@code converter}, and its type is one of
+   * the following.
+   */
+  static final Map<Class<?>, Converter<?>> DEFAULT_CONVERTERS = Maps.newHashMap();
+
+  static {
+    DEFAULT_CONVERTERS.put(String.class, new Converters.StringConverter());
+    DEFAULT_CONVERTERS.put(int.class, new Converters.IntegerConverter());
+    DEFAULT_CONVERTERS.put(long.class, new Converters.LongConverter());
+    DEFAULT_CONVERTERS.put(double.class, new Converters.DoubleConverter());
+    DEFAULT_CONVERTERS.put(boolean.class, new Converters.BooleanConverter());
+    DEFAULT_CONVERTERS.put(TriState.class, new Converters.TriStateConverter());
+    DEFAULT_CONVERTERS.put(Void.class, new Converters.VoidConverter());
+  }
+
   /**
    * Join a list of words as in English.  Examples:
    * "nothing"
@@ -92,7 +256,7 @@
 
   public static class LogLevelConverter implements Converter<Level> {
 
-    public static Level[] LEVELS = new Level[] {
+    public static final Level[] LEVELS = new Level[] {
       Level.OFF, Level.SEVERE, Level.WARNING, Level.INFO, Level.FINE,
       Level.FINER, Level.FINEST
     };
@@ -295,32 +459,4 @@
     }
   }
 
-  /**
-   * A converter for boolean values. This is already one of the defaults, so clients
-   * should not typically need to add this.
-   */
-  public static class BooleanConverter implements Converter<Boolean> {
-    @Override
-    public Boolean convert(String input) throws OptionsParsingException {
-      if (input == null) {
-        return false;
-      }
-      input = input.toLowerCase();
-      if (input.equals("true") || input.equals("1") || input.equals("yes") ||
-          input.equals("t") || input.equals("y")) {
-        return true;
-      }
-      if (input.equals("false") || input.equals("0") || input.equals("no") ||
-          input.equals("f") || input.equals("n")) {
-        return false;
-      }
-      throw new OptionsParsingException("'" + input + "' is not a boolean");
-    }
-
-    @Override
-    public String getTypeDescription() {
-      return "a boolean";
-    }
-  }
-
 }
diff --git a/java/com/google/devtools/common/options/ExpansionFunction.java b/java/com/google/devtools/common/options/ExpansionFunction.java
new file mode 100644
index 0000000..ffab6e7
--- /dev/null
+++ b/java/com/google/devtools/common/options/ExpansionFunction.java
@@ -0,0 +1,31 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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.devtools.common.options;
+
+/**
+ * A function from an option parser's static setup (what flags it knows about) to an expansion
+ * String[] to use for one of its options.
+ */
+public interface ExpansionFunction {
+
+  /**
+   * Compute the expansion for an option. May be called at any time during or after the {@link
+   * OptionsParser}'s construction, or not at all.
+   *
+   * @param optionsData the parser's indexed information about its own options, before expansion
+   *     information is computed
+   * @return An expansion to use for all occurrences of this option in this parser
+   */
+  public String[] getExpansion(IsolatedOptionsData optionsData);
+}
diff --git a/java/com/google/devtools/common/options/IsolatedOptionsData.java b/java/com/google/devtools/common/options/IsolatedOptionsData.java
new file mode 100644
index 0000000..27f42f4
--- /dev/null
+++ b/java/com/google/devtools/common/options/IsolatedOptionsData.java
@@ -0,0 +1,382 @@
+// Copyright 2014 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES 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.devtools.common.options;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.concurrent.Immutable;
+
+/**
+ * An immutable selection of options data corresponding to a set of options classes. The data is
+ * collected using reflection, which can be expensive. Therefore this class can be used internally
+ * to cache the results.
+ *
+ * <p>The data is isolated in the sense that it has not yet been processed to add inter-option-
+ * dependent information -- namely, the results of evaluating expansion functions. The {@link
+ * OptionsData} subclass stores this added information. The reason for the split is so that we can
+ * avoid exposing to expansion functions the effects of evaluating other expansion functions, to
+ * ensure that the order in which they run is not significant.
+ */
+// TODO(brandjon): This class is technically not necessarily immutable due to optionsDefault
+// accepting Object values, and the List in allOptionsField should be ImmutableList. Either fix
+// this or remove @Immutable.
+@Immutable
+class IsolatedOptionsData extends OpaqueOptionsData {
+
+  /**
+   * These are the options-declaring classes which are annotated with {@link Option} annotations.
+   */
+  private final ImmutableMap<Class<? extends OptionsBase>, Constructor<?>> optionsClasses;
+
+  /** Maps option name to Option-annotated Field. */
+  private final ImmutableMap<String, Field> nameToField;
+
+  /** Maps option abbreviation to Option-annotated Field. */
+  private final ImmutableMap<Character, Field> abbrevToField;
+
+  /** For each options class, contains a list of all Option-annotated fields in that class. */
+  private final ImmutableMap<Class<? extends OptionsBase>, List<Field>> allOptionsFields;
+
+  /** Mapping from each Option-annotated field to the default value for that field. */
+  // Immutable like the others, but uses Collections.unmodifiableMap because of null values.
+  private final Map<Field, Object> optionDefaults;
+
+  /**
+   * Mapping from each Option-annotated field to the proper converter.
+   *
+   * @see #findConverter
+   */
+  private final ImmutableMap<Field, Converter<?>> converters;
+
+  /**
+   * Mapping from each Option-annotated field to a boolean for whether that field allows multiple
+   * values.
+   */
+  private final ImmutableMap<Field, Boolean> allowMultiple;
+
+  private IsolatedOptionsData(
+      Map<Class<? extends OptionsBase>, Constructor<?>> optionsClasses,
+      Map<String, Field> nameToField,
+      Map<Character, Field> abbrevToField,
+      Map<Class<? extends OptionsBase>, List<Field>> allOptionsFields,
+      Map<Field, Object> optionDefaults,
+      Map<Field, Converter<?>> converters,
+      Map<Field, Boolean> allowMultiple) {
+    this.optionsClasses = ImmutableMap.copyOf(optionsClasses);
+    this.nameToField = ImmutableMap.copyOf(nameToField);
+    this.abbrevToField = ImmutableMap.copyOf(abbrevToField);
+    this.allOptionsFields = ImmutableMap.copyOf(allOptionsFields);
+    // Can't use an ImmutableMap here because of null values.
+    this.optionDefaults = Collections.unmodifiableMap(optionDefaults);
+    this.converters = ImmutableMap.copyOf(converters);
+    this.allowMultiple = ImmutableMap.copyOf(allowMultiple);
+  }
+
+  protected IsolatedOptionsData(IsolatedOptionsData other) {
+    this(
+        other.optionsClasses,
+        other.nameToField,
+        other.abbrevToField,
+        other.allOptionsFields,
+        other.optionDefaults,
+        other.converters,
+        other.allowMultiple);
+  }
+
+  public Collection<Class<? extends OptionsBase>> getOptionsClasses() {
+    return optionsClasses.keySet();
+  }
+
+  @SuppressWarnings("unchecked") // The construction ensures that the case is always valid.
+  public <T extends OptionsBase> Constructor<T> getConstructor(Class<T> clazz) {
+    return (Constructor<T>) optionsClasses.get(clazz);
+  }
+
+  public Field getFieldFromName(String name) {
+    return nameToField.get(name);
+  }
+
+  public Iterable<Map.Entry<String, Field>> getAllNamedFields() {
+    return nameToField.entrySet();
+  }
+
+  public Field getFieldForAbbrev(char abbrev) {
+    return abbrevToField.get(abbrev);
+  }
+
+  public List<Field> getFieldsForClass(Class<? extends OptionsBase> optionsClass) {
+    return allOptionsFields.get(optionsClass);
+  }
+
+  public Object getDefaultValue(Field field) {
+    return optionDefaults.get(field);
+  }
+
+  public Converter<?> getConverter(Field field) {
+    return converters.get(field);
+  }
+
+  public boolean getAllowMultiple(Field field) {
+    return allowMultiple.get(field);
+  }
+
+  /**
+   * For an option that does not use {@link Option#allowMultiple}, returns its type. For an option
+   * that does use it, asserts that the type is a {@code List<T>} and returns its element type
+   * {@code T}.
+   */
+  private static Type getFieldSingularType(Field field, Option annotation) {
+    Type fieldType = field.getGenericType();
+    if (annotation.allowMultiple()) {
+      // If the type isn't a List<T>, this is an error in the option's declaration.
+      if (!(fieldType instanceof ParameterizedType)) {
+        throw new AssertionError("Type of multiple occurrence option must be a List<...>");
+      }
+      ParameterizedType pfieldType = (ParameterizedType) fieldType;
+      if (pfieldType.getRawType() != List.class) {
+        throw new AssertionError("Type of multiple occurrence option must be a List<...>");
+      }
+      fieldType = pfieldType.getActualTypeArguments()[0];
+    }
+    return fieldType;
+  }
+
+  /**
+   * Returns whether a field should be considered as boolean.
+   *
+   * <p>Can be used for usage help and controlling whether the "no" prefix is allowed.
+   */
+  static boolean isBooleanField(Field field) {
+    return field.getType().equals(boolean.class)
+        || field.getType().equals(TriState.class)
+        || findConverter(field) instanceof BoolOrEnumConverter;
+  }
+
+  /** Returns whether a field has Void type. */
+  static boolean isVoidField(Field field) {
+    return field.getType().equals(Void.class);
+  }
+
+  /**
+   * Returns whether the arg is an expansion option defined by an expansion function (and not a
+   * constant expansion value).
+   */
+  static boolean usesExpansionFunction(Option annotation) {
+    return annotation.expansionFunction() != ExpansionFunction.class;
+  }
+
+  /**
+   * Given an {@code @Option}-annotated field, retrieves the {@link Converter} that will be used,
+   * taking into account the default converters if an explicit one is not specified.
+   */
+  static Converter<?> findConverter(Field optionField) {
+    Option annotation = optionField.getAnnotation(Option.class);
+    if (annotation.converter() == Converter.class) {
+      // No converter provided, use the default one.
+      Type type = getFieldSingularType(optionField, annotation);
+      Converter<?> converter = Converters.DEFAULT_CONVERTERS.get(type);
+      if (converter == null) {
+        throw new AssertionError(
+            "No converter found for "
+                + type
+                + "; possible fix: add "
+                + "converter=... to @Option annotation for "
+                + optionField.getName());
+      }
+      return converter;
+    }
+    try {
+      // Instantiate the given Converter class.
+      Class<?> converter = annotation.converter();
+      Constructor<?> constructor = converter.getConstructor();
+      return (Converter<?>) constructor.newInstance();
+    } catch (Exception e) {
+      // This indicates an error in the Converter, and should be discovered the first time it is
+      // used.
+      throw new AssertionError(e);
+    }
+  }
+
+  private static List<Field> getAllAnnotatedFields(Class<? extends OptionsBase> optionsClass) {
+    List<Field> allFields = Lists.newArrayList();
+    for (Field field : optionsClass.getFields()) {
+      if (field.isAnnotationPresent(Option.class)) {
+        allFields.add(field);
+      }
+    }
+    if (allFields.isEmpty()) {
+      throw new IllegalStateException(optionsClass + " has no public @Option-annotated fields");
+    }
+    return ImmutableList.copyOf(allFields);
+  }
+
+  private static Object retrieveDefaultFromAnnotation(Field optionField) {
+    Converter<?> converter = findConverter(optionField);
+    String defaultValueAsString = OptionsParserImpl.getDefaultOptionString(optionField);
+    // Special case for "null"
+    if (OptionsParserImpl.isSpecialNullDefault(defaultValueAsString, optionField)) {
+      return null;
+    }
+    boolean allowsMultiple = optionField.getAnnotation(Option.class).allowMultiple();
+    // If the option allows multiple values then we intentionally return the empty list as
+    // the default value of this option since it is not always the case that an option
+    // that allows multiple values will have a converter that returns a list value.
+    if (allowsMultiple) {
+      return Collections.emptyList();
+    }
+    // Otherwise try to convert the default value using the converter
+    Object convertedValue;
+    try {
+      convertedValue = converter.convert(defaultValueAsString);
+    } catch (OptionsParsingException e) {
+      throw new IllegalStateException("OptionsParsingException while "
+          + "retrieving default for " + optionField.getName() + ": "
+          + e.getMessage());
+    }
+    return convertedValue;
+  }
+
+  /**
+   * Constructs an {@link IsolatedOptionsData} object for a parser that knows about the given
+   * {@link OptionsBase} classes. No inter-option analysis is done. Performs basic sanity checking
+   * on each option in isolation.
+   */
+  static IsolatedOptionsData from(Collection<Class<? extends OptionsBase>> classes) {
+    Map<Class<? extends OptionsBase>, Constructor<?>> constructorBuilder = Maps.newHashMap();
+    Map<Class<? extends OptionsBase>, List<Field>> allOptionsFieldsBuilder = Maps.newHashMap();
+    Map<String, Field> nameToFieldBuilder = Maps.newHashMap();
+    Map<Character, Field> abbrevToFieldBuilder = Maps.newHashMap();
+    Map<Field, Object> optionDefaultsBuilder = Maps.newHashMap();
+    Map<Field, Converter<?>> convertersBuilder = Maps.newHashMap();
+    Map<Field, Boolean> allowMultipleBuilder = Maps.newHashMap();
+
+    // Read all Option annotations:
+    for (Class<? extends OptionsBase> parsedOptionsClass : classes) {
+      try {
+        Constructor<? extends OptionsBase> constructor =
+            parsedOptionsClass.getConstructor();
+        constructorBuilder.put(parsedOptionsClass, constructor);
+      } catch (NoSuchMethodException e) {
+        throw new IllegalArgumentException(parsedOptionsClass
+            + " lacks an accessible default constructor");
+      }
+      List<Field> fields = getAllAnnotatedFields(parsedOptionsClass);
+      allOptionsFieldsBuilder.put(parsedOptionsClass, fields);
+
+      for (Field field : fields) {
+        Option annotation = field.getAnnotation(Option.class);
+
+        if (annotation.name() == null) {
+          throw new AssertionError("Option cannot have a null name");
+        }
+
+        Type fieldType = getFieldSingularType(field, annotation);
+
+        // Get the converter return type.
+        @SuppressWarnings("rawtypes")
+        Class<? extends Converter> converter = annotation.converter();
+        if (converter == Converter.class) {
+          Converter<?> actualConverter = Converters.DEFAULT_CONVERTERS.get(fieldType);
+          if (actualConverter == null) {
+            throw new AssertionError("Cannot find converter for field of type "
+                + field.getType() + " named " + field.getName()
+                + " in class " + field.getDeclaringClass().getName());
+          }
+          converter = actualConverter.getClass();
+        }
+        if (Modifier.isAbstract(converter.getModifiers())) {
+          throw new AssertionError("The converter type " + converter
+              + " must be a concrete type");
+        }
+        Type converterResultType;
+        try {
+          Method convertMethod = converter.getMethod("convert", String.class);
+          converterResultType = GenericTypeHelper.getActualReturnType(converter, convertMethod);
+        } catch (NoSuchMethodException e) {
+          throw new AssertionError("A known converter object doesn't implement the convert"
+              + " method");
+        }
+
+        if (annotation.allowMultiple()) {
+          if (GenericTypeHelper.getRawType(converterResultType) == List.class) {
+            Type elementType =
+                ((ParameterizedType) converterResultType).getActualTypeArguments()[0];
+            if (!GenericTypeHelper.isAssignableFrom(fieldType, elementType)) {
+              throw new AssertionError("If the converter return type of a multiple occurance " +
+                  "option is a list, then the type of list elements (" + fieldType + ") must be " +
+                  "assignable from the converter list element type (" + elementType + ")");
+            }
+          } else {
+            if (!GenericTypeHelper.isAssignableFrom(fieldType, converterResultType)) {
+              throw new AssertionError("Type of list elements (" + fieldType +
+                  ") for multiple occurrence option must be assignable from the converter " +
+                  "return type (" + converterResultType + ")");
+            }
+          }
+        } else {
+          if (!GenericTypeHelper.isAssignableFrom(fieldType, converterResultType)) {
+            throw new AssertionError("Type of field (" + fieldType +
+                ") must be assignable from the converter " +
+                "return type (" + converterResultType + ")");
+          }
+        }
+
+        if (nameToFieldBuilder.put(annotation.name(), field) != null) {
+          throw new DuplicateOptionDeclarationException(
+              "Duplicate option name: --" + annotation.name());
+        }
+        if (!annotation.oldName().isEmpty()) {
+          if (nameToFieldBuilder.put(annotation.oldName(), field) != null) {
+            throw new DuplicateOptionDeclarationException(
+                "Old option name duplicates option name: --" + annotation.oldName());
+          }
+        }
+        if (annotation.abbrev() != '\0') {
+          if (abbrevToFieldBuilder.put(annotation.abbrev(), field) != null) {
+            throw new DuplicateOptionDeclarationException(
+                  "Duplicate option abbrev: -" + annotation.abbrev());
+          }
+        }
+
+        optionDefaultsBuilder.put(field, retrieveDefaultFromAnnotation(field));
+
+        convertersBuilder.put(field, findConverter(field));
+
+        allowMultipleBuilder.put(field, annotation.allowMultiple());
+      }
+    }
+
+    return new IsolatedOptionsData(
+        constructorBuilder,
+        nameToFieldBuilder,
+        abbrevToFieldBuilder,
+        allOptionsFieldsBuilder,
+        optionDefaultsBuilder,
+        convertersBuilder,
+        allowMultipleBuilder);
+  }
+}
diff --git a/java/com/google/devtools/common/options/Option.java b/java/com/google/devtools/common/options/Option.java
index 3b2ca30..249ee70 100644
--- a/java/com/google/devtools/common/options/Option.java
+++ b/java/com/google/devtools/common/options/Option.java
@@ -47,116 +47,147 @@
   String valueHelp() default "";
 
   /**
-   * The default value for the option. This method should only be invoked
-   * directly by the parser implementation. Any access to default values
-   * should go via the parser to allow for application specific defaults.
+   * The default value for the option. This method should only be invoked directly by the parser
+   * implementation. Any access to default values should go via the parser to allow for application
+   * specific defaults.
    *
-   * <p>There are two reasons this is a string.  Firstly, it ensures that
-   * explicitly specifying this option at its default value (as printed in the
-   * usage message) has the same behavior as not specifying the option at all;
-   * this would be very hard to achieve if the default value was an instance of
-   * type T, since we'd need to ensure that {@link #toString()} and {@link
-   * #converter} were dual to each other.  The second reason is more mundane
-   * but also more restrictive: annotation values must be compile-time
-   * constants.
+   * <p>There are two reasons this is a string. Firstly, it ensures that explicitly specifying this
+   * option at its default value (as printed in the usage message) has the same behavior as not
+   * specifying the option at all; this would be very hard to achieve if the default value was an
+   * instance of type T, since we'd need to ensure that {@link #toString()} and {@link #converter}
+   * were dual to each other. The second reason is more mundane but also more restrictive:
+   * annotation values must be compile-time constants.
    *
-   * <p>If an option's defaultValue() is the string "null", the option's
-   * converter will not be invoked to interpret it; a null reference will be
-   * used instead.  (It would be nice if defaultValue could simply return null,
-   * but bizarrely, the Java Language Specification does not consider null to
-   * be a compile-time constant.)  This special interpretation of the string
-   * "null" is only applicable when computing the default value; if specified
-   * on the command-line, this string will have its usual literal meaning.
+   * <p>If an option's defaultValue() is the string "null", the option's converter will not be
+   * invoked to interpret it; a null reference will be used instead. (It would be nice if
+   * defaultValue could simply return null, but bizarrely, the Java Language Specification does not
+   * consider null to be a compile-time constant.) This special interpretation of the string "null"
+   * is only applicable when computing the default value; if specified on the command-line, this
+   * string will have its usual literal meaning.
    *
-   * <p>The default value for flags that set allowMultiple is always the empty
-   * list and its default value is ignored.
+   * <p>The default value for flags that set allowMultiple is always the empty list and its default
+   * value is ignored.
    */
   String defaultValue();
 
   /**
    * A string describing the category of options that this belongs to. {@link
-   * OptionsParser#describeOptions} prints options of the same category grouped
-   * together.
+   * OptionsParser#describeOptions} prints options of the same category grouped together.
+   *
+   * <p>There are three special category values:
+   *
+   * <ul>
+   *   <li>{@code "undocumented"}: options which are useful for (some subset of) users, but not
+   *       meant to be publicly advertised. For example, experimental options which are only meant
+   *       to be used by specific testers or team members, but which should otherwise be treated
+   *       normally. These options will not be listed in the usage info displayed for the {@code
+   *       --help} option. They are otherwise normal - {@link
+   *       OptionsParser.UnparsedOptionValueDescription#isHidden()} returns {@code false} for them,
+   *       and they can be parsed normally from the command line or RC files.
+   *   <li>{@code "hidden"}: options which users should not pass or know about, but which are used
+   *       by the program (e.g., communication between a command-line client and a backend server).
+   *       Like {@code "undocumented"} options, these options will not be listed in the usage info
+   *       displayed for the {@code --help} option. However, in addition to this, calling {@link
+   *       OptionsParser.UnparsedOptionValueDescription#isHidden()} on these options will return
+   *       {@code true} - for example, this can be checked to strip out such secret options when
+   *       logging or otherwise reporting the command line to the user. This category does not
+   *       affect the option in any other way; it can still be parsed normally from the command line
+   *       or an RC file.
+   *   <li>{@code "internal"}: options which are purely for internal use within the JVM, and should
+   *       never be shown to the user, nor ever need to be parsed by the options parser. Like {@code
+   *       "hidden"} options, these options will not be listed in the usage info displayed for the
+   *       --help option, and are considered hidden by {@link
+   *       OptionsParser.UnparsedOptionValueDescription#isHidden()}. Unlike those, this type of
+   *       option cannot be parsed by any call to {@link OptionsParser#parse} - it will be treated
+   *       as if it was not defined.
+   * </ul>
    */
   String category() default "misc";
 
   /**
-   * The converter that we'll use to convert this option into an object or
-   * a simple type. The default is to use the builtin converters.
-   * Custom converters must implement the {@link Converter} interface.
+   * The converter that we'll use to convert the string representation of this option's value into
+   * an object or a simple type. The default is to use the builtin converters ({@link
+   * Converters#DEFAULT_CONVERTERS}). Custom converters must implement the {@link Converter}
+   * interface.
    */
   @SuppressWarnings({"unchecked", "rawtypes"})
   // Can't figure out how to coerce Converter.class into Class<? extends Converter<?>>
   Class<? extends Converter> converter() default Converter.class;
 
   /**
-   * A flag indicating whether the option type should be allowed to occur
-   * multiple times in a single option list.
+   * A flag indicating whether the option type should be allowed to occur multiple times in a single
+   * option list.
    *
-   * <p>If the command can occur multiple times, then the attribute value
-   * <em>must</em> be a list type {@code List<T>}, and the result type of the
-   * converter for this option must either match the parameter {@code T} or
-   * {@code List<T>}. In the latter case the individual lists are concatenated
-   * to form the full options value.
+   * <p>If the command can occur multiple times, then the attribute value <em>must</em> be a list
+   * type {@code List<T>}, and the result type of the converter for this option must either match
+   * the parameter {@code T} or {@code List<T>}. In the latter case the individual lists are
+   * concatenated to form the full options value.
    *
-   * <p>The {@link #defaultValue()} field of the annotation is ignored for repeatable
-   * flags and the default value will be the empty list.
+   * <p>The {@link #defaultValue()} field of the annotation is ignored for repeatable flags and the
+   * default value will be the empty list.
    */
   boolean allowMultiple() default false;
 
   /**
-   * If the option is actually an abbreviation for other options, this field will
-   * contain the strings to expand this option into. The original option is dropped
-   * and the replacement used in its stead. It is recommended that such an option be
-   * of type {@link Void}.
+   * If the option is actually an abbreviation for other options, this field will contain the
+   * strings to expand this option into. The original option is dropped and the replacement used in
+   * its stead. It is recommended that such an option be of type {@link Void}.
    *
-   * An expanded option overrides previously specified options of the same name,
-   * even if it is explicitly specified. This is the original behavior and can
-   * be surprising if the user is not aware of it, which has led to several
-   * requests to change this behavior. This was discussed in the blaze team and
-   * it was decided that it is not a strong enough case to change the behavior.
+   * <p>An expanded option overrides previously specified options of the same name, even if it is
+   * explicitly specified. This is the original behavior and can be surprising if the user is not
+   * aware of it, which has led to several requests to change this behavior. This was discussed in
+   * the blaze team and it was decided that it is not a strong enough case to change the behavior.
    */
   String[] expansion() default {};
 
   /**
-   * If the option requires that additional options be implicitly appended, this field
-   * will contain the additional options. Implicit dependencies are parsed at the end
-   * of each {@link OptionsParser#parse} invocation, and override options specified in
-   * the same call. However, they can be overridden by options specified in a later
-   * call or by options with a higher priority.
+   * A mechanism for specifying an expansion that is a function of the parser's {@link
+   * IsolatedOptionsData}. This can be used to create an option that expands to different strings
+   * depending on what other options the parser knows about.
+   *
+   * <p>If provided (i.e. not {@link ExpansionFunction}{@code .class}), the {@code expansion} field
+   * must not be set. The mechanism of expansion is as if the {@code expansion} field were set to
+   * whatever the return value of this function is.
+   */
+  Class<? extends ExpansionFunction> expansionFunction() default ExpansionFunction.class;
+
+  /**
+   * If the option requires that additional options be implicitly appended, this field will contain
+   * the additional options. Implicit dependencies are parsed at the end of each {@link
+   * OptionsParser#parse} invocation, and override options specified in the same call. However, they
+   * can be overridden by options specified in a later call or by options with a higher priority.
    *
    * @see OptionPriority
    */
   String[] implicitRequirements() default {};
 
   /**
-   * If this field is a non-empty string, the option is deprecated, and a
-   * deprecation warning is added to the list of warnings when such an option
-   * is used.
+   * If this field is a non-empty string, the option is deprecated, and a deprecation warning is
+   * added to the list of warnings when such an option is used.
    */
   String deprecationWarning() default "";
 
   /**
-   * The old name for this option. If an option has a name "foo" and an old name "bar",
-   * --foo=baz and --bar=baz will be equivalent. If the old name is used, a warning will be printed
-   * indicating that the old name is deprecated and the new name should be used.
+   * The old name for this option. If an option has a name "foo" and an old name "bar", --foo=baz
+   * and --bar=baz will be equivalent. If the old name is used, a warning will be printed indicating
+   * that the old name is deprecated and the new name should be used.
    */
   String oldName() default "";
 
   /**
-   * Indicates that this option is a wrapper for other options, and will be unwrapped
-   * when parsed. For example, if foo is a wrapper option, then "--foo=--bar=baz"
-   * will be parsed as the flag "--bar=baz" (rather than --foo taking the value
-   * "--bar=baz"). A wrapper option should have the type {@link Void} (if it is something other
-   * than Void, the parser will not assign a value to it). The
-   * {@link Option#implicitRequirements()}, {@link Option#expansion()}, {@link Option#converter()}
-   * attributes will not be processed. Wrapper options are implicitly repeatable (i.e., as though
-   * {@link Option#allowMultiple()} is true regardless of its value in the annotation).
+   * Indicates that this option is a wrapper for other options, and will be unwrapped when parsed.
+   * For example, if foo is a wrapper option, then "--foo=--bar=baz" will be parsed as the flag
+   * "--bar=baz" (rather than --foo taking the value "--bar=baz"). A wrapper option should have the
+   * type {@link Void} (if it is something other than Void, the parser will not assign a value to
+   * it). The {@link Option#implicitRequirements()}, {@link Option#expansion()}, {@link
+   * Option#converter()} attributes will not be processed. Wrapper options are implicitly repeatable
+   * (i.e., as though {@link Option#allowMultiple()} is true regardless of its value in the
+   * annotation).
    *
    * <p>Wrapper options are provided only for transitioning flags which appear as values to other
    * flags, to top-level flags. Wrapper options should not be used in Invocation Policy, as
-   * expansion flags to other flags, or as implicit requirements to other flags. Use the inner
-   * flags instead.  
+   * expansion flags to other flags, or as implicit requirements to other flags. Use the inner flags
+   * instead.
    */
   boolean wrapperOption() default false;
 }
diff --git a/java/com/google/devtools/common/options/OptionsData.java b/java/com/google/devtools/common/options/OptionsData.java
index ac23d63..e71321c 100644
--- a/java/com/google/devtools/common/options/OptionsData.java
+++ b/java/com/google/devtools/common/options/OptionsData.java
@@ -1,4 +1,4 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
+// Copyright 2017 The Bazel Authors. All rights reserved.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,280 +14,89 @@
 
 package com.google.devtools.common.options;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
-import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 import java.util.Map;
-
 import javax.annotation.concurrent.Immutable;
 
 /**
- * An immutable selection of options data corresponding to a set of options
- * classes. The data is collected using reflection, which can be expensive.
- * Therefore this class can be used internally to cache the results.
+ * This extends IsolatedOptionsData with information that can only be determined once all the {@link
+ * OptionsBase} subclasses for a parser are known. In particular, this includes expansion
+ * information.
  */
 @Immutable
-final class OptionsData extends OpaqueOptionsData {
+final class OptionsData extends IsolatedOptionsData {
 
   /**
-   * These are the options-declaring classes which are annotated with
-   * {@link Option} annotations.
+   * Mapping from each Option-annotated field with a {@code String[]} expansion to that expansion.
    */
-  private final Map<Class<? extends OptionsBase>, Constructor<?>> optionsClasses;
+  // TODO(brandjon): This is technically not necessarily immutable due to String[], and should use
+  // ImmutableList. Either fix this or remove @Immutable.
+  private final ImmutableMap<Field, String[]> evaluatedExpansions;
 
-  /** Maps option name to Option-annotated Field. */
-  private final Map<String, Field> nameToField;
+  /** Construct {@link OptionsData} by extending an {@link IsolatedOptionsData} with new info. */
+  private OptionsData(IsolatedOptionsData base, Map<Field, String[]> evaluatedExpansions) {
+    super(base);
+    this.evaluatedExpansions = ImmutableMap.copyOf(evaluatedExpansions);
+  }
 
-  /** Maps option abbreviation to Option-annotated Field. */
-  private final Map<Character, Field> abbrevToField;
+  private static final String[] EMPTY_EXPANSION = new String[] {};
 
   /**
-   * For each options class, contains a list of all Option-annotated fields in
-   * that class.
+   * Returns the expansion of an options field, regardless of whether it was defined using {@link
+   * Option#expansion} or {@link Option#expansionFunction}. If the field is not an expansion option,
+   * returns an empty array.
    */
-  private final Map<Class<? extends OptionsBase>, List<Field>> allOptionsFields;
+  public String[] getEvaluatedExpansion(Field field) {
+    String[] result = evaluatedExpansions.get(field);
+    return result != null ? result : EMPTY_EXPANSION;
+  }
 
   /**
-   * Mapping from each Option-annotated field to the default value for that
-   * field.
+   * Constructs an {@link OptionsData} object for a parser that knows about the given {@link
+   * OptionsBase} classes. In addition to the work done to construct the {@link
+   * IsolatedOptionsData}, this also computes expansion information.
    */
-  private final Map<Field, Object> optionDefaults;
+  public static OptionsData from(Collection<Class<? extends OptionsBase>> classes) {
+    IsolatedOptionsData isolatedData = IsolatedOptionsData.from(classes);
 
-  /**
-   * Mapping from each Option-annotated field to the proper converter.
-   *
-   * @see OptionsParserImpl#findConverter
-   */
-  private final Map<Field, Converter<?>> converters;
-
-  /**
-   * Mapping from each Option-annotated field to a boolean for whether that field allows multiple
-   * values.
-   */
-  private final Map<Field, Boolean> allowMultiple;
-
-  private OptionsData(Map<Class<? extends OptionsBase>, Constructor<?>> optionsClasses,
-                      Map<String, Field> nameToField,
-                      Map<Character, Field> abbrevToField,
-                      Map<Class<? extends OptionsBase>, List<Field>> allOptionsFields,
-                      Map<Field, Object> optionDefaults,
-                      Map<Field, Converter<?>> converters,
-                      Map<Field, Boolean> allowMultiple) {
-    this.optionsClasses = ImmutableMap.copyOf(optionsClasses);
-    this.allOptionsFields = ImmutableMap.copyOf(allOptionsFields);
-    this.nameToField = ImmutableMap.copyOf(nameToField);
-    this.abbrevToField = ImmutableMap.copyOf(abbrevToField);
-    // Can't use an ImmutableMap here because of null values.
-    this.optionDefaults = Collections.unmodifiableMap(optionDefaults);
-    this.converters = ImmutableMap.copyOf(converters);
-    this.allowMultiple = ImmutableMap.copyOf(allowMultiple);
-  }
-
-  public Collection<Class<? extends OptionsBase>> getOptionsClasses() {
-    return optionsClasses.keySet();
-  }
-
-  @SuppressWarnings("unchecked") // The construction ensures that the case is always valid.
-  public <T extends OptionsBase> Constructor<T> getConstructor(Class<T> clazz) {
-    return (Constructor<T>) optionsClasses.get(clazz);
-  }
-
-  public Field getFieldFromName(String name) {
-    return nameToField.get(name);
-  }
-
-  public Iterable<Map.Entry<String, Field>> getAllNamedFields() {
-    return nameToField.entrySet();
-  }
-
-  public Field getFieldForAbbrev(char abbrev) {
-    return abbrevToField.get(abbrev);
-  }
-
-  public List<Field> getFieldsForClass(Class<? extends OptionsBase> optionsClass) {
-    return allOptionsFields.get(optionsClass);
-  }
-
-  public Object getDefaultValue(Field field) {
-    return optionDefaults.get(field);
-  }
-
-  public Converter<?> getConverter(Field field) {
-    return converters.get(field);
-  }
-
-  public boolean getAllowMultiple(Field field) {
-    return allowMultiple.get(field);
-  }
-
-  private static List<Field> getAllAnnotatedFields(Class<? extends OptionsBase> optionsClass) {
-    List<Field> allFields = Lists.newArrayList();
-    for (Field field : optionsClass.getFields()) {
-      if (field.isAnnotationPresent(Option.class)) {
-        allFields.add(field);
-      }
-    }
-    if (allFields.isEmpty()) {
-      throw new IllegalStateException(optionsClass + " has no public @Option-annotated fields");
-    }
-    return ImmutableList.copyOf(allFields);
-  }
-
-  private static Object retrieveDefaultFromAnnotation(Field optionField) {
-    Converter<?> converter = OptionsParserImpl.findConverter(optionField);
-    String defaultValueAsString = OptionsParserImpl.getDefaultOptionString(optionField);
-    // Special case for "null"
-    if (OptionsParserImpl.isSpecialNullDefault(defaultValueAsString, optionField)) {
-      return null;
-    }
-    boolean allowsMultiple = optionField.getAnnotation(Option.class).allowMultiple();
-    // If the option allows multiple values then we intentionally return the empty list as
-    // the default value of this option since it is not always the case that an option
-    // that allows multiple values will have a converter that returns a list value.
-    if (allowsMultiple) {
-      return Collections.emptyList();
-    }
-    // Otherwise try to convert the default value using the converter
-    Object convertedValue;
-    try {
-      convertedValue = converter.convert(defaultValueAsString);
-    } catch (OptionsParsingException e) {
-      throw new IllegalStateException("OptionsParsingException while "
-          + "retrieving default for " + optionField.getName() + ": "
-          + e.getMessage());
-    }
-    return convertedValue;
-  }
-
-  static OptionsData of(Collection<Class<? extends OptionsBase>> classes) {
-    Map<Class<? extends OptionsBase>, Constructor<?>> constructorBuilder = Maps.newHashMap();
-    Map<Class<? extends OptionsBase>, List<Field>> allOptionsFieldsBuilder = Maps.newHashMap();
-    Map<String, Field> nameToFieldBuilder = Maps.newHashMap();
-    Map<Character, Field> abbrevToFieldBuilder = Maps.newHashMap();
-    Map<Field, Object> optionDefaultsBuilder = Maps.newHashMap();
-    Map<Field, Converter<?>> convertersBuilder = Maps.newHashMap();
-    Map<Field, Boolean> allowMultipleBuilder = Maps.newHashMap();
-
-    // Read all Option annotations:
-    for (Class<? extends OptionsBase> parsedOptionsClass : classes) {
-      try {
-        Constructor<? extends OptionsBase> constructor =
-            parsedOptionsClass.getConstructor(new Class[0]);
-        constructorBuilder.put(parsedOptionsClass, constructor);
-      } catch (NoSuchMethodException e) {
-        throw new IllegalArgumentException(parsedOptionsClass
-            + " lacks an accessible default constructor");
-      }
-      List<Field> fields = getAllAnnotatedFields(parsedOptionsClass);
-      allOptionsFieldsBuilder.put(parsedOptionsClass, fields);
-
-      for (Field field : fields) {
-        Option annotation = field.getAnnotation(Option.class);
-
-        // Check that the field type is a List, and that the converter
-        // type matches the element type of the list.
-        Type fieldType = field.getGenericType();
-        if (annotation.allowMultiple()) {
-          if (!(fieldType instanceof ParameterizedType)) {
-            throw new AssertionError("Type of multiple occurrence option must be a List<...>");
-          }
-          ParameterizedType pfieldType = (ParameterizedType) fieldType;
-          if (pfieldType.getRawType() != List.class) {
-            // Throw an assertion, because this indicates an undetected type
-            // error in the code.
-            throw new AssertionError("Type of multiple occurrence option must be a List<...>");
-          }
-          fieldType = pfieldType.getActualTypeArguments()[0];
-        }
-
-        // Get the converter return type.
-        @SuppressWarnings("rawtypes")
-        Class<? extends Converter> converter = annotation.converter();
-        if (converter == Converter.class) {
-          Converter<?> actualConverter = OptionsParserImpl.DEFAULT_CONVERTERS.get(fieldType);
-          if (actualConverter == null) {
-            throw new AssertionError("Cannot find converter for field of type "
-                + field.getType() + " named " + field.getName()
-                + " in class " + field.getDeclaringClass().getName());
-          }
-          converter = actualConverter.getClass();
-        }
-        if (Modifier.isAbstract(converter.getModifiers())) {
-          throw new AssertionError("The converter type (" + converter
-              + ") must be a concrete type");
-        }
-        Type converterResultType;
-        try {
-          Method convertMethod = converter.getMethod("convert", String.class);
-          converterResultType = GenericTypeHelper.getActualReturnType(converter, convertMethod);
-        } catch (NoSuchMethodException e) {
-          throw new AssertionError("A known converter object doesn't implement the convert"
-              + " method");
-        }
-
-        if (annotation.allowMultiple()) {
-          if (GenericTypeHelper.getRawType(converterResultType) == List.class) {
-            Type elementType =
-                ((ParameterizedType) converterResultType).getActualTypeArguments()[0];
-            if (!GenericTypeHelper.isAssignableFrom(fieldType, elementType)) {
-              throw new AssertionError("If the converter return type of a multiple occurance " +
-                  "option is a list, then the type of list elements (" + fieldType + ") must be " +
-                  "assignable from the converter list element type (" + elementType + ")");
-            }
-          } else {
-            if (!GenericTypeHelper.isAssignableFrom(fieldType, converterResultType)) {
-              throw new AssertionError("Type of list elements (" + fieldType +
-                  ") for multiple occurrence option must be assignable from the converter " +
-                  "return type (" + converterResultType + ")");
-            }
-          }
-        } else {
-          if (!GenericTypeHelper.isAssignableFrom(fieldType, converterResultType)) {
-            throw new AssertionError("Type of field (" + fieldType +
-                ") must be assignable from the converter " +
-                "return type (" + converterResultType + ")");
-          }
-        }
-
-        if (annotation.name() == null) {
+    // All that's left is to compute expansions.
+    Map<Field, String[]> evaluatedExpansionsBuilder = Maps.newHashMap();
+    for (Map.Entry<String, Field> entry : isolatedData.getAllNamedFields()) {
+      Field field = entry.getValue();
+      Option annotation = field.getAnnotation(Option.class);
+      // Determine either the hard-coded expansion, or the ExpansionFunction class.
+      String[] constExpansion = annotation.expansion();
+      Class<? extends ExpansionFunction> expansionFunctionClass = annotation.expansionFunction();
+      if (constExpansion.length > 0 && usesExpansionFunction(annotation)) {
+        throw new AssertionError(
+            "Cannot set both expansion and expansionFunction for option --" + annotation.name());
+      } else if (constExpansion.length > 0) {
+        evaluatedExpansionsBuilder.put(field, constExpansion);
+      } else if (usesExpansionFunction(annotation)) {
+        if (Modifier.isAbstract(expansionFunctionClass.getModifiers())) {
           throw new AssertionError(
-              "Option cannot have a null name");
+              "The expansionFunction type " + expansionFunctionClass + " must be a concrete type");
         }
-        if (nameToFieldBuilder.put(annotation.name(), field) != null) {
-          throw new DuplicateOptionDeclarationException(
-              "Duplicate option name: --" + annotation.name());
+        // Evaluate the ExpansionFunction.
+        ExpansionFunction instance;
+        try {
+          Constructor<?> constructor = expansionFunctionClass.getConstructor();
+          instance = (ExpansionFunction) constructor.newInstance();
+        } catch (Exception e) {
+          // This indicates an error in the ExpansionFunction, and should be discovered the first
+          // time it is used.
+          throw new AssertionError(e);
         }
-        if (!annotation.oldName().isEmpty()) {
-          if (nameToFieldBuilder.put(annotation.oldName(), field) != null) {
-            throw new DuplicateOptionDeclarationException(
-                "Old option name duplicates option name: --" + annotation.oldName());
-          }
-        }
-        if (annotation.abbrev() != '\0') {
-          if (abbrevToFieldBuilder.put(annotation.abbrev(), field) != null) {
-            throw new DuplicateOptionDeclarationException(
-                  "Duplicate option abbrev: -" + annotation.abbrev());
-          }
-        }
-
-        optionDefaultsBuilder.put(field, retrieveDefaultFromAnnotation(field));
-
-        convertersBuilder.put(field, OptionsParserImpl.findConverter(field));
-
-        allowMultipleBuilder.put(field, annotation.allowMultiple());
+        String[] expansion = instance.getExpansion(isolatedData);
+        evaluatedExpansionsBuilder.put(field, expansion);
       }
     }
-    return new OptionsData(constructorBuilder, nameToFieldBuilder, abbrevToFieldBuilder,
-        allOptionsFieldsBuilder, optionDefaultsBuilder, convertersBuilder, allowMultipleBuilder);
+
+    return new OptionsData(isolatedData, evaluatedExpansionsBuilder);
   }
 }
diff --git a/java/com/google/devtools/common/options/OptionsParser.java b/java/com/google/devtools/common/options/OptionsParser.java
index 946d73b..1c4b278 100644
--- a/java/com/google/devtools/common/options/OptionsParser.java
+++ b/java/com/google/devtools/common/options/OptionsParser.java
@@ -88,7 +88,7 @@
       ImmutableList<Class<? extends OptionsBase>> optionsClasses) {
     OptionsData result = optionsData.get(optionsClasses);
     if (result == null) {
-      result = OptionsData.of(optionsClasses);
+      result = OptionsData.from(optionsClasses);
       optionsData.put(optionsClasses, result);
     }
     return result;
@@ -140,10 +140,6 @@
   private final List<String> residue = new ArrayList<String>();
   private boolean allowResidue = true;
 
-  OptionsParser(Collection<Class<? extends OptionsBase>> optionsClasses) {
-    this(OptionsData.of(optionsClasses));
-  }
-
   OptionsParser(OptionsData optionsData) {
     impl = new OptionsParserImpl(optionsData);
   }
@@ -395,12 +391,14 @@
     }
 
     public boolean isHidden() {
-      return documentationLevel() == DocumentationLevel.HIDDEN;
+      return documentationLevel() == DocumentationLevel.HIDDEN
+          || documentationLevel() == DocumentationLevel.INTERNAL;
     }
 
     boolean isExpansion() {
       Option option = field.getAnnotation(Option.class);
-      return option.expansion().length > 0;
+      return (option.expansion().length > 0
+          || OptionsData.usesExpansionFunction(option));
     }
 
     boolean isImplicitRequirement() {
@@ -455,28 +453,27 @@
    *
    * <p>We use 'hidden' so that options that form the protocol between the
    * client and the server are not logged.
+   *
+   * <p>Options which are 'internal' are not recognized by the parser at all.
    */
   enum DocumentationLevel {
-    DOCUMENTED, UNDOCUMENTED, HIDDEN
+    DOCUMENTED, UNDOCUMENTED, HIDDEN, INTERNAL
   }
 
   /**
-   * Returns a description of all the options this parser can digest.
-   * In addition to {@link Option} annotations, this method also
-   * interprets {@link OptionsUsage} annotations which give an intuitive short
-   * description for the options.
+   * Returns a description of all the options this parser can digest. In addition to {@link Option}
+   * annotations, this method also interprets {@link OptionsUsage} annotations which give an
+   * intuitive short description for the options. Options of the same category (see {@link
+   * Option#category}) will be grouped together.
    *
-   * @param categoryDescriptions a mapping from category names to category
-   *   descriptions.  Options of the same category (see {@link
-   *   Option#category}) will be grouped together, preceded by the description
-   *   of the category.
-   * @param helpVerbosity if {@code long}, the options will be described
-   *   verbosely, including their types, defaults and descriptions.  If {@code
-   *   medium}, the descriptions are omitted, and if {@code short}, the options
-   *   are just enumerated.
+   * @param categoryDescriptions a mapping from category names to category descriptions.
+   *     Descriptions are optional; if omitted, a string based on the category name will be used.
+   * @param helpVerbosity if {@code long}, the options will be described verbosely, including their
+   *     types, defaults and descriptions. If {@code medium}, the descriptions are omitted, and if
+   *     {@code short}, the options are just enumerated.
    */
-  public String describeOptions(Map<String, String> categoryDescriptions,
-                                HelpVerbosity helpVerbosity) {
+  public String describeOptions(
+      Map<String, String> categoryDescriptions, HelpVerbosity helpVerbosity) {
     StringBuilder desc = new StringBuilder();
     if (!impl.getOptionsClasses().isEmpty()) {
       List<Field> allFields = Lists.newArrayList();
@@ -500,7 +497,7 @@
         }
 
         if (documentationLevel(prevCategory) == DocumentationLevel.DOCUMENTED) {
-          OptionsUsage.getUsage(optionField, desc, helpVerbosity);
+          OptionsUsage.getUsage(optionField, desc, helpVerbosity, impl.getOptionsData());
         }
       }
     }
@@ -545,7 +542,7 @@
         }
 
         if (level == DocumentationLevel.DOCUMENTED) {
-          OptionsUsage.getUsageHtml(optionField, desc, escaper);
+          OptionsUsage.getUsageHtml(optionField, desc, escaper, impl.getOptionsData());
         }
       }
       desc.append("</dl>\n");
@@ -614,6 +611,8 @@
       return DocumentationLevel.UNDOCUMENTED;
     } else if ("hidden".equals(category)) {
       return DocumentationLevel.HIDDEN;
+    } else if ("internal".equals(category)) {
+      return DocumentationLevel.INTERNAL;
     } else {
       return DocumentationLevel.DOCUMENTED;
     }
diff --git a/java/com/google/devtools/common/options/OptionsParserImpl.java b/java/com/google/devtools/common/options/OptionsParserImpl.java
index c15f927..5c6498a 100644
--- a/java/com/google/devtools/common/options/OptionsParserImpl.java
+++ b/java/com/google/devtools/common/options/OptionsParserImpl.java
@@ -32,8 +32,6 @@
 import com.google.devtools.common.options.OptionsParser.UnparsedOptionValueDescription;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -50,100 +48,6 @@
  */
 class OptionsParserImpl {
 
-  /**
-   * A bunch of default converters in case the user doesn't specify a
-   * different one in the field annotation.
-   */
-  static final Map<Class<?>, Converter<?>> DEFAULT_CONVERTERS = Maps.newHashMap();
-
-  static {
-    DEFAULT_CONVERTERS.put(String.class, new Converter<String>() {
-      @Override
-      public String convert(String input) {
-        return input;
-      }
-      @Override
-      public String getTypeDescription() {
-        return "a string";
-      }});
-    DEFAULT_CONVERTERS.put(int.class, new Converter<Integer>() {
-      @Override
-      public Integer convert(String input) throws OptionsParsingException {
-        try {
-          return Integer.decode(input);
-        } catch (NumberFormatException e) {
-          throw new OptionsParsingException("'" + input + "' is not an int");
-        }
-      }
-      @Override
-      public String getTypeDescription() {
-        return "an integer";
-      }});
-    DEFAULT_CONVERTERS.put(double.class, new Converter<Double>() {
-      @Override
-      public Double convert(String input) throws OptionsParsingException {
-        try {
-          return Double.parseDouble(input);
-        } catch (NumberFormatException e) {
-          throw new OptionsParsingException("'" + input + "' is not a double");
-        }
-      }
-      @Override
-      public String getTypeDescription() {
-        return "a double";
-      }});
-    DEFAULT_CONVERTERS.put(boolean.class, new Converters.BooleanConverter());
-    DEFAULT_CONVERTERS.put(TriState.class, new Converter<TriState>() {
-      @Override
-      public TriState convert(String input) throws OptionsParsingException {
-        if (input == null) {
-          return TriState.AUTO;
-        }
-        input = input.toLowerCase();
-        if (input.equals("auto")) {
-          return TriState.AUTO;
-        }
-        if (input.equals("true") || input.equals("1") || input.equals("yes") ||
-            input.equals("t") || input.equals("y")) {
-          return TriState.YES;
-        }
-        if (input.equals("false") || input.equals("0") || input.equals("no") ||
-            input.equals("f") || input.equals("n")) {
-          return TriState.NO;
-        }
-        throw new OptionsParsingException("'" + input + "' is not a boolean");
-      }
-      @Override
-      public String getTypeDescription() {
-        return "a tri-state (auto, yes, no)";
-      }});
-    DEFAULT_CONVERTERS.put(Void.class, new Converter<Void>() {
-      @Override
-      public Void convert(String input) throws OptionsParsingException {
-        if (input == null) {
-          return null;  // expected input, return is unused so null is fine.
-        }
-        throw new OptionsParsingException("'" + input + "' unexpected");
-      }
-      @Override
-      public String getTypeDescription() {
-        return "";
-      }});
-    DEFAULT_CONVERTERS.put(long.class, new Converter<Long>() {
-      @Override
-      public Long convert(String input) throws OptionsParsingException {
-        try {
-          return Long.decode(input);
-        } catch (NumberFormatException e) {
-          throw new OptionsParsingException("'" + input + "' is not a long");
-        }
-      }
-      @Override
-      public String getTypeDescription() {
-        return "a long integer";
-      }});
-  }
-
   private final OptionsData optionsData;
 
   /**
@@ -196,6 +100,10 @@
     this.optionsData = optionsData;
   }
 
+  OptionsData getOptionsData() {
+    return optionsData;
+  }
+
   /**
    * Indicates whether or not the parser will allow long options with a
    * single-dash, instead of the usual double-dash, too, eg. -example instead of just --example.
@@ -440,7 +348,8 @@
 
     // Recurse to remove any implicit or expansion flags that this flag may have added when
     // originally parsed.
-    for (String[] args : new String[][] {option.implicitRequirements(), option.expansion()}) {
+    String[] expansion = optionsData.getEvaluatedExpansion(field);
+    for (String[] args : new String[][] {option.implicitRequirements(), expansion}) {
       Iterator<String> argsIterator = Iterators.forArray(args);
       while (argsIterator.hasNext()) {
         String arg = argsIterator.next();
@@ -578,7 +487,8 @@
       }
 
       // Handle expansion options.
-      if (option.expansion().length > 0) {
+      String[] expansion = optionsData.getEvaluatedExpansion(field);
+      if (expansion.length > 0) {
         Function<Object, String> expansionSourceFunction =
             Functions.constant(
                 "expanded from option --"
@@ -587,7 +497,7 @@
                     + sourceFunction.apply(originalName));
         maybeAddDeprecationWarning(field);
         List<String> unparsed = parse(priority, expansionSourceFunction, null, originalName,
-            ImmutableList.copyOf(option.expansion()));
+            ImmutableList.copyOf(expansion));
         if (!unparsed.isEmpty()) {
           // Throw an assertion, because this indicates an error in the code that specified the
           // expansion for the current option.
@@ -701,7 +611,7 @@
         booleanValue = false;
         if (field != null) {
           // TODO(bazel-team): Add tests for these cases.
-          if (!OptionsParserImpl.isBooleanField(field)) {
+          if (!OptionsData.isBooleanField(field)) {
             throw new OptionsParsingException(
                 "Illegal use of 'no' prefix on non-boolean option: " + arg, arg);
           }
@@ -717,15 +627,18 @@
       throw new OptionsParsingException("Invalid options syntax: " + arg, arg);
     }
 
-    if (field == null) {
+    Option option = field == null ? null : field.getAnnotation(Option.class);
+
+    if (option == null
+        || OptionsParser.documentationLevel(option.category())
+            == OptionsParser.DocumentationLevel.INTERNAL) {
+      // This also covers internal options, which are treated as if they did not exist.
       throw new OptionsParsingException("Unrecognized option: " + arg, arg);
     }
 
-    Option option = field.getAnnotation(Option.class);
-
     if (value == null) {
       // Special-case boolean to supply value based on presence of "no" prefix.
-      if (OptionsParserImpl.isBooleanField(field)) {
+      if (OptionsData.isBooleanField(field)) {
         value = booleanValue ? "1" : "0";
       } else if (field.getType().equals(Void.class) && !option.wrapperOption()) {
         // This is expected, Void type options have no args (unless they're wrapper options).
@@ -782,46 +695,7 @@
     return annotation.defaultValue();
   }
 
-  static boolean isBooleanField(Field field) {
-    return field.getType().equals(boolean.class)
-        || field.getType().equals(TriState.class)
-        || findConverter(field) instanceof BoolOrEnumConverter;
-  }
-
-  static boolean isVoidField(Field field) {
-    return field.getType().equals(Void.class);
-  }
-
   static boolean isSpecialNullDefault(String defaultValueString, Field optionField) {
     return defaultValueString.equals("null") && !optionField.getType().isPrimitive();
   }
-
-  static Converter<?> findConverter(Field optionField) {
-    Option annotation = optionField.getAnnotation(Option.class);
-    if (annotation.converter() == Converter.class) {
-      Type type;
-      if (annotation.allowMultiple()) {
-        // The OptionParserImpl already checked that the type is List<T> for some T;
-        // here we extract the type T.
-        type = ((ParameterizedType) optionField.getGenericType()).getActualTypeArguments()[0];
-      } else {
-        type = optionField.getType();
-      }
-      Converter<?> converter = DEFAULT_CONVERTERS.get(type);
-      if (converter == null) {
-        throw new AssertionError("No converter found for "
-            + type + "; possible fix: add "
-            + "converter=... to @Option annotation for "
-            + optionField.getName());
-      }
-      return converter;
-    }
-    try {
-      Class<?> converter = annotation.converter();
-      Constructor<?> constructor = converter.getConstructor(new Class<?>[0]);
-      return (Converter<?>) constructor.newInstance(new Object[0]);
-    } catch (Exception e) {
-      throw new AssertionError(e);
-    }
-  }
 }
diff --git a/java/com/google/devtools/common/options/OptionsUsage.java b/java/com/google/devtools/common/options/OptionsUsage.java
index b8c19df..aa48cb7 100644
--- a/java/com/google/devtools/common/options/OptionsUsage.java
+++ b/java/com/google/devtools/common/options/OptionsUsage.java
@@ -13,19 +13,17 @@
 // limitations under the License.
 package com.google.devtools.common.options;
 
-import static com.google.devtools.common.options.OptionsParserImpl.findConverter;
-
 import com.google.common.base.Joiner;
 import com.google.common.base.Splitter;
 import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import com.google.common.escape.Escaper;
-
 import java.lang.reflect.Field;
 import java.text.BreakIterator;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import javax.annotation.Nullable;
 
 /**
  * A renderer for usage messages. For now this is very simple.
@@ -36,15 +34,17 @@
   private static final Joiner COMMA_JOINER = Joiner.on(",");
 
   /**
-   * Given an options class, render the usage string into the usage,
-   * which is passed in as an argument.
+   * Given an options class, render the usage string into the usage, which is passed in as an
+   * argument. This will not include information about expansions for options using expansion
+   * functions (it would be unsafe to report this as we cannot know what options from other {@link
+   * OptionsBase} subclasses they depend on until a complete parser is constructed).
    */
   static void getUsage(Class<? extends OptionsBase> optionsClass, StringBuilder usage) {
     List<Field> optionFields =
         Lists.newArrayList(OptionsParser.getAllAnnotatedFields(optionsClass));
     Collections.sort(optionFields, BY_NAME);
     for (Field optionField : optionFields) {
-      getUsage(optionField, usage, OptionsParser.HelpVerbosity.LONG);
+      getUsage(optionField, usage, OptionsParser.HelpVerbosity.LONG, null);
     }
   }
 
@@ -79,10 +79,35 @@
   }
 
   /**
-   * Append the usage message for a single option-field message to 'usage'.
+   * Returns the expansion for an option, to the extent known. Precisely, if an {@link OptionsData}
+   * object is supplied, the expansion is read from that. Otherwise, the annotation is inspected: If
+   * the annotation uses {@link Option#expansion} it is returned, and if it uses {@link
+   * Option#expansionFunction} null is returned, indicating a lack of definite information. In all
+   * cases, when the option is not an expansion option, an empty array is returned.
    */
-  static void getUsage(Field optionField, StringBuilder usage,
-                       OptionsParser.HelpVerbosity helpVerbosity) {
+  private static @Nullable String[] getExpansionIfKnown(
+      Field optionField, Option annotation, @Nullable OptionsData optionsData) {
+    if (optionsData != null) {
+      return optionsData.getEvaluatedExpansion(optionField);
+    } else {
+      if (OptionsData.usesExpansionFunction(annotation)) {
+        return null;
+      } else {
+        // Empty array if it's not an expansion option.
+        return annotation.expansion();
+      }
+    }
+  }
+
+  /**
+   * Appends the usage message for a single option-field message to 'usage'. If {@code optionsData}
+   * is not supplied, options that use expansion functions won't be fully described.
+   */
+  static void getUsage(
+      Field optionField,
+      StringBuilder usage,
+      OptionsParser.HelpVerbosity helpVerbosity,
+      @Nullable OptionsData optionsData) {
     String flagName = getFlagName(optionField);
     String typeDescription = getTypeDescription(optionField);
     Option annotation = optionField.getAnnotation(Option.class);
@@ -117,9 +142,12 @@
       usage.append(paragraphFill(annotation.help(), 4, 80)); // (indent, width)
       usage.append('\n');
     }
-    if (annotation.expansion().length > 0) {
+    String[] expansion = getExpansionIfKnown(optionField, annotation, optionsData);
+    if (expansion == null) {
+      usage.append("    Expands to unknown options.\n");
+    } else if (expansion.length > 0) {
       StringBuilder expandsMsg = new StringBuilder("Expands to: ");
-      for (String exp : annotation.expansion()) {
+      for (String exp : expansion) {
         expandsMsg.append(exp).append(" ");
       }
       usage.append(paragraphFill(expandsMsg.toString(), 4, 80)); // (indent, width)
@@ -128,9 +156,11 @@
   }
 
   /**
-   * Append the usage message for a single option-field message to 'usage'.
+   * Append the usage message for a single option-field message to 'usage'. If {@code optionsData}
+   * is not supplied, options that use expansion functions won't be fully described.
    */
-  static void getUsageHtml(Field optionField, StringBuilder usage, Escaper escaper) {
+  static void getUsageHtml(
+      Field optionField, StringBuilder usage, Escaper escaper, @Nullable OptionsData optionsData) {
     String plainFlagName = optionField.getAnnotation(Option.class).name();
     String flagName = getFlagName(optionField);
     String valueDescription = optionField.getAnnotation(Option.class).valueHelp();
@@ -138,8 +168,7 @@
     Option annotation = optionField.getAnnotation(Option.class);
     usage.append("<dt><code><a name=\"flag--").append(plainFlagName).append("\"></a>--");
     usage.append(flagName);
-    if (OptionsParserImpl.isBooleanField(optionField)
-        || OptionsParserImpl.isVoidField(optionField)) {
+    if (OptionsData.isBooleanField(optionField) || OptionsData.isVoidField(optionField)) {
       // Nothing for boolean, tristate, boolean_or_enum, or void options.
     } else if (!valueDescription.isEmpty()) {
       usage.append("=").append(escaper.escape(valueDescription));
@@ -157,7 +186,7 @@
     } else {
       // Don't call the annotation directly (we must allow overrides to certain defaults).
       String defaultValueString = OptionsParserImpl.getDefaultOptionString(optionField);
-      if (OptionsParserImpl.isVoidField(optionField)) {
+      if (OptionsData.isVoidField(optionField)) {
         // Void options don't have a default.
       } else if (OptionsParserImpl.isSpecialNullDefault(defaultValueString, optionField)) {
         usage.append(" default: see description");
@@ -171,10 +200,13 @@
       usage.append(paragraphFill(escaper.escape(annotation.help()), 0, 80)); // (indent, width)
       usage.append('\n');
     }
-    if (annotation.expansion().length > 0) {
+    String[] expansion = getExpansionIfKnown(optionField, annotation, optionsData);
+    if (expansion == null) {
+      usage.append("    Expands to unknown options.<br>\n");
+    } else if (expansion.length > 0) {
       usage.append("<br/>\n");
       StringBuilder expandsMsg = new StringBuilder("Expands to:<br/>\n");
-      for (String exp : annotation.expansion()) {
+      for (String exp : expansion) {
         // TODO(ulfjack): Can we link to the expanded flags here?
         expandsMsg
             .append("&nbsp;&nbsp;<code>")
@@ -259,12 +291,12 @@
   };
 
   private static String getTypeDescription(Field optionsField) {
-    return findConverter(optionsField).getTypeDescription();
+    return OptionsData.findConverter(optionsField).getTypeDescription();
   }
 
   static String getFlagName(Field field) {
     String name = field.getAnnotation(Option.class).name();
-    return OptionsParserImpl.isBooleanField(field) ? "[no]" + name : name;
+    return OptionsData.isBooleanField(field) ? "[no]" + name : name;
   }
 
 }
