diff --git a/src/main/java/com/google/devtools/common/options/OptionsBase.java b/src/main/java/com/google/devtools/common/options/OptionsBase.java
index ce66e66..fd684c6 100644
--- a/src/main/java/com/google/devtools/common/options/OptionsBase.java
+++ b/src/main/java/com/google/devtools/common/options/OptionsBase.java
@@ -14,10 +14,9 @@
 
 package com.google.devtools.common.options;
 
+import com.google.common.collect.Maps;
 import com.google.common.escape.CharEscaperBuilder;
 import com.google.common.escape.Escaper;
-import java.lang.reflect.Field;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -63,23 +62,23 @@
    * inherited ones. The mapping is a copy, so subsequent mutations to it or to this object are
    * independent. Entries are sorted alphabetically.
    */
-  public final <O extends OptionsBase> Map<String, Object> asMap() {
-    // Generic O is needed to tell the type system that the toMap() call is safe.
-    // The casts are safe because "this" is an instance of "getClass()"
-    // which subclasses OptionsBase.
-    @SuppressWarnings("unchecked")
-    O castThis = (O) this;
-    @SuppressWarnings("unchecked")
-    Class<O> castClass = (Class<O>) getClass();
-
-    Map<String, Object> map = new LinkedHashMap<>();
-    for (Map.Entry<Field, Object> entry : OptionsParser.toMap(castClass, castThis).entrySet()) {
-      OptionDefinition optionDefinition = OptionDefinition.extractOptionDefinition(entry.getKey());
-      map.put(optionDefinition.getOptionName(), entry.getValue());
+  public final Map<String, Object> asMap() {
+    List<OptionDefinition> definitions = OptionsData.getAllOptionDefinitionsForClass(getClass());
+    Map<String, Object> map = Maps.newLinkedHashMapWithExpectedSize(definitions.size());
+    for (OptionDefinition definition : definitions) {
+      map.put(definition.getOptionName(), getValueFromDefinition(definition));
     }
     return map;
   }
 
+  private Object getValueFromDefinition(OptionDefinition definition) {
+    try {
+      return definition.getField().get(this);
+    } catch (IllegalAccessException e) {
+      throw new IllegalStateException("All options fields of options classes should be public", e);
+    }
+  }
+
   @Override
   public final String toString() {
     return getClass().getName() + asMap();
diff --git a/src/main/java/com/google/devtools/common/options/OptionsParser.java b/src/main/java/com/google/devtools/common/options/OptionsParser.java
index 78f37e0..4f26562 100644
--- a/src/main/java/com/google/devtools/common/options/OptionsParser.java
+++ b/src/main/java/com/google/devtools/common/options/OptionsParser.java
@@ -23,19 +23,14 @@
 import com.google.common.collect.ListMultimap;
 import com.google.common.collect.MoreCollectors;
 import com.google.common.escape.Escaper;
-import com.google.devtools.common.options.OptionDefinition.NotAnOptionException;
 import com.google.devtools.common.options.OptionsParserImpl.ResidueAndPriority;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
@@ -796,132 +791,5 @@
     OptionsData data = OptionsParser.getOptionsDataInternal(optionsClass);
     return data.getUsesOnlyCoreTypes(optionsClass);
   }
-
-  /**
-   * Returns a mapping from each option {@link Field} in {@code optionsClass} (including inherited
-   * ones) to its value in {@code options}.
-   *
-   * <p>To save space, the map directly stores {@code Fields} instead of the {@code
-   * OptionDefinitions}.
-   *
-   * <p>The map is a mutable copy; changing the map won't affect {@code options} and vice versa. The
-   * map entries appear sorted alphabetically by option name.
-   *
-   * <p>If {@code options} is an instance of a subclass of {@link OptionsBase}, any options defined
-   * by the subclass are not included in the map, only the options declared in the provided class
-   * are included.
-   *
-   * @throws IllegalArgumentException if {@code options} is not an instance of {@link OptionsBase}
-   */
-  public static <O extends OptionsBase> Map<Field, Object> toMap(Class<O> optionsClass, O options) {
-    // Alphabetized due to getAllOptionDefinitionsForClass()'s order.
-    Map<Field, Object> map = new LinkedHashMap<>();
-    for (OptionDefinition optionDefinition :
-        OptionsData.getAllOptionDefinitionsForClass(optionsClass)) {
-      try {
-        // Get the object value of the optionDefinition and place in map.
-        map.put(optionDefinition.getField(), optionDefinition.getField().get(options));
-      } catch (IllegalAccessException e) {
-        // All options fields of options classes should be public.
-        throw new IllegalStateException(e);
-      } catch (IllegalArgumentException e) {
-        // This would indicate an inconsistency in the cached OptionsData.
-        throw new IllegalStateException(e);
-      }
-    }
-    return map;
-  }
-
-  /**
-   * Given a mapping as returned by {@link #toMap}, and the options class it that its entries
-   * correspond to, this constructs the corresponding instance of the options class.
-   *
-   * @param map Field to Object, expecting an entry for each field in the optionsClass. This
-   *     directly refers to the Field, without wrapping it in an OptionDefinition, see {@link
-   *     #toMap}.
-   * @throws IllegalArgumentException if {@code map} does not contain exactly the fields of {@code
-   *     optionsClass}, with values of the appropriate type
-   */
-  public static <O extends OptionsBase> O fromMap(Class<O> optionsClass, Map<Field, Object> map) {
-    // Instantiate the options class.
-    OptionsData data = getOptionsDataInternal(optionsClass);
-    O optionsInstance;
-    try {
-      Constructor<O> constructor = data.getConstructor(optionsClass);
-      Preconditions.checkNotNull(constructor, "No options class constructor available");
-      optionsInstance = constructor.newInstance();
-    } catch (ReflectiveOperationException e) {
-      throw new IllegalStateException("Error while instantiating options class", e);
-    }
-
-    List<OptionDefinition> optionDefinitions =
-        OptionsData.getAllOptionDefinitionsForClass(optionsClass);
-    // Ensure all fields are covered, no extraneous fields.
-    validateFieldsSets(optionsClass, new LinkedHashSet<Field>(map.keySet()));
-    // Populate the instance.
-    for (OptionDefinition optionDefinition : optionDefinitions) {
-      // Non-null as per above check.
-      Object value = map.get(optionDefinition.getField());
-      try {
-        optionDefinition.getField().set(optionsInstance, value);
-      } catch (IllegalAccessException e) {
-        throw new IllegalStateException(e);
-      }
-      // May also throw IllegalArgumentException if map value is ill typed.
-    }
-    return optionsInstance;
-  }
-
-  /**
-   * Raises a pretty {@link IllegalArgumentException} if the provided set of fields is a complete
-   * set for the optionsClass.
-   *
-   * <p>The entries in {@code fieldsFromMap} may be ill formed by being null or lacking an {@link
-   * Option} annotation.
-   */
-  private static void validateFieldsSets(
-      Class<? extends OptionsBase> optionsClass, LinkedHashSet<Field> fieldsFromMap) {
-    ImmutableList<OptionDefinition> optionDefsFromClasses =
-        OptionsData.getAllOptionDefinitionsForClass(optionsClass);
-    Set<Field> fieldsFromClass =
-        optionDefsFromClasses.stream().map(OptionDefinition::getField).collect(Collectors.toSet());
-
-    if (fieldsFromClass.equals(fieldsFromMap)) {
-      // They are already equal, avoid additional checks.
-      return;
-    }
-
-    List<String> extraNamesFromClass = new ArrayList<>();
-    List<String> extraNamesFromMap = new ArrayList<>();
-    for (OptionDefinition optionDefinition : optionDefsFromClasses) {
-      if (!fieldsFromMap.contains(optionDefinition.getField())) {
-        extraNamesFromClass.add("'" + optionDefinition.getOptionName() + "'");
-      }
-    }
-    for (Field field : fieldsFromMap) {
-      // Extra validation on the map keys since they don't come from OptionsData.
-      if (!fieldsFromClass.contains(field)) {
-        if (field == null) {
-          extraNamesFromMap.add("<null field>");
-        } else {
-          OptionDefinition optionDefinition = null;
-          try {
-            // TODO(ccalvarin) This shouldn't be necessary, no option definitions should be found in
-            // this optionsClass that weren't in the cache.
-            optionDefinition = OptionDefinition.extractOptionDefinition(field);
-            extraNamesFromMap.add("'" + optionDefinition.getOptionName() + "'");
-          } catch (NotAnOptionException e) {
-            extraNamesFromMap.add("<non-Option field>");
-          }
-        }
-      }
-    }
-    throw new IllegalArgumentException(
-        "Map keys do not match fields of options class; extra map keys: {"
-            + Joiner.on(", ").join(extraNamesFromMap)
-            + "}; extra options class options: {"
-            + Joiner.on(", ").join(extraNamesFromClass)
-            + "}");
-  }
 }
 
diff --git a/src/test/java/com/google/devtools/common/options/OptionsMapConversionTest.java b/src/test/java/com/google/devtools/common/options/OptionsMapConversionTest.java
index b96e57a..9065912 100644
--- a/src/test/java/com/google/devtools/common/options/OptionsMapConversionTest.java
+++ b/src/test/java/com/google/devtools/common/options/OptionsMapConversionTest.java
@@ -15,12 +15,7 @@
 package com.google.devtools.common.options;
 
 import static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.fail;
 
-import com.google.common.collect.ImmutableMap;
-import java.lang.reflect.Field;
-import java.util.LinkedHashMap;
-import java.util.Map;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;
@@ -29,90 +24,44 @@
 @RunWith(JUnit4.class)
 public class OptionsMapConversionTest {
 
-  private static Map<String, Object> keysToStrings(Map<Field, Object> map) {
-    Map<String, Object> result = new LinkedHashMap<>();
-    for (Map.Entry<Field, Object> entry : map.entrySet()) {
-      OptionDefinition optionDefinition = OptionDefinition.extractOptionDefinition(entry.getKey());
-      result.put(optionDefinition.getOptionName(), entry.getValue());
-    }
-    return result;
-  }
-
-  private static Map<Field, Object> keysToFields(
-      Class<? extends OptionsBase> optionsClass, Map<String, Object> map) {
-    OptionsData data = OptionsParser.getOptionsDataInternal(optionsClass);
-    Map<Field, Object> result = new LinkedHashMap<>();
-    for (Map.Entry<String, Object> entry : map.entrySet()) {
-      OptionDefinition optionDefinition = data.getOptionDefinitionFromName(entry.getKey());
-      result.put(optionDefinition.getField(), entry.getValue());
-    }
-    return result;
-  }
-
   /** Dummy options base class. */
   public static class FooOptions extends OptionsBase {
     @Option(
-      name = "foo",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "false"
-    )
+        name = "foo",
+        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+        effectTags = {OptionEffectTag.NO_OP},
+        defaultValue = "false")
     public boolean foo;
   }
 
   /** Dummy options derived class. */
   public static class BazOptions extends FooOptions {
     @Option(
-      name = "bar",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "true"
-    )
+        name = "bar",
+        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+        effectTags = {OptionEffectTag.NO_OP},
+        defaultValue = "true")
     public boolean bar;
 
     @Option(
-      name = "baz",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "5"
-    )
+        name = "baz",
+        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+        effectTags = {OptionEffectTag.NO_OP},
+        defaultValue = "5")
     public int baz;
   }
 
   @Test
-  public void toMap_Basic() {
-    FooOptions foo = Options.getDefaults(FooOptions.class);
-    assertThat(keysToStrings(OptionsParser.toMap(FooOptions.class, foo)))
-        .containsExactly("foo", false);
-  }
-
-  @Test
   public void asMap_Basic() {
     FooOptions foo = Options.getDefaults(FooOptions.class);
-    assertThat(foo.asMap())
-        .containsExactly("foo", false);
-  }
-
-  @Test
-  public void toMap_Inheritance() {
-    BazOptions baz = Options.getDefaults(BazOptions.class);
-    assertThat(keysToStrings(OptionsParser.toMap(BazOptions.class, baz)))
-        .containsExactly("foo", false, "bar", true, "baz", 5);
+    assertThat(foo.asMap()).containsExactly("foo", false);
   }
 
   @Test
   public void asMap_Inheritance() {
     // Static type is base class, dynamic type is derived. We still get the derived fields.
     FooOptions foo = Options.getDefaults(BazOptions.class);
-    assertThat(foo.asMap())
-        .containsExactly("foo", false, "bar", true, "baz", 5);
-  }
-
-  @Test
-  public void toMap_InheritanceBaseFieldsOnly() {
-    BazOptions baz = Options.getDefaults(BazOptions.class);
-    assertThat(keysToStrings(OptionsParser.toMap(FooOptions.class, baz)))
-        .containsExactly("foo", false);
+    assertThat(foo.asMap()).containsExactly("foo", false, "bar", true, "baz", 5);
   }
 
   /**
@@ -123,135 +72,44 @@
   public static class AlphaOptions extends OptionsBase {
 
     @Option(
-      name = "c",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "0"
-    )
+        name = "c",
+        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+        effectTags = {OptionEffectTag.NO_OP},
+        defaultValue = "0")
     public int v;
 
     @Option(
-      name = "d",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "0"
-    )
+        name = "d",
+        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+        effectTags = {OptionEffectTag.NO_OP},
+        defaultValue = "0")
     public int w;
 
     @Option(
-      name = "a",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "0"
-    )
+        name = "a",
+        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+        effectTags = {OptionEffectTag.NO_OP},
+        defaultValue = "0")
     public int x;
 
     @Option(
-      name = "e",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "0"
-    )
+        name = "e",
+        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+        effectTags = {OptionEffectTag.NO_OP},
+        defaultValue = "0")
     public int y;
 
     @Option(
-      name = "b",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "0"
-    )
+        name = "b",
+        documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+        effectTags = {OptionEffectTag.NO_OP},
+        defaultValue = "0")
     public int z;
   }
 
   @Test
-  public void toMap_AlphabeticalOrder() {
-    AlphaOptions alpha = Options.getDefaults(AlphaOptions.class);
-    assertThat(keysToStrings(OptionsParser.toMap(AlphaOptions.class, alpha)))
-        .containsExactly("a", 0, "b", 0, "c", 0, "d", 0, "e", 0).inOrder();
-  }
-
-  @Test
   public void asMap_AlphabeticalOrder() {
     AlphaOptions alpha = Options.getDefaults(AlphaOptions.class);
-    assertThat(alpha.asMap())
-        .containsExactly("a", 0, "b", 0, "c", 0, "d", 0, "e", 0).inOrder();
-  }
-
-  @Test
-  public void fromMap_Basic() {
-    Map<String, Object> map = ImmutableMap.<String, Object>of("foo", true);
-    Map<Field, Object> fieldMap = keysToFields(FooOptions.class, map);
-    FooOptions foo = OptionsParser.fromMap(FooOptions.class, fieldMap);
-    assertThat(foo.foo).isTrue();
-  }
-
-  /** Dummy subclass of foo. */
-  public static class SubFooAOptions extends FooOptions {
-    @Option(
-      name = "a",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "false"
-    )
-    public boolean a;
-  }
-
-  /** Dummy subclass of foo. */
-  public static class SubFooBOptions extends FooOptions {
-    @Option(
-      name = "b1",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "false"
-    )
-    public boolean b1;
-
-    @Option(
-      name = "b2",
-      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
-      effectTags = {OptionEffectTag.NO_OP},
-      defaultValue = "false"
-    )
-    public boolean b2;
-  }
-
-  @Test
-  public void fromMap_FailsOnWrongKeys() {
-    Map<String, Object> map = ImmutableMap.<String, Object>of("foo", true, "a", false);
-    Map<Field, Object> fieldMap = keysToFields(SubFooAOptions.class, map);
-    try {
-      OptionsParser.fromMap(SubFooBOptions.class, fieldMap);
-      fail("Should have failed due to the given map's fields not matching the ones on the class");
-    } catch (IllegalArgumentException e) {
-      assertThat(e)
-          .hasMessageThat()
-          .contains(
-              "Map keys do not match fields of options class; extra map keys: {'a'}; "
-                  + "extra options class options: {'b1', 'b2'}");
-    }
-  }
-
-  @Test
-  public void fromMap_FailsOnWrongTypes() {
-    Map<String, Object> map = ImmutableMap.<String, Object>of("foo", 5);
-    Map<Field, Object> fieldMap = keysToFields(SubFooAOptions.class, map);
-    try {
-      OptionsParser.fromMap(FooOptions.class, fieldMap);
-      fail("Should have failed due to trying to assign a field value with the wrong type");
-    } catch (IllegalArgumentException e) {
-      assertThat(e)
-          .hasMessageThat()
-          .matches("Can not set boolean field .*\\.foo to java\\.lang\\.Integer");
-    }
-  }
-
-  @Test
-  public void fromMap_Inheritance() {
-    Map<String, Object> map = ImmutableMap.<String, Object>of("foo", true, "bar", true, "baz", 3);
-    Map<Field, Object> fieldMap = keysToFields(BazOptions.class, map);
-    BazOptions baz = OptionsParser.fromMap(BazOptions.class, fieldMap);
-    assertThat(baz.foo).isTrue();
-    assertThat(baz.bar).isTrue();
-    assertThat(baz.baz).isEqualTo(3);
+    assertThat(alpha.asMap()).containsExactly("a", 0, "b", 0, "c", 0, "d", 0, "e", 0).inOrder();
   }
 }
