diff --git a/src/main/java/com/google/devtools/common/options/Converter.java b/src/main/java/com/google/devtools/common/options/Converter.java
new file mode 100644
index 0000000..867ef82
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/Converter.java
@@ -0,0 +1,33 @@
+// Copyright 2014 Google Inc. 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 converter is a little helper object that can take a String and
+ * turn it into an instance of type T (the type parameter to the converter).
+ */
+public interface Converter<T> {
+
+  /**
+   * Convert a string into type T.
+   */
+  T convert(String input) throws OptionsParsingException;
+
+  /**
+   * The type description appears in usage messages. E.g.: "a string",
+   * "a path", etc.
+   */
+  String getTypeDescription();
+
+}
diff --git a/src/main/java/com/google/devtools/common/options/Converters.java b/src/main/java/com/google/devtools/common/options/Converters.java
new file mode 100644
index 0000000..e8c69ec
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/Converters.java
@@ -0,0 +1,326 @@
+// Copyright 2014 Google Inc. 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.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;
+import java.util.logging.Level;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+/**
+ * Some convenient converters used by blaze. Note: These are specific to
+ * blaze.
+ */
+public final class Converters {
+
+  /**
+   * Join a list of words as in English.  Examples:
+   * "nothing"
+   * "one"
+   * "one or two"
+   * "one and two"
+   * "one, two or three".
+   * "one, two and three".
+   * The toString method of each element is used.
+   */
+  static String joinEnglishList(Iterable<?> choices) {
+    StringBuilder buf = new StringBuilder();
+    for (Iterator<?> ii = choices.iterator(); ii.hasNext(); ) {
+      Object choice = ii.next();
+      if (buf.length() > 0) {
+        buf.append(ii.hasNext() ? ", " : " or ");
+      }
+      buf.append(choice);
+    }
+    return buf.length() == 0 ? "nothing" : buf.toString();
+  }
+
+  public static class SeparatedOptionListConverter
+      implements Converter<List<String>> {
+
+    private final String separatorDescription;
+    private final Splitter splitter;
+
+    protected SeparatedOptionListConverter(char separator,
+                                           String separatorDescription) {
+      this.separatorDescription = separatorDescription;
+      this.splitter = Splitter.on(separator);
+    }
+
+    @Override
+    public List<String> convert(String input) {
+      return input.equals("")
+          ? ImmutableList.<String>of()
+          : ImmutableList.copyOf(splitter.split(input));
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return separatorDescription + "-separated list of options";
+    }
+  }
+
+  public static class CommaSeparatedOptionListConverter
+      extends SeparatedOptionListConverter {
+    public CommaSeparatedOptionListConverter() {
+      super(',', "comma");
+    }
+  }
+
+  public static class ColonSeparatedOptionListConverter extends SeparatedOptionListConverter {
+    public ColonSeparatedOptionListConverter() {
+      super(':', "colon");
+    }
+  }
+
+  public static class LogLevelConverter implements Converter<Level> {
+
+    public static Level[] LEVELS = new Level[] {
+      Level.OFF, Level.SEVERE, Level.WARNING, Level.INFO, Level.FINE,
+      Level.FINER, Level.FINEST
+    };
+
+    @Override
+    public Level convert(String input) throws OptionsParsingException {
+      try {
+        int level = Integer.parseInt(input);
+        return LEVELS[level];
+      } catch (NumberFormatException e) {
+        throw new OptionsParsingException("Not a log level: " + input);
+      } catch (ArrayIndexOutOfBoundsException e) {
+        throw new OptionsParsingException("Not a log level: " + input);
+      }
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "0 <= an integer <= " + (LEVELS.length - 1);
+    }
+
+  }
+
+  /**
+   * Checks whether a string is part of a set of strings.
+   */
+  public static class StringSetConverter implements Converter<String> {
+
+    // TODO(bazel-team): if this class never actually contains duplicates, we could s/List/Set/
+    // here.
+    private final List<String> values;
+
+    public StringSetConverter(String... values) {
+      this.values = ImmutableList.copyOf(values);
+    }
+
+    @Override
+    public String convert(String input) throws OptionsParsingException {
+      if (values.contains(input)) {
+        return input;
+      }
+
+      throw new OptionsParsingException("Not one of " + values);
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return joinEnglishList(values);
+    }
+  }
+
+  /**
+   * Checks whether a string is a valid regex pattern and compiles it.
+   */
+  public static class RegexPatternConverter implements Converter<Pattern> {
+
+    @Override
+    public Pattern convert(String input) throws OptionsParsingException {
+      try {
+        return Pattern.compile(input);
+      } catch (PatternSyntaxException e) {
+        throw new OptionsParsingException("Not a valid regular expression: " + e.getMessage());
+      }
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "a valid Java regular expression";
+    }
+  }
+
+  /**
+   * Limits the length of a string argument.
+   */
+  public static class LengthLimitingConverter implements Converter<String> {
+    private final int maxSize;
+
+    public LengthLimitingConverter(int maxSize) {
+      this.maxSize = maxSize;
+    }
+
+    @Override
+    public String convert(String input) throws OptionsParsingException {
+      if (input.length() > maxSize) {
+        throw new OptionsParsingException("Input must be " + getTypeDescription());
+      }
+      return input;
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "a string <= " + maxSize + " characters";
+    }
+  }
+
+  /**
+   * Checks whether an integer is in the given range.
+   */
+  public static class RangeConverter implements Converter<Integer> {
+    final int minValue;
+    final int maxValue;
+
+    public RangeConverter(int minValue, int maxValue) {
+      this.minValue = minValue;
+      this.maxValue = maxValue;
+    }
+
+    @Override
+    public Integer convert(String input) throws OptionsParsingException {
+      try {
+        Integer value = Integer.parseInt(input);
+        if (value < minValue) {
+          throw new OptionsParsingException("'" + input + "' should be >= " + minValue);
+        } else if (value < minValue || value > maxValue) {
+          throw new OptionsParsingException("'" + input + "' should be <= " + maxValue);
+        }
+        return value;
+      } catch (NumberFormatException e) {
+        throw new OptionsParsingException("'" + input + "' is not an int");
+      }
+    }
+
+    @Override
+    public String getTypeDescription() {
+      if (minValue == Integer.MIN_VALUE) {
+        if (maxValue == Integer.MAX_VALUE) {
+          return "an integer";
+        } else {
+          return "an integer, <= " + maxValue;
+        }
+      } else if (maxValue == Integer.MAX_VALUE) {
+        return "an integer, >= " + minValue;
+      } else {
+        return "an integer in "
+            + (minValue < 0 ? "(" + minValue + ")" : minValue) + "-" + maxValue + " range";
+      }
+    }
+  }
+
+  /**
+   * A converter for variable assignments from the parameter list of a blaze
+   * command invocation. Assignments are expected to have the form "name=value",
+   * where names and values are defined to be as permissive as possible.
+   */
+  public static class AssignmentConverter implements Converter<Map.Entry<String, String>> {
+
+    @Override
+    public Map.Entry<String, String> convert(String input)
+        throws OptionsParsingException {
+      int pos = input.indexOf("=");
+      if (pos <= 0) {
+        throw new OptionsParsingException("Variable definitions must be in the form of a "
+            + "'name=value' assignment");
+      }
+      String name = input.substring(0, pos);
+      String value = input.substring(pos + 1);
+      return Maps.immutableEntry(name, value);
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "a 'name=value' assignment";
+    }
+
+  }
+
+  /**
+   * A converter for variable assignments from the parameter list of a blaze
+   * command invocation. Assignments are expected to have the form "name[=value]",
+   * where names and values are defined to be as permissive as possible and value
+   * part can be optional (in which case it is considered to be null).
+   */
+  public static class OptionalAssignmentConverter implements Converter<Map.Entry<String, String>> {
+
+    @Override
+    public Map.Entry<String, String> convert(String input)
+        throws OptionsParsingException {
+      int pos = input.indexOf("=");
+      if (pos == 0 || input.length() == 0) {
+        throw new OptionsParsingException("Variable definitions must be in the form of a "
+            + "'name=value' or 'name' assignment");
+      } else if (pos < 0) {
+        return Maps.immutableEntry(input, null);
+      }
+      String name = input.substring(0, pos);
+      String value = input.substring(pos + 1);
+      return Maps.immutableEntry(name, value);
+    }
+
+    @Override
+    public String getTypeDescription() {
+      return "a 'name=value' assignment with an optional value part";
+    }
+
+  }
+
+  public static class HelpVerbosityConverter extends EnumConverter<OptionsParser.HelpVerbosity> {
+    public HelpVerbosityConverter() {
+      super(OptionsParser.HelpVerbosity.class, "--help_verbosity setting");
+    }
+  }
+
+  /**
+   * 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/src/main/java/com/google/devtools/common/options/DuplicateOptionDeclarationException.java b/src/main/java/com/google/devtools/common/options/DuplicateOptionDeclarationException.java
new file mode 100644
index 0000000..b4e572e
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/DuplicateOptionDeclarationException.java
@@ -0,0 +1,26 @@
+// Copyright 2014 Google Inc. 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;
+
+/**
+ * Indicates that an option is declared in more than one class.
+ */
+public class DuplicateOptionDeclarationException extends RuntimeException {
+
+  DuplicateOptionDeclarationException(String message) {
+    super(message);
+  }
+
+}
diff --git a/src/main/java/com/google/devtools/common/options/EnumConverter.java b/src/main/java/com/google/devtools/common/options/EnumConverter.java
new file mode 100644
index 0000000..f65241a
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/EnumConverter.java
@@ -0,0 +1,74 @@
+// Copyright 2014 Google Inc. 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 java.util.Arrays;
+
+/**
+ * A converter superclass for converters that parse enums.
+ *
+ * Just subclass this class, creating a zero aro argument constructor that
+ * calls {@link #EnumConverter(Class, String)}.
+ *
+ * This class compares the input string to the string returned by the toString()
+ * method of each enum member in a case-insensitive way. Usually, this is the
+ * name of the symbol, but beware if you override toString()!
+ */
+public abstract class EnumConverter<T extends Enum<T>>
+    implements Converter<T> {
+
+  private final Class<T> enumType;
+  private final String typeName;
+
+  /**
+   * Creates a new enum converter. You *must* implement a zero-argument
+   * constructor that delegates to this constructor, passing in the appropriate
+   * parameters.
+   *
+   * @param enumType The type of your enumeration; usually a class literal
+   *                 like MyEnum.class
+   * @param typeName The intuitive name of your enumeration, for example, the
+   *                 type name for CompilationMode might be "compilation mode".
+   */
+  protected EnumConverter(Class<T> enumType, String typeName) {
+    this.enumType = enumType;
+    this.typeName = typeName;
+  }
+
+  /**
+   * Implements {@link #convert(String)}.
+   */
+  @Override
+  public final T convert(String input) throws OptionsParsingException {
+    for (T value : enumType.getEnumConstants()) {
+      if (value.toString().equalsIgnoreCase(input)) {
+        return value;
+      }
+    }
+    throw new OptionsParsingException("Not a valid " + typeName + ": '"
+                                      + input + "' (should be "
+                                      + getTypeDescription() + ")");
+  }
+
+  /**
+   * Implements {@link #getTypeDescription()}.
+   */
+  @Override
+  public final String getTypeDescription() {
+    return Converters.joinEnglishList(
+        Arrays.asList(enumType.getEnumConstants())).toLowerCase();
+  }
+
+}
diff --git a/src/main/java/com/google/devtools/common/options/GenericTypeHelper.java b/src/main/java/com/google/devtools/common/options/GenericTypeHelper.java
new file mode 100644
index 0000000..2240860
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/GenericTypeHelper.java
@@ -0,0 +1,133 @@
+// Copyright 2014 Google Inc. 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.annotations.VisibleForTesting;
+import com.google.common.primitives.Primitives;
+import com.google.common.reflect.TypeToken;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+/**
+ * A helper class for {@link OptionsParserImpl} to help checking the return type
+ * of a {@link Converter} against the type of a field or the element type of a
+ * list.
+ *
+ * <p>This class has to go through considerable contortion to get the correct result
+ * from the Java reflection system, unfortunately. If the generic reflection part
+ * had been better designed, some of this would not be necessary.
+ */
+class GenericTypeHelper {
+
+  /**
+   * Returns the raw type of t, if t is either a raw or parameterized type.
+   * Otherwise, this method throws an {@link AssertionError}.
+   */
+  @VisibleForTesting
+  static Class<?> getRawType(Type t) {
+    if (t instanceof Class<?>) {
+      return (Class<?>) t;
+    } else if (t instanceof ParameterizedType) {
+      return (Class<?>) ((ParameterizedType) t).getRawType();
+    } else {
+      throw new AssertionError("A known concrete type is not concrete");
+    }
+  }
+
+  /**
+   * If type is a parameterized type, searches the given type variable in the list
+   * of declared type variables, and then returns the corresponding actual type.
+   * Returns null if the type variable is not defined by type.
+   */
+  private static Type matchTypeVariable(Type type, TypeVariable<?> variable) {
+    if (type instanceof ParameterizedType) {
+      Class<?> rawInterfaceType = getRawType(type);
+      TypeVariable<?>[] typeParameters = rawInterfaceType.getTypeParameters();
+      for (int i = 0; i < typeParameters.length; i++) {
+        if (variable.equals(typeParameters[i])) {
+          return ((ParameterizedType) type).getActualTypeArguments()[i];
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Resolves the return type of a method, in particular if the generic return
+   * type ({@link Method#getGenericReturnType()}) is a type variable
+   * ({@link TypeVariable}), by checking all super-classes and directly
+   * implemented interfaces.
+   *
+   * <p>The method m must be defined by the given type or by its raw class type.
+   *
+   * @throws AssertionError if the generic return type could not be resolved
+   */
+  // TODO(bazel-team): also check enclosing classes and indirectly implemented
+  // interfaces, which can also contribute type variables. This doesn't happen
+  // in the existing use cases.
+  public static Type getActualReturnType(Type type, Method method) {
+    Type returnType = method.getGenericReturnType();
+    if (returnType instanceof Class<?>) {
+      return returnType;
+    } else if (returnType instanceof ParameterizedType) {
+      return returnType;
+    } else if (returnType instanceof TypeVariable<?>) {
+      TypeVariable<?> variable = (TypeVariable<?>) returnType;
+      while (type != null) {
+        Type candidate = matchTypeVariable(type, variable);
+        if (candidate != null) {
+          return candidate;
+        }
+
+        Class<?> rawType = getRawType(type);
+        for (Type interfaceType : rawType.getGenericInterfaces()) {
+          candidate = matchTypeVariable(interfaceType, variable);
+          if (candidate != null) {
+            return candidate;
+          }
+        }
+
+        type = rawType.getGenericSuperclass();
+      }
+    }
+    throw new AssertionError("The type " + returnType
+        + " is not a Class, ParameterizedType, or TypeVariable");
+  }
+
+  /**
+   * Determines if a value of a particular type (from) is assignable to a field of
+   * a particular type (to). Also allows assigning wrapper types to primitive
+   * types.
+   *
+   * <p>The checks done here should be identical to the checks done by
+   * {@link java.lang.reflect.Field#set}. I.e., if this method returns true, a
+   * subsequent call to {@link java.lang.reflect.Field#set} should succeed.
+   */
+  public static boolean isAssignableFrom(Type to, Type from) {
+    if (to instanceof Class<?>) {
+      Class<?> toClass = (Class<?>) to;
+      if (toClass.isPrimitive()) {
+        return Primitives.wrap(toClass).equals(from);
+      }
+    }
+    return TypeToken.of(to).isAssignableFrom(from);
+  }
+
+  private GenericTypeHelper() {
+    // Prevents Java from creating a public constructor.
+  }
+}
diff --git a/src/main/java/com/google/devtools/common/options/Option.java b/src/main/java/com/google/devtools/common/options/Option.java
new file mode 100644
index 0000000..e244736
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/Option.java
@@ -0,0 +1,127 @@
+// Copyright 2014 Google Inc. 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 java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * An interface for annotating fields in classes (derived from OptionsBase)
+ * that are options.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Option {
+
+  /**
+   * The name of the option ("--name").
+   */
+  String name();
+
+  /**
+   * The single-character abbreviation of the option ("-abbrev").
+   */
+  char abbrev() default '\0';
+
+  /**
+   * A help string for the usage information.
+   */
+  String help() 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.
+   *
+   * <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.
+   */
+  String defaultValue();
+
+  /**
+   * A string describing the category of options that this belongs to. {@link
+   * OptionsParser#describeOptions} prints options of the same category grouped
+   * together.
+   */
+  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.
+   */
+  @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.
+   *
+   * <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.
+   */
+  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}.
+   *
+   * 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.
+   *
+   * @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.
+   */
+  String deprecationWarning() default "";
+}
diff --git a/src/main/java/com/google/devtools/common/options/OptionPriority.java b/src/main/java/com/google/devtools/common/options/OptionPriority.java
new file mode 100644
index 0000000..6e90008
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/OptionPriority.java
@@ -0,0 +1,58 @@
+// Copyright 2014 Google Inc. 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;
+
+/**
+ * The priority of option values, in order of increasing priority.
+ *
+ * <p>In general, new values for options can only override values with a lower or
+ * equal priority. Option values provided in annotations in an options class are
+ * implicitly at the priority {@code DEFAULT}.
+ *
+ * <p>The ordering of the priorities is the source-code order. This is consistent
+ * with the automatically generated {@code compareTo} method as specified by the
+ * Java Language Specification. DO NOT change the source-code order of these
+ * values, or you will break code that relies on the ordering.
+ */
+public enum OptionPriority {
+
+  /**
+   * The priority of values specified in the {@link Option} annotation. This
+   * should never be specified in calls to {@link OptionsParser#parse}.
+   */
+  DEFAULT,
+
+  /**
+   * Overrides default options at runtime, while still allowing the values to be
+   * overridden manually.
+   */
+  COMPUTED_DEFAULT,
+
+  /**
+   * For options coming from a configuration file or rc file.
+   */
+  RC_FILE,
+
+  /**
+   * For options coming from the command line.
+   */
+  COMMAND_LINE,
+
+  /**
+   * This priority can be used to unconditionally override any user-provided options.
+   * This should be used rarely and with caution!
+   */
+  SOFTWARE_REQUIREMENT;
+
+}
diff --git a/src/main/java/com/google/devtools/common/options/Options.java b/src/main/java/com/google/devtools/common/options/Options.java
new file mode 100644
index 0000000..171be2e
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/Options.java
@@ -0,0 +1,104 @@
+// Copyright 2014 Google Inc. 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 java.util.Arrays;
+import java.util.List;
+
+/**
+ * Interface for parsing options from a single options specification class.
+ *
+ * The {@link Options#parse(Class, String...)} method in this class has no clear
+ * use case. Instead, use the {@link OptionsParser} class directly, as in this
+ * code snippet:
+ *
+ * <pre>
+ * OptionsParser parser = OptionsParser.newOptionsParser(FooOptions.class);
+ * try {
+ *   parser.parse(FooOptions.class, args);
+ * } catch (OptionsParsingException e) {
+ *   System.err.print("Error parsing options: " + e.getMessage());
+ *   System.err.print(options.getUsage());
+ *   System.exit(1);
+ * }
+ * FooOptions foo = parser.getOptions(FooOptions.class);
+ * List&lt;String&gt; otherArguments = parser.getResidue();
+ * </pre>
+ *
+ * Using this class in this case actually results in more code.
+ *
+ * @see OptionsParser for parsing options from multiple options specification classes.
+ */
+public class Options<O extends OptionsBase> {
+
+  /**
+   * Parse the options provided in args, given the specification in
+   * optionsClass.
+   */
+  public static <O extends OptionsBase> Options<O> parse(Class<O> optionsClass, String... args)
+      throws OptionsParsingException {
+    OptionsParser parser = OptionsParser.newOptionsParser(optionsClass);
+    parser.parse(OptionPriority.COMMAND_LINE, null, Arrays.asList(args));
+    List<String> remainingArgs = parser.getResidue();
+    return new Options<O>(parser.getOptions(optionsClass),
+                          remainingArgs.toArray(new String[0]));
+  }
+
+  /**
+   * Returns an options object at its default values.  The returned object may
+   * be freely modified by the caller, by assigning its fields.
+   */
+  public static <O extends OptionsBase> O getDefaults(Class<O> optionsClass) {
+    try {
+      return parse(optionsClass, new String[0]).getOptions();
+    } catch (OptionsParsingException e) {
+      String message = "Error while parsing defaults: " + e.getMessage();
+      throw new AssertionError(message);
+    }
+  }
+
+  /**
+   * Returns a usage string (renders the help information, the defaults, and
+   * of course the option names).
+   */
+  public static String getUsage(Class<? extends OptionsBase> optionsClass) {
+    StringBuilder usage = new StringBuilder();
+    OptionsUsage.getUsage(optionsClass, usage);
+    return usage.toString();
+  }
+
+  private O options;
+  private String[] remainingArgs;
+
+  private Options(O options, String[] remainingArgs) {
+    this.options = options;
+    this.remainingArgs = remainingArgs;
+  }
+
+  /**
+   * Returns an instance of options class O.
+   */
+  public O getOptions() {
+    return options;
+  }
+
+  /**
+   * Returns the arguments that we didn't parse.
+   */
+  public String[] getRemainingArgs() {
+    return remainingArgs;
+  }
+
+}
diff --git a/src/main/java/com/google/devtools/common/options/OptionsBase.java b/src/main/java/com/google/devtools/common/options/OptionsBase.java
new file mode 100644
index 0000000..ed9f215
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/OptionsBase.java
@@ -0,0 +1,118 @@
+// Copyright 2014 Google Inc. 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.escape.CharEscaperBuilder;
+import com.google.common.escape.Escaper;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * Base class for all options classes.  Extend this class, adding public
+ * instance fields annotated with @Option.  Then you can create instances
+ * either programmatically:
+ *
+ * <pre>
+ *   X x = Options.getDefaults(X.class);
+ *   x.host = "localhost";
+ *   x.port = 80;
+ * </pre>
+ *
+ * or from an array of command-line arguments:
+ *
+ * <pre>
+ *   OptionsParser parser = OptionsParser.newOptionsParser(X.class);
+ *   parser.parse("--host", "localhost", "--port", "80");
+ *   X x = parser.getOptions(X.class);
+ * </pre>
+ *
+ * <p>Subclasses of OptionsBase <b>must</b> be constructed reflectively,
+ * i.e. using not {@code new MyOptions}, but one of the two methods above
+ * instead.  (Direct construction creates an empty instance, not containing
+ * default values.  This leads to surprising behavior and often
+ * NullPointerExceptions, etc.)
+ */
+public abstract class OptionsBase {
+
+  private static final Escaper ESCAPER = new CharEscaperBuilder()
+      .addEscape('\\', "\\\\").addEscape('"', "\\\"").toEscaper();
+
+  /**
+   * Subclasses must provide a default (no argument) constructor.
+   */
+  protected OptionsBase() {
+    // There used to be a sanity check here that checks the stack trace of this constructor
+    // invocation; unfortunately, that makes the options construction about 10x slower. So be
+    // careful with how you construct options classes.
+  }
+
+  /**
+   * Returns this options object in the form of a (new) mapping from option
+   * names, including inherited ones, to option values.  If the public fields
+   * are mutated, this will be reflected in subsequent calls to {@code asMap}.
+   * Mutation of this map by the caller does not affect this options object.
+   */
+  public final Map<String, Object> asMap() {
+    return OptionsParserImpl.optionsAsMap(this);
+  }
+
+  @Override
+  public final String toString() {
+    return getClass().getName() + asMap();
+  }
+
+  /**
+   * Returns a string that uniquely identifies the options. This value is
+   * intended for analysis caching.
+   */
+  public final String cacheKey() {
+    StringBuilder result = new StringBuilder(getClass().getName()).append("{");
+
+    for (Entry<String, Object> entry : asMap().entrySet()) {
+      result.append(entry.getKey()).append("=");
+
+      Object value = entry.getValue();
+      // This special case is needed because List.toString() prints the same
+      // ("[]") for an empty list and for a list with a single empty string.
+      if (value instanceof List<?> && ((List<?>) value).isEmpty()) {
+        result.append("EMPTY");
+      } else if (value == null) {
+        result.append("NULL");
+      } else {
+        result
+            .append('"')
+            .append(ESCAPER.escape(value.toString()))
+            .append('"');
+      }
+      result.append(", ");
+    }
+
+    return result.append("}").toString();
+  }
+
+  @Override
+  public final boolean equals(Object that) {
+    return that != null &&
+        this.getClass() == that.getClass() &&
+        this.asMap().equals(((OptionsBase) that).asMap());
+  }
+
+  @Override
+  public final int hashCode() {
+    return this.getClass().hashCode() + asMap().hashCode();
+  }
+}
diff --git a/src/main/java/com/google/devtools/common/options/OptionsClassProvider.java b/src/main/java/com/google/devtools/common/options/OptionsClassProvider.java
new file mode 100644
index 0000000..1868e23
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/OptionsClassProvider.java
@@ -0,0 +1,29 @@
+// Copyright 2014 Google Inc. 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 read-only interface for options parser results, which only allows to query the options of
+ * a specific class, but not e.g. the residue any other information pertaining to the command line.
+ */
+public interface OptionsClassProvider {
+  /**
+   * Returns the options instance for the given {@code optionsClass}, that is,
+   * the parsed options, or null if it is not among those available.
+   *
+   * <p>The returned options should be treated by library code as immutable and
+   * a provider is permitted to return the same options instance multiple times.
+   */
+  <O extends OptionsBase> O getOptions(Class<O> optionsClass);
+}
diff --git a/src/main/java/com/google/devtools/common/options/OptionsData.java b/src/main/java/com/google/devtools/common/options/OptionsData.java
new file mode 100644
index 0000000..e9b6574
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/OptionsData.java
@@ -0,0 +1,264 @@
+// Copyright 2014 Google Inc. 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.
+ */
+@Immutable
+final class OptionsData {
+
+  /**
+   * These are the options-declaring classes which are annotated with
+   * {@link Option} annotations.
+   */
+  private final Map<Class<? extends OptionsBase>, Constructor<?>> optionsClasses;
+
+  /** Maps option name to Option-annotated Field. */
+  private final Map<String, Field> nameToField;
+
+  /** Maps option abbreviation to Option-annotated Field. */
+  private final Map<Character, Field> abbrevToField;
+
+  /**
+   * For each options class, contains a list of all Option-annotated fields in
+   * that class.
+   */
+  private final Map<Class<? extends OptionsBase>, List<Field>> allOptionsFields;
+
+  /**
+   * Mapping from each Option-annotated field to the default value for that
+   * field.
+   */
+  private final Map<Field, Object> optionDefaults;
+
+  /**
+   * Mapping from each Option-annotated field to the proper converter.
+   *
+   * @see OptionsParserImpl#findConverter
+   */
+  private final Map<Field, Converter<?>> converters;
+
+  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) {
+    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);
+  }
+
+  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);
+  }
+
+  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) {
+    Option annotation = optionField.getAnnotation(Option.class);
+    // If an option can be specified multiple times, its default value is a new empty list.
+    if (annotation.allowMultiple()) {
+      return Collections.emptyList();
+    }
+    String defaultValueString = OptionsParserImpl.getDefaultOptionString(optionField);
+    try {
+      return OptionsParserImpl.isSpecialNullDefault(defaultValueString, optionField)
+          ? null
+          : OptionsParserImpl.findConverter(optionField).convert(defaultValueString);
+    } catch (OptionsParsingException e) {
+      throw new IllegalStateException("OptionsParsingException while "
+          + "retrieving default for " + optionField.getName() + ": "
+          + e.getMessage());
+    }
+  }
+
+  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();
+
+    // 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) {
+          throw new AssertionError(
+              "Option cannot have a null name");
+        }
+        if (nameToFieldBuilder.put(annotation.name(), field) != null) {
+          throw new DuplicateOptionDeclarationException(
+              "Duplicate option name: --" + annotation.name());
+        }
+        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));
+      }
+    }
+    return new OptionsData(constructorBuilder, nameToFieldBuilder, abbrevToFieldBuilder,
+        allOptionsFieldsBuilder, optionDefaultsBuilder, convertersBuilder);
+  }
+}
diff --git a/src/main/java/com/google/devtools/common/options/OptionsParser.java b/src/main/java/com/google/devtools/common/options/OptionsParser.java
new file mode 100644
index 0000000..9564daa
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/OptionsParser.java
@@ -0,0 +1,526 @@
+// Copyright 2014 Google Inc. 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.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A parser for options. Typical use case in a main method:
+ *
+ * <pre>
+ * OptionsParser parser = OptionsParser.newOptionsParser(FooOptions.class, BarOptions.class);
+ * parser.parseAndExitUponError(args);
+ * FooOptions foo = parser.getOptions(FooOptions.class);
+ * BarOptions bar = parser.getOptions(BarOptions.class);
+ * List&lt;String&gt; otherArguments = parser.getResidue();
+ * </pre>
+ *
+ * <p>FooOptions and BarOptions would be options specification classes, derived
+ * from OptionsBase, that contain fields annotated with @Option(...).
+ *
+ * <p>Alternatively, rather than calling
+ * {@link #parseAndExitUponError(OptionPriority, String, String[])},
+ * client code may call {@link #parse(OptionPriority,String,List)}, and handle
+ * parser exceptions usage messages themselves.
+ *
+ * <p>This options parsing implementation has (at least) one design flaw. It
+ * allows both '--foo=baz' and '--foo baz' for all options except void, boolean
+ * and tristate options. For these, the 'baz' in '--foo baz' is not treated as
+ * a parameter to the option, making it is impossible to switch options between
+ * void/boolean/tristate and everything else without breaking backwards
+ * compatibility.
+ *
+ * @see Options a simpler class which you can use if you only have one options
+ * specification class
+ */
+public class OptionsParser implements OptionsProvider {
+
+  /**
+   * A cache for the parsed options data. Both keys and values are immutable, so
+   * this is always safe. Only access this field through the {@link
+   * #getOptionsData} method for thread-safety! The cache is very unlikely to
+   * grow to a significant amount of memory, because there's only a fixed set of
+   * options classes on the classpath.
+   */
+  private static final Map<ImmutableList<Class<? extends OptionsBase>>, OptionsData> optionsData =
+      Maps.newHashMap();
+
+  private static synchronized OptionsData getOptionsData(
+      ImmutableList<Class<? extends OptionsBase>> optionsClasses) {
+    OptionsData result = optionsData.get(optionsClasses);
+    if (result == null) {
+      result = OptionsData.of(optionsClasses);
+      optionsData.put(optionsClasses, result);
+    }
+    return result;
+  }
+
+  /**
+   * Returns all the annotated fields for the given class, including inherited
+   * ones.
+   */
+  static Collection<Field> getAllAnnotatedFields(Class<? extends OptionsBase> optionsClass) {
+    OptionsData data = getOptionsData(ImmutableList.<Class<? extends OptionsBase>>of(optionsClass));
+    return data.getFieldsForClass(optionsClass);
+  }
+
+  /**
+   * @see #newOptionsParser(Iterable)
+   */
+  public static OptionsParser newOptionsParser(Class<? extends OptionsBase> class1) {
+    return newOptionsParser(ImmutableList.<Class<? extends OptionsBase>>of(class1));
+  }
+
+  /**
+   * @see #newOptionsParser(Iterable)
+   */
+  public static OptionsParser newOptionsParser(Class<? extends OptionsBase> class1,
+                                               Class<? extends OptionsBase> class2) {
+    return newOptionsParser(ImmutableList.of(class1, class2));
+  }
+
+  /**
+   * Create a new {@link OptionsParser}.
+   */
+  public static OptionsParser newOptionsParser(
+      Iterable<Class<? extends OptionsBase>> optionsClasses) {
+    return new OptionsParser(getOptionsData(ImmutableList.copyOf(optionsClasses)));
+  }
+
+  /**
+   * Canonicalizes a list of options using the given option classes. The
+   * contract is that if the returned set of options is passed to an options
+   * parser with the same options classes, then that will have the same effect
+   * as using the original args (which are passed in here), except for cosmetic
+   * differences.
+   */
+  public static List<String> canonicalize(
+      Collection<Class<? extends OptionsBase>> optionsClasses, List<String> args)
+      throws OptionsParsingException {
+    OptionsParser parser = new OptionsParser(optionsClasses);
+    parser.setAllowResidue(false);
+    parser.parse(args);
+    return parser.impl.asCanonicalizedList();
+  }
+
+  private final OptionsParserImpl impl;
+  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);
+  }
+
+  /**
+   * Indicates whether or not the parser will allow a non-empty residue; that
+   * is, iff this value is true then a call to one of the {@code parse}
+   * methods will throw {@link OptionsParsingException} unless
+   * {@link #getResidue()} is empty after parsing.
+   */
+  public void setAllowResidue(boolean allowResidue) {
+    this.allowResidue = allowResidue;
+  }
+
+  /**
+   * 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.
+   */
+  public void setAllowSingleDashLongOptions(boolean allowSingleDashLongOptions) {
+    this.impl.setAllowSingleDashLongOptions(allowSingleDashLongOptions);
+  }
+
+  public void parseAndExitUponError(String[] args) {
+    parseAndExitUponError(OptionPriority.COMMAND_LINE, "unknown", args);
+  }
+
+  /**
+   * A convenience function for use in main methods. Parses the command line
+   * parameters, and exits upon error. Also, prints out the usage message
+   * if "--help" appears anywhere within {@code args}.
+   */
+  public void parseAndExitUponError(OptionPriority priority, String source, String[] args) {
+    try {
+      parse(priority, source, Arrays.asList(args));
+    } catch (OptionsParsingException e) {
+      System.err.println("Error parsing command line: " + e.getMessage());
+      System.err.println("Try --help.");
+      System.exit(2);
+    }
+    for (String arg : args) {
+      if (arg.equals("--help")) {
+        System.out.println(describeOptions(Collections.<String, String>emptyMap(),
+                                           HelpVerbosity.LONG));
+        System.exit(0);
+      }
+    }
+  }
+
+  /**
+   * The name and value of an option with additional metadata describing its
+   * priority, source, whether it was set via an implicit dependency, and if so,
+   * by which other option.
+   */
+  public static class OptionValueDescription {
+    private final String name;
+    private final Object value;
+    private final OptionPriority priority;
+    private final String source;
+    private final String implicitDependant;
+    private final String expandedFrom;
+
+    public OptionValueDescription(String name, Object value,
+        OptionPriority priority, String source, String implicitDependant, String expandedFrom) {
+      this.name = name;
+      this.value = value;
+      this.priority = priority;
+      this.source = source;
+      this.implicitDependant = implicitDependant;
+      this.expandedFrom = expandedFrom;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    public Object getValue() {
+      return value;
+    }
+
+    public OptionPriority getPriority() {
+      return priority;
+    }
+
+    public String getSource() {
+      return source;
+    }
+
+    public String getImplicitDependant() {
+      return implicitDependant;
+    }
+
+    public boolean isImplicitDependency() {
+      return implicitDependant != null;
+    }
+
+    public String getExpansionParent() {
+      return expandedFrom;
+    }
+
+    public boolean isExpansion() {
+      return expandedFrom != null;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder result = new StringBuilder();
+      result.append("option '").append(name).append("' ");
+      result.append("set to '").append(value).append("' ");
+      result.append("with priority ").append(priority);
+      if (source != null) {
+        result.append(" and source '").append(source).append("'");
+      }
+      if (implicitDependant != null) {
+        result.append(" implicitly by ");
+      }
+      return result.toString();
+    }
+  }
+
+  /**
+   * The name and unparsed value of an option with additional metadata describing its
+   * priority, source, whether it was set via an implicit dependency, and if so,
+   * by which other option.
+   *
+   * <p>Note that the unparsed value and the source parameters can both be null.
+   */
+  public static class UnparsedOptionValueDescription {
+    private final String name;
+    private final Field field;
+    private final String unparsedValue;
+    private final OptionPriority priority;
+    private final String source;
+    private final boolean explicit;
+
+    public UnparsedOptionValueDescription(String name, Field field, String unparsedValue,
+        OptionPriority priority, String source, boolean explicit) {
+      this.name = name;
+      this.field = field;
+      this.unparsedValue = unparsedValue;
+      this.priority = priority;
+      this.source = source;
+      this.explicit = explicit;
+    }
+
+    public String getName() {
+      return name;
+    }
+
+    Field getField() {
+      return field;
+    }
+
+    public boolean isBooleanOption() {
+      return field.getType().equals(boolean.class);
+    }
+
+    private DocumentationLevel documentationLevel() {
+      Option option = field.getAnnotation(Option.class);
+      return OptionsParser.documentationLevel(option.category());
+    }
+
+    public boolean isDocumented() {
+      return documentationLevel() == DocumentationLevel.DOCUMENTED;
+    }
+
+    public boolean isHidden() {
+      return documentationLevel() == DocumentationLevel.HIDDEN;
+    }
+
+    boolean isExpansion() {
+      Option option = field.getAnnotation(Option.class);
+      return option.expansion().length > 0;
+    }
+
+    boolean isImplicitRequirement() {
+      Option option = field.getAnnotation(Option.class);
+      return option.implicitRequirements().length > 0;
+    }
+
+    boolean allowMultiple() {
+      Option option = field.getAnnotation(Option.class);
+      return option.allowMultiple();
+    }
+
+    public String getUnparsedValue() {
+      return unparsedValue;
+    }
+
+    OptionPriority getPriority() {
+      return priority;
+    }
+
+    public String getSource() {
+      return source;
+    }
+
+    public boolean isExplicit() {
+      return explicit;
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder result = new StringBuilder();
+      result.append("option '").append(name).append("' ");
+      result.append("set to '").append(unparsedValue).append("' ");
+      result.append("with priority ").append(priority);
+      if (source != null) {
+        result.append(" and source '").append(source).append("'");
+      }
+      return result.toString();
+    }
+  }
+
+  /**
+   * The verbosity with which option help messages are displayed: short (just
+   * the name), medium (name, type, default, abbreviation), and long (full
+   * description).
+   */
+  public enum HelpVerbosity { LONG, MEDIUM, SHORT }
+
+  /**
+   * The level of documentation. Only documented options are output as part of
+   * the help.
+   *
+   * <p>We use 'hidden' so that options that form the protocol between the
+   * client and the server are not logged.
+   */
+  enum DocumentationLevel {
+    DOCUMENTED, UNDOCUMENTED, HIDDEN
+  }
+
+  /**
+   * 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.
+   *
+   * @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.
+   */
+  public String describeOptions(Map<String, String> categoryDescriptions,
+                                HelpVerbosity helpVerbosity) {
+    StringBuilder desc = new StringBuilder();
+    if (!impl.getOptionsClasses().isEmpty()) {
+
+      List<Field> allFields = Lists.newArrayList();
+      for (Class<? extends OptionsBase> optionsClass : impl.getOptionsClasses()) {
+        allFields.addAll(impl.getAnnotatedFieldsFor(optionsClass));
+      }
+      Collections.sort(allFields, OptionsUsage.BY_CATEGORY);
+      String prevCategory = null;
+
+      for (Field optionField : allFields) {
+        String category = optionField.getAnnotation(Option.class).category();
+        if (!category.equals(prevCategory)) {
+          prevCategory = category;
+          String description = categoryDescriptions.get(category);
+          if (description == null) {
+            description = "Options category '" + category + "'";
+          }
+          if (documentationLevel(category) == DocumentationLevel.DOCUMENTED) {
+            desc.append("\n").append(description).append(":\n");
+          }
+        }
+
+        if (documentationLevel(prevCategory) == DocumentationLevel.DOCUMENTED) {
+          OptionsUsage.getUsage(optionField, desc, helpVerbosity);
+        }
+      }
+    }
+    return desc.toString().trim();
+  }
+
+  /**
+   * Returns a description of the option value set by the last previous call to
+   * {@link #parse(OptionPriority, String, List)} that successfully set the given
+   * option. If the option is of type {@link List}, the description will
+   * correspond to any one of the calls, but not necessarily the last.
+   */
+  public OptionValueDescription getOptionValueDescription(String name) {
+    return impl.getOptionValueDescription(name);
+  }
+
+  static DocumentationLevel documentationLevel(String category) {
+    if ("undocumented".equals(category)) {
+      return DocumentationLevel.UNDOCUMENTED;
+    } else if ("hidden".equals(category)) {
+      return DocumentationLevel.HIDDEN;
+    } else {
+      return DocumentationLevel.DOCUMENTED;
+    }
+  }
+
+  /**
+   * A convenience method, equivalent to
+   * {@code parse(OptionPriority.COMMAND_LINE, null, Arrays.asList(args))}.
+   */
+  public void parse(String... args) throws OptionsParsingException {
+    parse(OptionPriority.COMMAND_LINE, (String) null, Arrays.asList(args));
+  }
+
+  /**
+   * A convenience method, equivalent to
+   * {@code parse(OptionPriority.COMMAND_LINE, null, args)}.
+   */
+  public void parse(List<String> args) throws OptionsParsingException {
+    parse(OptionPriority.COMMAND_LINE, (String) null, args);
+  }
+
+  /**
+   * Parses {@code args}, using the classes registered with this parser.
+   * {@link #getOptions(Class)} and {@link #getResidue()} return the results.
+   * May be called multiple times; later options override existing ones if they
+   * have equal or higher priority. The source of options is a free-form string
+   * that can be used for debugging. Strings that cannot be parsed as options
+   * accumulates as residue, if this parser allows it.
+   *
+   * @see OptionPriority
+   */
+  public void parse(OptionPriority priority, String source,
+      List<String> args) throws OptionsParsingException {
+    parseWithSourceFunction(priority, Functions.constant(source), args);
+  }
+
+  /**
+   * Parses {@code args}, using the classes registered with this parser.
+   * {@link #getOptions(Class)} and {@link #getResidue()} return the results. May be called
+   * multiple times; later options override existing ones if they have equal or higher priority.
+   * The source of options is given as a function that maps option names to the source of the
+   * option. Strings that cannot be parsed as options accumulates as* residue, if this parser
+   * allows it.
+   */
+  public void parseWithSourceFunction(OptionPriority priority,
+      Function<? super String, String> sourceFunction, List<String> args)
+      throws OptionsParsingException {
+    Preconditions.checkNotNull(priority);
+    Preconditions.checkArgument(priority != OptionPriority.DEFAULT);
+    residue.addAll(impl.parse(priority, sourceFunction, args));
+    if (!allowResidue && !residue.isEmpty()) {
+      String errorMsg = "Unrecognized arguments: " + Joiner.on(' ').join(residue);
+      throw new OptionsParsingException(errorMsg);
+    }
+  }
+
+  @Override
+  public List<String> getResidue() {
+    return ImmutableList.copyOf(residue);
+  }
+
+  /**
+   * Returns a list of warnings about problems encountered by previous parse calls.
+   */
+  public List<String> getWarnings() {
+    return impl.getWarnings();
+  }
+
+  @Override
+  public <O extends OptionsBase> O getOptions(Class<O> optionsClass) {
+    return impl.getParsedOptions(optionsClass);
+  }
+
+  @Override
+  public boolean containsExplicitOption(String name) {
+    return impl.containsExplicitOption(name);
+  }
+
+  @Override
+  public List<UnparsedOptionValueDescription> asListOfUnparsedOptions() {
+    return impl.asListOfUnparsedOptions();
+  }
+
+  @Override
+  public List<UnparsedOptionValueDescription> asListOfExplicitOptions() {
+    return impl.asListOfExplicitOptions();
+  }
+
+  @Override
+  public List<OptionValueDescription> asListOfEffectiveOptions() {
+    return impl.asListOfEffectiveOptions();
+  }
+}
diff --git a/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java b/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java
new file mode 100644
index 0000000..e339dcd
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java
@@ -0,0 +1,722 @@
+// Copyright 2014 Google Inc. 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.base.Function;
+import com.google.common.base.Functions;
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Predicate;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.devtools.common.options.OptionsParser.OptionValueDescription;
+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;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The implementation of the options parser. This is intentionally package
+ * private for full flexibility. Use {@link OptionsParser} or {@link Options}
+ * if you're a consumer.
+ */
+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";
+      }});
+  }
+
+  /**
+   * For every value, this class keeps track of its priority, its free-form source
+   * description, whether it was set as an implicit dependency, and the value.
+   */
+  private static final class ParsedOptionEntry {
+    private final Object value;
+    private final OptionPriority priority;
+    private final String source;
+    private final String implicitDependant;
+    private final String expandedFrom;
+    private final boolean allowMultiple;
+
+    ParsedOptionEntry(Object value,
+        OptionPriority priority, String source, String implicitDependant, String expandedFrom,
+        boolean allowMultiple) {
+      this.value = value;
+      this.priority = priority;
+      this.source = source;
+      this.implicitDependant = implicitDependant;
+      this.expandedFrom = expandedFrom;
+      this.allowMultiple = allowMultiple;
+    }
+
+    // Need to suppress unchecked warnings, because the "multiple occurrence"
+    // options use unchecked ListMultimaps due to limitations of Java generics.
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    Object getValue() {
+      if (allowMultiple) {
+        // Sort the results by option priority and return them in a new list.
+        // The generic type of the list is not known at runtime, so we can't
+        // use it here. It was already checked in the constructor, so this is
+        // type-safe.
+        List result = Lists.newArrayList();
+        ListMultimap realValue = (ListMultimap) value;
+        for (OptionPriority priority : OptionPriority.values()) {
+          // If there is no mapping for this key, this check avoids object creation (because
+          // ListMultimap has to return a new object on get) and also an unnecessary addAll call.
+          if (realValue.containsKey(priority)) {
+            result.addAll(realValue.get(priority));
+          }
+        }
+        return result;
+      }
+      return value;
+    }
+
+    // Need to suppress unchecked warnings, because the "multiple occurrence"
+    // options use unchecked ListMultimaps due to limitations of Java generics.
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    void addValue(OptionPriority addedPriority, Object addedValue) {
+      Preconditions.checkState(allowMultiple);
+      ListMultimap optionValueList = (ListMultimap) value;
+      if (addedValue instanceof List<?>) {
+        for (Object element : (List<?>) addedValue) {
+          optionValueList.put(addedPriority, element);
+        }
+      } else {
+        optionValueList.put(addedPriority, addedValue);
+      }
+    }
+
+    OptionValueDescription asOptionValueDescription(String fieldName) {
+      return new OptionValueDescription(fieldName, getValue(), priority,
+          source, implicitDependant, expandedFrom);
+    }
+  }
+
+  private final OptionsData optionsData;
+
+  /**
+   * We store the results of parsing the arguments in here. It'll look like
+   * <pre>
+   *   Field("--host") -> "www.google.com"
+   *   Field("--port") -> 80
+   * </pre>
+   * This map is modified by repeated calls to
+   * {@link #parse(OptionPriority,Function,List)}.
+   */
+  private final Map<Field, ParsedOptionEntry> parsedValues = Maps.newHashMap();
+
+  /**
+   * We store the pre-parsed, explicit options for each priority in here.
+   * We use partially preparsed options, which can be different from the original
+   * representation, e.g. "--nofoo" becomes "--foo=0".
+   */
+  private final List<UnparsedOptionValueDescription> unparsedValues =
+      Lists.newArrayList();
+
+  private final List<String> warnings = Lists.newArrayList();
+  
+  private boolean allowSingleDashLongOptions = false;
+
+  /**
+   * Create a new parser object
+   */
+  OptionsParserImpl(OptionsData optionsData) {
+    this.optionsData = 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.
+   */
+  void setAllowSingleDashLongOptions(boolean allowSingleDashLongOptions) {
+    this.allowSingleDashLongOptions = allowSingleDashLongOptions;
+  }
+  
+  /**
+   * The implementation of {@link OptionsBase#asMap}.
+   */
+  static Map<String, Object> optionsAsMap(OptionsBase optionsInstance) {
+    Map<String, Object> map = Maps.newHashMap();
+    for (Field field : OptionsParser.getAllAnnotatedFields(optionsInstance.getClass())) {
+      try {
+        String name = field.getAnnotation(Option.class).name();
+        Object value = field.get(optionsInstance);
+        map.put(name, value);
+      } catch (IllegalAccessException e) {
+        throw new IllegalStateException(e); // unreachable
+      }
+    }
+    return map;
+  }
+
+  List<Field> getAnnotatedFieldsFor(Class<? extends OptionsBase> clazz) {
+    return optionsData.getFieldsForClass(clazz);
+  }
+
+  /**
+   * Implements {@link OptionsParser#asListOfUnparsedOptions()}.
+   */
+  List<UnparsedOptionValueDescription> asListOfUnparsedOptions() {
+    List<UnparsedOptionValueDescription> result = Lists.newArrayList(unparsedValues);
+    // It is vital that this sort is stable so that options on the same priority are not reordered.
+    Collections.sort(result, new Comparator<UnparsedOptionValueDescription>() {
+      @Override
+      public int compare(UnparsedOptionValueDescription o1,
+          UnparsedOptionValueDescription o2) {
+        return o1.getPriority().compareTo(o2.getPriority());
+      }
+    });
+    return result;
+  }
+
+  /**
+   * Implements {@link OptionsParser#asListOfExplicitOptions()}.
+   */
+  List<UnparsedOptionValueDescription> asListOfExplicitOptions() {
+    List<UnparsedOptionValueDescription> result = Lists.newArrayList(Iterables.filter(
+      unparsedValues,
+      new Predicate<UnparsedOptionValueDescription>() {
+        @Override
+        public boolean apply(UnparsedOptionValueDescription input) {
+          return input.isExplicit();
+        }
+    }));
+    // It is vital that this sort is stable so that options on the same priority are not reordered.
+    Collections.sort(result, new Comparator<UnparsedOptionValueDescription>() {
+      @Override
+      public int compare(UnparsedOptionValueDescription o1,
+          UnparsedOptionValueDescription o2) {
+        return o1.getPriority().compareTo(o2.getPriority());
+      }
+    });
+    return result;
+  }
+
+  /**
+   * Implements {@link OptionsParser#canonicalize}.
+   */
+  List<String> asCanonicalizedList() {
+    List<UnparsedOptionValueDescription> processed = Lists.newArrayList(unparsedValues);
+    Collections.sort(processed, new Comparator<UnparsedOptionValueDescription>() {
+      // This Comparator sorts implicit requirement options to the end, keeping their existing
+      // order, and sorts the other options alphabetically.
+      @Override
+      public int compare(UnparsedOptionValueDescription o1,
+          UnparsedOptionValueDescription o2) {
+        if (o1.isImplicitRequirement()) {
+          return o2.isImplicitRequirement() ? 0 : 1;
+        }
+        if (o2.isImplicitRequirement()) {
+          return -1;
+        }
+        return o1.getName().compareTo(o2.getName());
+      }
+    });
+
+    List<String> result = Lists.newArrayList();
+    for (int i = 0; i < processed.size(); i++) {
+      UnparsedOptionValueDescription value = processed.get(i);
+      // Skip an option if the next option is the same, but only if the option does not allow
+      // multiple values.
+      if (!value.allowMultiple()) {
+        if ((i < processed.size() - 1) && value.getName().equals(processed.get(i + 1).getName())) {
+          continue;
+        }
+      }
+
+      // Ignore expansion options.
+      if (value.isExpansion()) {
+        continue;
+      }
+
+      result.add("--" + value.getName() + "=" + value.getUnparsedValue());
+    }
+    return result;
+  }
+
+  /**
+   * Implements {@link OptionsParser#asListOfEffectiveOptions()}.
+   */
+  List<OptionValueDescription> asListOfEffectiveOptions() {
+    List<OptionValueDescription> result = Lists.newArrayList();
+    for (Map.Entry<String,Field> mapEntry : optionsData.getAllNamedFields()) {
+      String fieldName = mapEntry.getKey();
+      Field field = mapEntry.getValue();
+      ParsedOptionEntry entry = parsedValues.get(field);
+      if (entry == null) {
+        Object value = optionsData.getDefaultValue(field);
+        result.add(new OptionValueDescription(fieldName, value, OptionPriority.DEFAULT,
+            null, null, null));
+      } else {
+        result.add(entry.asOptionValueDescription(fieldName));
+      }
+    }
+    return result;
+  }
+
+  Collection<Class<?  extends OptionsBase>> getOptionsClasses() {
+    return optionsData.getOptionsClasses();
+  }
+
+  private void maybeAddDeprecationWarning(Field field) {
+    Option option = field.getAnnotation(Option.class);
+    // Continue to support the old behavior for @Deprecated options.
+    String warning = option.deprecationWarning();
+    if (!warning.equals("") || (field.getAnnotation(Deprecated.class) != null)) {
+      warnings.add("Option '" + option.name() + "' is deprecated"
+          + (warning.equals("") ? "" : ": " + warning));
+    }
+  }
+
+  // Warnings should not end with a '.' because the internal reporter adds one automatically.
+  private void setValue(Field field, String name, Object value,
+      OptionPriority priority, String source, String implicitDependant, String expandedFrom) {
+    ParsedOptionEntry entry = parsedValues.get(field);
+    if (entry != null) {
+      // Override existing option if the new value has higher or equal priority.
+      if (priority.compareTo(entry.priority) >= 0) {
+        // Output warnings:
+        if ((implicitDependant != null) && (entry.implicitDependant != null)) {
+          if (!implicitDependant.equals(entry.implicitDependant)) {
+            warnings.add("Option '" + name + "' is implicitly defined by both option '" +
+                entry.implicitDependant + "' and option '" + implicitDependant + "'");
+          }
+        } else if ((implicitDependant != null) && priority.equals(entry.priority)) {
+          warnings.add("Option '" + name + "' is implicitly defined by option '" +
+              implicitDependant + "'; the implicitly set value overrides the previous one");
+        } else if (entry.implicitDependant != null) {
+          warnings.add("A new value for option '" + name + "' overrides a previous " +
+              "implicit setting of that option by option '" + entry.implicitDependant + "'");
+        } else if ((priority == entry.priority) &&
+            ((entry.expandedFrom == null) && (expandedFrom != null))) {
+          // Create a warning if an expansion option overrides an explicit option:
+          warnings.add("The option '" + expandedFrom + "' was expanded and now overrides a "
+              + "previous explicitly specified option '" + name + "'");
+        }
+
+        // Record the new value:
+        parsedValues.put(field,
+            new ParsedOptionEntry(value, priority, source, implicitDependant, expandedFrom, false));
+      }
+    } else {
+      parsedValues.put(field,
+          new ParsedOptionEntry(value, priority, source, implicitDependant, expandedFrom, false));
+      maybeAddDeprecationWarning(field);
+    }
+  }
+
+  private void addListValue(Field field, String name, Object value,
+      OptionPriority priority, String source, String implicitDependant, String expandedFrom) {
+    ParsedOptionEntry entry = parsedValues.get(field);
+    if (entry == null) {
+      entry = new ParsedOptionEntry(ArrayListMultimap.create(), priority, source,
+          implicitDependant, expandedFrom, true);
+      parsedValues.put(field, entry);
+      maybeAddDeprecationWarning(field);
+    }
+    entry.addValue(priority, value);
+  }
+
+  private Object getValue(Field field) {
+    ParsedOptionEntry entry = parsedValues.get(field);
+    return entry == null ? null : entry.getValue();
+  }
+
+  OptionValueDescription getOptionValueDescription(String name) {
+    Field field = optionsData.getFieldFromName(name);
+    if (field == null) {
+      throw new IllegalArgumentException("No such option '" + name + "'");
+    }
+    ParsedOptionEntry entry = parsedValues.get(field);
+    if (entry == null) {
+      return null;
+    }
+    return entry.asOptionValueDescription(name);
+  }
+
+  boolean containsExplicitOption(String name) {
+    Field field = optionsData.getFieldFromName(name);
+    if (field == null) {
+      throw new IllegalArgumentException("No such option '" + name + "'");
+    }
+    return parsedValues.get(field) != null;
+  }
+
+  /**
+   * Parses the args, and returns what it doesn't parse. May be called multiple
+   * times, and may be called recursively. In each call, there may be no
+   * duplicates, but separate calls may contain intersecting sets of options; in
+   * that case, the arg seen last takes precedence.
+   */
+  List<String> parse(OptionPriority priority, Function<? super String, String> sourceFunction,
+      List<String> args) throws OptionsParsingException {
+    return parse(priority, sourceFunction, null, null, args);
+  }
+
+  /**
+   * Parses the args, and returns what it doesn't parse. May be called multiple
+   * times, and may be called recursively. Calls may contain intersecting sets
+   * of options; in that case, the arg seen last takes precedence.
+   *
+   * <p>The method uses the invariant that if an option has neither an implicit
+   * dependant nor an expanded from value, then it must have been explicitly
+   * set.
+   */
+  private List<String> parse(OptionPriority priority,
+      final Function<? super String, String> sourceFunction, String implicitDependant,
+      String expandedFrom, List<String> args) throws OptionsParsingException {
+    List<String> unparsedArgs = Lists.newArrayList();
+    LinkedHashMap<String,List<String>> implicitRequirements = Maps.newLinkedHashMap();
+    for (int pos = 0; pos < args.size(); pos++) {
+      String arg = args.get(pos);
+      if (!arg.startsWith("-")) {
+        unparsedArgs.add(arg);
+        continue;  // not an option arg
+      }
+      if (arg.equals("--")) {  // "--" means all remaining args aren't options
+        while (++pos < args.size()) {
+          unparsedArgs.add(args.get(pos));
+        }
+        break;
+      }
+
+      String value = null;
+      Field field;
+      boolean booleanValue = true;
+
+      if (arg.length() == 2) { // -l  (may be nullary or unary)
+        field = optionsData.getFieldForAbbrev(arg.charAt(1));
+        booleanValue = true;
+
+      } else if (arg.length() == 3 && arg.charAt(2) == '-') { // -l-  (boolean)
+        field = optionsData.getFieldForAbbrev(arg.charAt(1));
+        booleanValue = false;
+
+      } else if (allowSingleDashLongOptions // -long_option
+          || arg.startsWith("--")) { // or --long_option
+        int equalsAt = arg.indexOf('=');
+        int nameStartsAt = arg.startsWith("--") ? 2 : 1;
+        String name =
+            equalsAt == -1 ? arg.substring(nameStartsAt) : arg.substring(nameStartsAt, equalsAt);
+        if (name.trim().equals("")) {
+          throw new OptionsParsingException("Invalid options syntax: " + arg, arg);
+        }
+        value = equalsAt == -1 ? null : arg.substring(equalsAt + 1);
+        field = optionsData.getFieldFromName(name);
+
+        // look for a "no"-prefixed option name: "no<optionname>";
+        // (Undocumented: we also allow --no_foo.  We're generous like that.)
+        if (field == null && name.startsWith("no")) {
+          String realname = name.substring(name.startsWith("no_") ? 3 : 2);
+          field = optionsData.getFieldFromName(realname);
+          booleanValue = false;
+          if (field != null) {
+            // TODO(bazel-team): Add tests for these cases.
+            if (!OptionsParserImpl.isBooleanField(field)) {
+              throw new OptionsParsingException(
+                  "Illegal use of 'no' prefix on non-boolean option: " + arg, arg);
+            }
+            if (value != null) {
+              throw new OptionsParsingException(
+                  "Unexpected value after boolean option: " + arg, arg);
+            }
+            // "no<optionname>" signifies a boolean option w/ false value
+            value = "0";
+          }
+        }
+
+      } else {
+        throw new OptionsParsingException("Invalid options syntax: " + arg, arg);
+      }
+
+      if (field == null) {
+        throw new OptionsParsingException("Unrecognized option: " + arg, arg);
+      }
+      
+      if (value == null) {
+        // special case boolean to supply value based on presence of "no" prefix
+        if (OptionsParserImpl.isBooleanField(field)) {
+          value = booleanValue ? "1" : "0";
+        } else if (field.getType().equals(Void.class)) {
+          // this is expected, Void type options have no args
+        } else if (pos != args.size() - 1) {
+          value = args.get(++pos);  // "--flag value" form
+        } else {
+          throw new OptionsParsingException("Expected value after " + arg);
+        }
+      }
+
+      Option option = field.getAnnotation(Option.class);
+      final String originalName = option.name();
+      if (implicitDependant == null) {
+        // Log explicit options and expanded options in the order they are parsed (can be sorted
+        // later). Also remember whether they were expanded or not. This information is needed to
+        // correctly canonicalize flags.
+        unparsedValues.add(new UnparsedOptionValueDescription(originalName, field, value,
+            priority, sourceFunction.apply(originalName), expandedFrom == null));
+      }
+
+      // Handle expansion options.
+      if (option.expansion().length > 0) {
+        Function<Object, String> expansionSourceFunction = Functions.<String>constant(
+            "expanded from option --" + originalName + " from " +
+            sourceFunction.apply(originalName));
+        maybeAddDeprecationWarning(field);
+        List<String> unparsed = parse(priority, expansionSourceFunction, null, originalName,
+            ImmutableList.copyOf(option.expansion()));
+        if (!unparsed.isEmpty()) {
+          // Throw an assertion, because this indicates an error in the code that specified the
+          // expansion for the current option.
+          throw new AssertionError("Unparsed options remain after parsing expansion of " +
+            arg + ":" + Joiner.on(' ').join(unparsed));
+        }
+      } else {
+        Converter<?> converter = optionsData.getConverter(field);
+        Object convertedValue;
+        try {
+          convertedValue = converter.convert(value);
+        } catch (OptionsParsingException e) {
+          // The converter doesn't know the option name, so we supply it here by
+          // re-throwing:
+          throw new OptionsParsingException("While parsing option " + arg
+                                            + ": " + e.getMessage(), e);
+        }
+
+        // ...but allow duplicates of single-use options across separate calls to
+        // parse(); latest wins:
+        if (!option.allowMultiple()) {
+          setValue(field, originalName, convertedValue,
+              priority, sourceFunction.apply(originalName), implicitDependant, expandedFrom);
+        } else {
+          // But if it's a multiple-use option, then just accumulate the
+          // values, in the order in which they were seen.
+          // Note: The type of the list member is not known; Java introspection
+          // only makes it available in String form via the signature string
+          // for the field declaration.
+          addListValue(field, originalName, convertedValue,
+              priority, sourceFunction.apply(originalName), implicitDependant, expandedFrom);
+        }
+      }
+
+      // Collect any implicit requirements.
+      if (option.implicitRequirements().length > 0) {
+        implicitRequirements.put(option.name(), Arrays.asList(option.implicitRequirements()));
+      }
+    }
+
+    // Now parse any implicit requirements that were collected.
+    // TODO(bazel-team): this should happen when the option is encountered.
+    if (!implicitRequirements.isEmpty()) {
+      for (Map.Entry<String,List<String>> entry : implicitRequirements.entrySet()) {
+        Function<Object, String> requirementSourceFunction = Functions.<String>constant(
+            "implicit requirement of option --" + entry.getKey() + " from " +
+            sourceFunction.apply(entry.getKey()));
+
+        List<String> unparsed = parse(priority, requirementSourceFunction, entry.getKey(), null,
+            entry.getValue());
+        if (!unparsed.isEmpty()) {
+          // Throw an assertion, because this indicates an error in the code that specified in the
+          // implicit requirements for the option(s).
+          throw new AssertionError("Unparsed options remain after parsing implicit options:"
+              + Joiner.on(' ').join(unparsed));
+        }
+      }
+    }
+
+    return unparsedArgs;
+  }
+
+  /**
+   * Gets the result of parsing the options.
+   */
+  <O extends OptionsBase> O getParsedOptions(Class<O> optionsClass) {
+    // Create the instance:
+    O optionsInstance;
+    try {
+      Constructor<O> constructor = optionsData.getConstructor(optionsClass);
+      if (constructor == null) {
+        return null;
+      }
+      optionsInstance = constructor.newInstance(new Object[0]);
+    } catch (Exception e) {
+      throw new IllegalStateException(e);
+    }
+
+    // Set the fields
+    for (Field field : optionsData.getFieldsForClass(optionsClass)) {
+      Object value = getValue(field);
+      if (value == null) {
+        value = optionsData.getDefaultValue(field);
+      }
+      try {
+        field.set(optionsInstance, value);
+      } catch (IllegalAccessException e) {
+        throw new IllegalStateException(e);
+      }
+    }
+    return optionsInstance;
+  }
+
+  List<String> getWarnings() {
+    return ImmutableList.copyOf(warnings);
+  }
+
+  static String getDefaultOptionString(Field optionField) {
+    Option annotation = optionField.getAnnotation(Option.class);
+    return annotation.defaultValue();
+  }
+
+  static boolean isBooleanField(Field field) {
+    return field.getType().equals(boolean.class) || field.getType().equals(TriState.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/src/main/java/com/google/devtools/common/options/OptionsParsingException.java b/src/main/java/com/google/devtools/common/options/OptionsParsingException.java
new file mode 100644
index 0000000..9d2916a
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/OptionsParsingException.java
@@ -0,0 +1,50 @@
+// Copyright 2014 Google Inc. 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;
+
+/**
+ * An exception that's thrown when the {@link OptionsParser} fails.
+ *
+ * @see OptionsParser#parse(OptionPriority,String,java.util.List)
+ */
+public class OptionsParsingException extends Exception {
+  private final String invalidArgument;
+
+  public OptionsParsingException(String message) {
+    this(message, (String) null);
+  }
+
+  public OptionsParsingException(String message, String argument) {
+    super(message);
+    this.invalidArgument = argument;
+  }
+
+  public OptionsParsingException(String message, Throwable throwable) {
+    this(message, null, throwable);
+  }
+
+  public OptionsParsingException(String message, String argument, Throwable throwable) {
+    super(message, throwable);
+    this.invalidArgument = argument;
+  }
+
+  /**
+   * Gets the name of the invalid argument or {@code null} if the exception
+   * can not determine the exact invalid arguments
+   */
+  public String getInvalidArgument() {
+    return invalidArgument;
+  }
+}
diff --git a/src/main/java/com/google/devtools/common/options/OptionsProvider.java b/src/main/java/com/google/devtools/common/options/OptionsProvider.java
new file mode 100644
index 0000000..be399a7
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/OptionsProvider.java
@@ -0,0 +1,67 @@
+// Copyright 2014 Google Inc. 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.devtools.common.options.OptionsParser.OptionValueDescription;
+import com.google.devtools.common.options.OptionsParser.UnparsedOptionValueDescription;
+
+import java.util.List;
+
+/**
+ * A read-only interface for options parser results, which does not allow any
+ * further parsing of options.
+ */
+public interface OptionsProvider extends OptionsClassProvider {
+
+  /**
+   * Returns an immutable copy of the residue, that is, the arguments that
+   * have not been parsed.
+   */
+  List<String> getResidue();
+
+  /**
+   * Returns if the named option was specified explicitly in a call to parse.
+   */
+  boolean containsExplicitOption(String string);
+
+  /**
+   * Returns a mutable copy of the list of all options that were specified
+   * either explicitly or implicitly. These options are sorted by priority, and
+   * by the order in which they were specified. If an option was specified
+   * multiple times, it is included in the result multiple times. Does not
+   * include the residue.
+   *
+   * <p>The returned list can be filtered if undocumented, hidden or implicit
+   * options should not be displayed.
+   */
+  List<UnparsedOptionValueDescription> asListOfUnparsedOptions();
+
+  /**
+   * Returns a list of all explicitly specified options, suitable for logging
+   * or for displaying back to the user. These options are sorted by priority,
+   * and by the order in which they were specified. If an option was
+   * explicitly specified multiple times, it is included in the result
+   * multiple times. Does not include the residue.
+   *
+   * <p>The list includes undocumented options.
+   */
+  public List<UnparsedOptionValueDescription> asListOfExplicitOptions();
+
+  /**
+   * Returns a list of all options, including undocumented ones, and their
+   * effective values. There is no guaranteed ordering for the result.
+   */
+  public List<OptionValueDescription> asListOfEffectiveOptions();
+}
diff --git a/src/main/java/com/google/devtools/common/options/OptionsUsage.java b/src/main/java/com/google/devtools/common/options/OptionsUsage.java
new file mode 100644
index 0000000..c48a532
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/OptionsUsage.java
@@ -0,0 +1,156 @@
+// Copyright 2014 Google Inc. 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 static com.google.devtools.common.options.OptionsParserImpl.findConverter;
+
+import com.google.common.base.Splitter;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+
+import java.lang.reflect.Field;
+import java.text.BreakIterator;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * A renderer for usage messages. For now this is very simple.
+ */
+class OptionsUsage {
+
+  private static final Splitter NEWLINE_SPLITTER = Splitter.on('\n');
+
+  /**
+   * Given an options class, render the usage string into the usage,
+   * which is passed in as an argument.
+   */
+  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);
+    }
+  }
+
+  /**
+   * Paragraph-fill the specified input text, indenting lines to 'indent' and
+   * wrapping lines at 'width'.  Returns the formatted result.
+   */
+  static String paragraphFill(String in, int indent, int width) {
+    String indentString = Strings.repeat(" ", indent);
+    StringBuilder out = new StringBuilder();
+    String sep = "";
+    for (String paragraph : NEWLINE_SPLITTER.split(in)) {
+      BreakIterator boundary = BreakIterator.getLineInstance(); // (factory)
+      boundary.setText(paragraph);
+      out.append(sep).append(indentString);
+      int cursor = indent;
+      for (int start = boundary.first(), end = boundary.next();
+           end != BreakIterator.DONE;
+           start = end, end = boundary.next()) {
+        String word =
+            paragraph.substring(start, end); // (may include trailing space)
+        if (word.length() + cursor > width) {
+          out.append('\n').append(indentString);
+          cursor = indent;
+        }
+        out.append(word);
+        cursor += word.length();
+      }
+      sep = "\n";
+    }
+    return out.toString();
+  }
+
+  /**
+   * Append the usage message for a single option-field message to 'usage'.
+   */
+  static void getUsage(Field optionField, StringBuilder usage,
+                       OptionsParser.HelpVerbosity helpVerbosity) {
+    String flagName = getFlagName(optionField);
+    String typeDescription = getTypeDescription(optionField);
+    Option annotation = optionField.getAnnotation(Option.class);
+    usage.append("  --" + flagName);
+    if (helpVerbosity == OptionsParser.HelpVerbosity.SHORT) { // just the name
+      usage.append('\n');
+      return;
+    }
+    if (annotation.abbrev() != '\0') {
+      usage.append(" [-").append(annotation.abbrev()).append(']');
+    }
+    if (!typeDescription.equals("")) {
+      usage.append(" (" + typeDescription + "; ");
+      if (annotation.allowMultiple()) {
+        usage.append("may be used multiple times");
+      } else {
+        // Don't call the annotation directly (we must allow overrides to certain defaults)
+        String defaultValueString = OptionsParserImpl.getDefaultOptionString(optionField);
+        if (OptionsParserImpl.isSpecialNullDefault(defaultValueString, optionField)) {
+          usage.append("default: see description");
+        } else {
+          usage.append("default: \"" + defaultValueString + "\"");
+        }
+      }
+      usage.append(")");
+    }
+    usage.append("\n");
+    if (helpVerbosity == OptionsParser.HelpVerbosity.MEDIUM) { // just the name and type.
+      return;
+    }
+    if (!annotation.help().equals("")) {
+      usage.append(paragraphFill(annotation.help(), 4, 80)); // (indent, width)
+      usage.append('\n');
+    }
+    if (annotation.expansion().length > 0) {
+      StringBuilder expandsMsg = new StringBuilder("Expands to: ");
+      for (String exp : annotation.expansion()) {
+        expandsMsg.append(exp).append(" ");
+      }
+      usage.append(paragraphFill(expandsMsg.toString(), 4, 80)); // (indent, width)
+      usage.append('\n');
+    }
+  }
+
+  private static final Comparator<Field> BY_NAME = new Comparator<Field>() {
+    @Override
+    public int compare(Field left, Field right) {
+      return left.getName().compareTo(right.getName());
+    }
+  };
+
+  /**
+   * An ordering relation for option-field fields that first groups together
+   * options of the same category, then sorts by name within the category.
+   */
+  static final Comparator<Field> BY_CATEGORY = new Comparator<Field>() {
+    @Override
+    public int compare(Field left, Field right) {
+      int r = left.getAnnotation(Option.class).category().compareTo(
+              right.getAnnotation(Option.class).category());
+      return r == 0 ? BY_NAME.compare(left, right) : r;
+    }
+  };
+
+  private static String getTypeDescription(Field optionsField) {
+    return findConverter(optionsField).getTypeDescription();
+  }
+
+  static String getFlagName(Field field) {
+    String name = field.getAnnotation(Option.class).name();
+    return OptionsParserImpl.isBooleanField(field) ? "[no]" + name : name;
+  }
+
+}
diff --git a/src/main/java/com/google/devtools/common/options/TriState.java b/src/main/java/com/google/devtools/common/options/TriState.java
new file mode 100644
index 0000000..9e873ea
--- /dev/null
+++ b/src/main/java/com/google/devtools/common/options/TriState.java
@@ -0,0 +1,21 @@
+// Copyright 2014 Google Inc. 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;
+
+/**
+ * Enum used to represent tri-state options (yes/no/auto).
+ */
+public enum TriState {
+  YES, NO, AUTO
+}
