Code cleanup.
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_nameOf_FieldOption_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_nameOf_FieldOption_Test.java
index afed8a3..a1166c0 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_nameOf_FieldOption_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_nameOf_FieldOption_Test.java
@@ -19,7 +19,7 @@
 import com.google.eclipse.protobuf.protobuf.FieldOption;
 
 /**
- * Tests for <code>{@link FieldOptions#nameOf(FieldOption)}</code>.
+ * Tests for <code>{@link Options#nameOf(FieldOption)}</code>.
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_rootSourceOf_FieldOption_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_rootSourceOf_FieldOption_Test.java
index 55630b2..dec3cea 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_rootSourceOf_FieldOption_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_rootSourceOf_FieldOption_Test.java
@@ -19,7 +19,7 @@
 import com.google.eclipse.protobuf.protobuf.*;
 
 /**
- * Tests for <code>{@link Options#rootSourceOf(FieldOption)}</code>.
+ * Tests for <code>{@link Options#rootSourceOf(AbstractOption)}</code>.
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_rootSourceOf_Option_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_rootSourceOf_Option_Test.java
index 5511cda..a9abb79 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_rootSourceOf_Option_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_rootSourceOf_Option_Test.java
@@ -19,7 +19,7 @@
 import com.google.eclipse.protobuf.protobuf.*;
 
 /**
- * Tests for <code>{@link Options#rootSourceOf(Option)}</code>.
+ * Tests for <code>{@link Options#rootSourceOf(AbstractOption)}</code>.
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOfLastFieldIn_CustomFieldOption_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOfLastFieldIn_CustomFieldOption_Test.java
index 3f5734c..c702f82 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOfLastFieldIn_CustomFieldOption_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOfLastFieldIn_CustomFieldOption_Test.java
@@ -19,7 +19,7 @@
 import com.google.eclipse.protobuf.protobuf.*;
 
 /**
- * Tests for <code>{@link Options#sourceOfLastFieldIn(CustomFieldOption)}</code>.
+ * Tests for <code>{@link Options#sourceOfLastFieldIn(AbstractCustomOption)}</code>.
  *
  * alruiz@google.com (Alex Ruiz)
  */
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOfLastFieldIn_CustomOption_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOfLastFieldIn_CustomOption_Test.java
index 6f59648..e146b82 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOfLastFieldIn_CustomOption_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOfLastFieldIn_CustomOption_Test.java
@@ -19,7 +19,7 @@
 import com.google.eclipse.protobuf.protobuf.*;
 
 /**
- * Tests for <code>{@link Options#sourceOfLastFieldIn(CustomOption)}</code>.
+ * Tests for <code>{@link Options#sourceOfLastFieldIn(AbstractCustomOption)}</code>.
  *
  * alruiz@google.com (Alex Ruiz)
  */
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOf_CustomFieldOption_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOf_CustomFieldOption_Test.java
index e7e98db..26d7783 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOf_CustomFieldOption_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOf_CustomFieldOption_Test.java
@@ -19,7 +19,7 @@
 import com.google.eclipse.protobuf.protobuf.*;
 
 /**
- * Tests for <code>{@link Options#sourceOf(CustomFieldOption)}</code>.
+ * Tests for <code>{@link Options#sourceOf(AbstractCustomOption)}</code>.
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOf_CustomOption_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOf_CustomOption_Test.java
index d6c9ba2..8a8af1d 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOf_CustomOption_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_sourceOf_CustomOption_Test.java
@@ -19,7 +19,7 @@
 import com.google.eclipse.protobuf.protobuf.*;
 
 /**
- * Tests for <code>{@link Options#sourceOf(CustomOption)}</code>
+ * Tests for <code>{@link Options#sourceOf(AbstractCustomOption)}</code>
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
index f840954..7fff679 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
@@ -340,7 +340,8 @@
     proposeAndAccept(name, context, acceptor);
   }
 
-  private void proposeAndAccept(String proposalText, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+  private void proposeAndAccept(String proposalText, ContentAssistContext context,
+      ICompletionProposalAcceptor acceptor) {
     acceptor.accept(createCompletionProposal(proposalText, context));
   }
 
@@ -515,25 +516,26 @@
 
   @Override public void completeCustomOption_Source(EObject model, Assignment assignment,
       ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
-    if (!(model instanceof CustomOption)) {
-      return;
-    }
-    CustomOption option = (CustomOption) model;
-    Collection<IEObjectDescription> scope = scoping().allPossibleSourcesOf(option);
-    proposeAndAcceptOptions(scope, context, acceptor);
+    completeAbstractCustomOptionSource(model, context, acceptor);
   }
 
   @Override public void completeCustomFieldOption_Source(EObject model, Assignment assignment,
       ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
-    if (!(model instanceof CustomFieldOption)) {
+    completeAbstractCustomOptionSource(model, context, acceptor);
+  }
+
+  private void completeAbstractCustomOptionSource(EObject model, ContentAssistContext context,
+      ICompletionProposalAcceptor acceptor) {
+    if (!(model instanceof AbstractCustomOption)) {
       return;
     }
-    CustomFieldOption option = (CustomFieldOption) model;
+    AbstractCustomOption option = (AbstractCustomOption) model;
     Collection<IEObjectDescription> scope = scoping().allPossibleSourcesOf(option);
     proposeAndAcceptOptions(scope, context, acceptor);
   }
 
-  private void proposeAndAcceptOptions(Collection<IEObjectDescription> scope, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+  private void proposeAndAcceptOptions(Collection<IEObjectDescription> scope, ContentAssistContext context,
+      ICompletionProposalAcceptor acceptor) {
     Image image = imageForOption();
     for (IEObjectDescription d : descriptionChooser.shortestQualifiedNamesIn(scope)) {
       proposeAndAccept(d, image, context, acceptor);
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/syntaxcoloring/ProtobufSemanticHighlightingCalculator.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/syntaxcoloring/ProtobufSemanticHighlightingCalculator.java
index 329a76b..41a418e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/syntaxcoloring/ProtobufSemanticHighlightingCalculator.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/syntaxcoloring/ProtobufSemanticHighlightingCalculator.java
@@ -128,11 +128,11 @@
     for (FieldOption option : indexedElements.fieldOptionsOf(element)) {
       Value value = option.getValue();
       if (value instanceof LiteralLink) {
-        highlightFirstFeature(option, FIELD_OPTION__VALUE, acceptor, ENUM_LITERAL_ID);
+        highlightFirstFeature(option, ABSTRACT_OPTION__VALUE, acceptor, ENUM_LITERAL_ID);
         return;
       }
       if (value instanceof NumberLink) {
-        highlightFirstFeature(option, FIELD_OPTION__VALUE, acceptor, NUMBER_ID);
+        highlightFirstFeature(option, ABSTRACT_OPTION__VALUE, acceptor, NUMBER_ID);
       }
     }
   }
@@ -216,11 +216,11 @@
     }
     Value value = option.getValue();
     if (value instanceof LiteralLink) {
-      highlightFirstFeature(option, OPTION__VALUE, acceptor, ENUM_LITERAL_ID);
+      highlightFirstFeature(option, ABSTRACT_OPTION__VALUE, acceptor, ENUM_LITERAL_ID);
       return;
     }
     if (value instanceof NumberLink) {
-      highlightFirstFeature(option, OPTION__VALUE, acceptor, NUMBER_ID);
+      highlightFirstFeature(option, ABSTRACT_OPTION__VALUE, acceptor, NUMBER_ID);
     }
   }
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/labeling/Labels.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/labeling/Labels.java
index 1fb28a4..104ba58 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/labeling/Labels.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/labeling/Labels.java
@@ -57,8 +57,8 @@
       MessageField field = (MessageField) o;
       return labelFor(field);
     }
-    if (o instanceof Option) {
-      Option option = (Option) o;
+    if (o instanceof AbstractOption) {
+      AbstractOption option = (AbstractOption) o;
       return labelFor(option);
     }
     if (o instanceof Rpc) {
@@ -127,19 +127,13 @@
     return text;
   }
 
-  private Object labelFor(Option option) {
+  private Object labelFor(AbstractOption option) {
     IndexedElement e = options.rootSourceOf(option);
     String name = options.nameForOption(e);
     StringBuilder b = new StringBuilder();
-    boolean isCustomOption = option instanceof CustomOption || option instanceof CustomFieldOption;
-    if (isCustomOption) {
+    if (option instanceof AbstractCustomOption) {
       b.append(formatCustomOptionName(name));
-    }
-    if (option instanceof CustomOption) {
-      appendFields(b, ((CustomOption) option).getFields());
-    }
-    if (option instanceof CustomFieldOption) {
-      appendFields(b, ((CustomFieldOption) option).getFields());
+      appendFields(b, options.fieldsOf((AbstractCustomOption) option));
     }
     return b.toString();
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/LabelWidgets.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/LabelWidgets.java
index fa07622..37b8777 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/LabelWidgets.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/LabelWidgets.java
@@ -26,7 +26,7 @@
    * if the given "enabled" state is {@code true}, otherwise it sets the foreground of the widget to the system color
    * with id <code>{@link SWT#COLOR_TITLE_INACTIVE_FOREGROUND}</code>.
    * @param label the given label widget.
-   * @param editable the new "enabled" state.
+   * @param enabled the new "enabled" state.
    * @throws SWTException if the given label widget has been disposed or if this method is not called from the thread
    * that created the label widget.
    */
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/TextWidgets.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/TextWidgets.java
index 0cde79d..aeabb3b 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/TextWidgets.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/preferences/pages/TextWidgets.java
@@ -41,7 +41,7 @@
    * if the given "enabled" state is {@code true}, otherwise it sets the background of the widget to the system color
    * with id <code>{@link SWT#COLOR_WIDGET_BACKGROUND}</code>.
    * @param text the given text widget.
-   * @param editable the new "enabled" state.
+   * @param enabled the new "enabled" state.
    * @throws SWTException if the given text widget has been disposed or if this method is not called from the thread
    * that created the text widget.
    */
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext
index 415e8d4..4caaeb1 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/Protobuf.xtext
@@ -134,6 +134,12 @@
 MessageLink:
   target=[Message|QualifiedName];
 
+AbstractOption:
+  Option | FieldOption;
+
+AbstractCustomOption:
+  CustomOption | CustomFieldOption;
+
 Option:
   NativeOption | CustomOption;
 
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Options.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Options.java
index e167625..e5e9da2 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Options.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Options.java
@@ -8,12 +8,11 @@
  */
 package com.google.eclipse.protobuf.model.util;
 
+import static java.util.Collections.emptyList;
 import static org.eclipse.xtext.util.Strings.isEmpty;
 
 import java.util.List;
 
-import org.eclipse.emf.ecore.EObject;
-
 import com.google.eclipse.protobuf.naming.NameResolver;
 import com.google.eclipse.protobuf.protobuf.*;
 import com.google.inject.*;
@@ -29,6 +28,20 @@
   @Inject private NameResolver nameResolver;
   @Inject private OptionFields optionFields;
 
+  public boolean isNative(AbstractOption option) {
+    return option instanceof NativeOption || option instanceof NativeFieldOption;
+  }
+
+  public List<OptionField> fieldsOf(AbstractCustomOption option) {
+    if (option instanceof CustomOption) {
+      return ((CustomOption) option).getFields();
+    }
+    if (option instanceof CustomFieldOption) {
+      return ((CustomFieldOption) option).getFields();
+    }
+    return emptyList();
+  }
+
   /**
    * Indicates whether the given option is the "default value" one.
    * @param option the given option to check.
@@ -39,9 +52,9 @@
   }
 
   /**
-   * Returns the <code>{@link IndexedElement}</code> the given <code>{@link CustomOption}</code> is referring to. This
-   * method will check first the source of the last field of the given option (if any.) If the option does not have any
-   * fields, this method will return the root source of the option.
+   * Returns the <code>{@link IndexedElement}</code> the given custom option is referring to. This method will check
+   * first the source of the last field of the given option (if any.) If the option does not have any fields, this
+   * method will return the root source of the option.
    * <p>
    * Example #1
    *
@@ -60,102 +73,32 @@
    *
    * this method will return the <code>{@link IndexedElement}</code> "foo" is pointing to.
    * </p>
-   * @param option the given {@code CustomOption}.
-   * @return the {@code IndexedElement} the given {@code CustomOption} is referring to, or {@code null} if it cannot be
+   * @param option the given custom option.
+   * @return the {@code IndexedElement} the given custom option is referring to, or {@code null} if it cannot be
    * found.
    */
-  public IndexedElement sourceOf(CustomOption option) {
+  public IndexedElement sourceOf(AbstractCustomOption option) {
     IndexedElement e = sourceOfLastFieldIn(option);
     if (e == null) {
-      e = rootSourceOf(option);
+      e = rootSourceOf((AbstractOption) option);
     }
     return e;
   }
 
   /**
-   * Returns the last field of the given <code>{@link CustomOption}</code>. In the following example
+   * Returns the last field of the given custom option. In the following example
    *
    * <pre>
    * option(myOption).foo = true;
    * </pre>
    *
    * this method will return the field that "foo" is pointing to.
-   * @param option the given {@code CustomOption}.
-   * @return the last field of the given {@code CustomOption} is referring to, or {@code null} if one cannot be found.
+   * @param option the given custom option.
+   * @return the last field of the given custom option is referring to, or {@code null} if one cannot be found.
    */
-  public IndexedElement sourceOfLastFieldIn(CustomOption option) {
-    return findSourceOfLastField(option);
-  }
-
-  /**
-   * Returns the <code>{@link IndexedElement}</code> the given <code>{@link Option}</code> is referring to. In the
-   * following example
-   *
-   * <pre>
-   * option(myOption).foo = true;
-   * </pre>
-   *
-   * this method will return the <code>{@link IndexedElement}</code> "myOption" is pointing to.
-   * @param option the given {@code Option}.
-   * @return the {@code IndexedElement} the given {@code Option} is referring to, or {@code null} if it cannot be found.
-   */
-  public IndexedElement rootSourceOf(Option option) {
-    return findRootSource(option);
-  }
-
-  /**
-   * Returns the <code>{@link IndexedElement}</code> the given <code>{@link CustomFieldOption}</code> is referring to.
-   * This method will check first the source of the last field of the given option (if any.) If the option does not have
-   * any fields, this method will return the root source of the option.
-   * <p>
-   * Example #1
-   *
-   * <pre>
-   * [(myFieldOption) = true];
-   * </pre>
-   *
-   * this method will return the <code>{@link IndexedElement}</code> "myFieldOption" is pointing to.
-   * </p>
-   * <p>
-   * Example #2
-   *
-   * <pre>
-   * [(myOption).foo = true];
-   * </pre>
-   *
-   * this method will return the <code>{@link IndexedElement}</code> "foo" is pointing to.
-   * </p>
-   * @param option the given {@code CustomFieldOption}.
-   * @return the {@code IndexedElement} the given {@code CustomFieldOption} is referring to, or {@code null} if it
-   *         cannot be found.
-   */
-  public IndexedElement sourceOf(CustomFieldOption option) {
-    IndexedElement e = sourceOfLastFieldIn(option);
-    if (e == null) {
-      e = rootSourceOf(option);
-    }
-    return e;
-  }
-
-  /**
-   * Returns the last field of the given <code>{@link CustomFieldOption}</code>. In the following example
-   *
-   * <pre>
-   * [(myOption).foo = true];
-   * </pre>
-   *
-   * this method will return the field that "foo" is pointing to.
-   * @param option the given {@code CustomFieldOption}.
-   * @return the last field of the given {@code CustomFieldOption} is referring to, or {@code null} if one cannot be
-   * found.
-   */
-  public IndexedElement sourceOfLastFieldIn(CustomFieldOption option) {
-    return findSourceOfLastField(option);
-  }
-
   @SuppressWarnings("unchecked")
-  private IndexedElement findSourceOfLastField(EObject e) {
-    List<OptionField> fields = modelObjects.valueOfFeature(e, "fields", List.class);
+  public IndexedElement sourceOfLastFieldIn(AbstractCustomOption option) {
+    List<OptionField> fields = modelObjects.valueOfFeature(option, "fields", List.class);
     if (fields == null || fields.isEmpty()) {
       return null;
     }
@@ -164,23 +107,18 @@
   }
 
   /**
-   * Returns the <code>{@link IndexedElement}</code> the given <code>{@link FieldOption}</code> is referring to. In the
-   * following example
+   * Returns the <code>{@link IndexedElement}</code> the given option is referring to. In the following example
    *
    * <pre>
-   * [(myFieldOption) = true]
+   * option(myOption).foo = true;
    * </pre>
    *
-   * this method will return the <code>{@link IndexedElement}</code> "myFieldOption" is pointing to.
-   * @param option the given {@code FieldOption}.
-   * @return the {@code Property} the given {@code FieldOption} is referring to, or {@code null} if it cannot be found.
+   * this method will return the <code>{@link IndexedElement}</code> "myOption" is pointing to.
+   * @param option the given option.
+   * @return the {@code Property} the given option is referring to, or {@code null} if it cannot be found.
    */
-  public IndexedElement rootSourceOf(FieldOption option) {
-    return findRootSource(option);
-  }
-
-  private IndexedElement findRootSource(EObject e) {
-    OptionSource source = modelObjects.valueOfFeature(e, "source", OptionSource.class);
+  public IndexedElement rootSourceOf(AbstractOption option) {
+    OptionSource source = modelObjects.valueOfFeature(option, "source", OptionSource.class);
     return source == null ? null : source.getTarget();
   }
 
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionFieldScopeFinder.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionFieldScopeFinder.java
index 5f95dfc..2d854f6 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionFieldScopeFinder.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionFieldScopeFinder.java
@@ -30,19 +30,19 @@
   @Inject private Options options;
   @Inject private QualifiedNameDescriptions qualifiedNameDescriptions;
 
-  Collection<IEObjectDescription> findScope(CustomOption option, MessageOptionField field) {
+  Collection<IEObjectDescription> findScope(AbstractCustomOption option, MessageOptionField field) {
     return findScope(option, field, new MessageFieldDescriptorProvider());
   }
 
-  Collection<IEObjectDescription> findScope(CustomOption option, ExtensionOptionField field) {
+  Collection<IEObjectDescription> findScope(AbstractCustomOption option, ExtensionOptionField field) {
     return findScope(option, field, new ExtensionFieldDescriptorProvider());
   }
 
-  private Collection<IEObjectDescription> findScope(final CustomOption option, OptionField field,
+  private Collection<IEObjectDescription> findScope(final AbstractCustomOption option, OptionField field,
       IEObjectDescriptionsProvider provider) {
-    IndexedElement e = referredField(field, option.getFields(), new Provider<IndexedElement>() {
+    IndexedElement e = referredField(option, field, new Provider<IndexedElement>() {
       @Override public IndexedElement get() {
-        return options.rootSourceOf(option);
+        return options.rootSourceOf((AbstractOption) option);
       }
     });
     if (e != null) {
@@ -51,32 +51,11 @@
     return emptySet();
   }
 
-  Collection<IEObjectDescription> findScope(CustomFieldOption option, MessageOptionField field) {
-    return findScope(option, field, new MessageFieldDescriptorProvider());
-  }
-
-  Collection<IEObjectDescription> findScope(CustomFieldOption option, ExtensionOptionField field) {
-    return findScope(option, field, new ExtensionFieldDescriptorProvider());
-  }
-
-  private Collection<IEObjectDescription> findScope(final CustomFieldOption option, OptionField field,
-      IEObjectDescriptionsProvider provider) {
-    IndexedElement e = referredField(field, option.getFields(), new Provider<IndexedElement>() {
-      @Override public IndexedElement get() {
-        return options.rootSourceOf(option);
-      }
-    });
-    if (e != null) {
-      return provider.fieldsInTypeOf(e);
-    }
-    return emptySet();
-  }
-
-  private IndexedElement referredField(OptionField field, List<OptionField> allFields,
+  private IndexedElement referredField(AbstractCustomOption option, OptionField field,
       Provider<IndexedElement> provider) {
     OptionField previous = null;
     boolean isFirstField = true;
-    for (OptionField current : allFields) {
+    for (OptionField current : options.fieldsOf(option)) {
       if (current == field) {
         return (isFirstField) ? provider.get() : optionFields.sourceOf(previous);
       }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/FieldNotationScopeFinder.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/FieldNotationScopeFinder.java
index 329ebce..bce1500 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/FieldNotationScopeFinder.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/FieldNotationScopeFinder.java
@@ -48,12 +48,8 @@
   private MessageField sourceOf(ComplexValue value) {
     IndexedElement source = null;
     EObject container = value.eContainer();
-    if (container instanceof CustomOption) {
-      CustomOption option = (CustomOption) container;
-      source = options.sourceOf(option);
-    }
-    if (container instanceof CustomFieldOption) {
-      CustomFieldOption option = (CustomFieldOption) container;
+    if (container instanceof AbstractCustomOption) {
+      AbstractCustomOption option = (AbstractCustomOption) container;
       source = options.sourceOf(option);
     }
     if (container instanceof ComplexValueField) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/NativeOptionDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/NativeOptionDescriptions.java
index 7e00ff6..81f731b 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/NativeOptionDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/NativeOptionDescriptions.java
@@ -13,7 +13,6 @@
 
 import java.util.*;
 
-import org.eclipse.emf.ecore.EObject;
 import org.eclipse.xtext.resource.IEObjectDescription;
 
 import com.google.eclipse.protobuf.protobuf.*;
@@ -26,15 +25,7 @@
 
   @Inject private ProtoDescriptorProvider descriptorProvider;
 
-  Collection<IEObjectDescription> sources(NativeOption option) {
-    return allSources(option);
-  }
-
-  Collection<IEObjectDescription> sources(NativeFieldOption option) {
-    return allSources(option);
-  }
-
-  private Collection<IEObjectDescription> allSources(EObject option) {
+  Collection<IEObjectDescription> sources(AbstractOption option) {
     ProtoDescriptor descriptor = descriptorProvider.primaryDescriptor();
     Collection<MessageField> optionSources = descriptor.availableOptionsFor(option.eContainer());
     if (optionSources.isEmpty()) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
index 0273084..ad22ddb 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/OptionType.java
@@ -56,16 +56,7 @@
    * @param option the given option.
    * @return the type of the given option or {@code null} if a type cannot be found.
    */
-  static OptionType typeOf(FieldOption option) {
-    return findOptionTypeForLevelOf(option.eContainer());
-  }
-
-  /**
-   * Returns the type of the given option.
-   * @param option the given option.
-   * @return the type of the given option or {@code null} if a type cannot be found.
-   */
-  static OptionType typeOf(Option option) {
+  static OptionType typeOf(AbstractOption option) {
     return findOptionTypeForLevelOf(option.eContainer());
   }
 
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
index a49d287..1bfbb39 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
@@ -45,7 +45,8 @@
   @Inject private Options options;
   @Inject private TypeScopeFinder typeScopeFinder;
 
-  @SuppressWarnings("unused") public IScope scope_ComplexTypeLink_target(ComplexTypeLink link, EReference r) {
+  @SuppressWarnings("unused")
+  public IScope scope_ComplexTypeLink_target(ComplexTypeLink link, EReference r) {
     EObject c = link.eContainer();
     if (c instanceof MessageField) { return createScope(allPossibleTypesFor((MessageField) c)); }
     Set<IEObjectDescription> descriptions = emptySet();
@@ -56,7 +57,8 @@
     return astWalker.traverseAst(field, typeScopeFinder, ComplexType.class);
   }
 
-  @SuppressWarnings("unused") public IScope scope_ExtensibleTypeLink_target(ExtensibleTypeLink link, EReference r) {
+  @SuppressWarnings("unused")
+  public IScope scope_ExtensibleTypeLink_target(ExtensibleTypeLink link, EReference r) {
     return createScope(extensibleTypesFor(link));
   }
 
@@ -69,7 +71,8 @@
     return astWalker.traverseAst(root, typeScopeFinder, ExtensibleType.class);
   }
 
-  @SuppressWarnings("unused") public IScope scope_MessageLink_target(MessageLink link, EReference r) {
+  @SuppressWarnings("unused")
+  public IScope scope_MessageLink_target(MessageLink link, EReference r) {
     return createScope(messagesFor(link));
   }
 
@@ -82,28 +85,23 @@
     return astWalker.traverseAst(root, typeScopeFinder, Message.class);
   }
 
-  @SuppressWarnings("unused") public IScope scope_LiteralLink_target(LiteralLink link, EReference r) {
+  @SuppressWarnings("unused")
+  public IScope scope_LiteralLink_target(LiteralLink link, EReference r) {
     EObject container = link.eContainer();
     Enum anEnum = null;
     if (container instanceof DefaultValueFieldOption) {
       container = container.eContainer();
     }
-    if (container instanceof NativeOption) {
-      ProtoDescriptor descriptor = descriptorProvider.primaryDescriptor();
-      IndexedElement e = options.rootSourceOf((Option) container);
-      anEnum = descriptor.enumTypeOf((MessageField) e);
+    if (container instanceof AbstractOption) {
+      AbstractOption option = (AbstractOption) container;
+      if (options.isNative(option)) {
+        ProtoDescriptor descriptor = descriptorProvider.primaryDescriptor();
+        IndexedElement e = options.rootSourceOf(option);
+        anEnum = descriptor.enumTypeOf((MessageField) e);
+      }
     }
-    if (container instanceof CustomOption) {
-      CustomOption option = (CustomOption) container;
-      container = options.sourceOf(option);
-    }
-    if (container instanceof NativeFieldOption) {
-      ProtoDescriptor descriptor = descriptorProvider.primaryDescriptor();
-      IndexedElement c = options.rootSourceOf((FieldOption) container);
-      anEnum = descriptor.enumTypeOf((MessageField) c);
-    }
-    if (container instanceof CustomFieldOption) {
-      CustomFieldOption option = (CustomFieldOption) container;
+    if (container instanceof AbstractCustomOption) {
+      AbstractCustomOption option = (AbstractCustomOption) container;
       container = options.sourceOf(option);
     }
     if (container instanceof SimpleValueField) {
@@ -116,30 +114,25 @@
     return createScope(literalDescriptions.literalsOf(anEnum));
   }
 
-  @SuppressWarnings("unused") public IScope scope_OptionSource_target(OptionSource source, EReference r) {
+  @SuppressWarnings("unused")
+  public IScope scope_OptionSource_target(OptionSource source, EReference r) {
     EObject c = source.eContainer();
-    if (c instanceof NativeOption) {
-      NativeOption option = (NativeOption) c;
-      return createScope(nativeOptionDescriptions.sources(option));
+    if (c instanceof AbstractOption) {
+      AbstractOption option = (AbstractOption) c;
+      if (options.isNative(option)) {
+        return createScope(nativeOptionDescriptions.sources(option));
+      }
     }
-    if (c instanceof NativeFieldOption) {
-      NativeFieldOption option = (NativeFieldOption) c;
-      return createScope(nativeOptionDescriptions.sources(option));
-    }
-    if (c instanceof CustomOption) {
-      CustomOption option = (CustomOption) c;
-      return createScope(allPossibleSourcesOf(option));
-    }
-    if (c instanceof CustomFieldOption) {
-      CustomFieldOption option = (CustomFieldOption) c;
+    if (c instanceof AbstractCustomOption) {
+      AbstractCustomOption option = (AbstractCustomOption) c;
       return createScope(allPossibleSourcesOf(option));
     }
     Set<IEObjectDescription> descriptions = emptySet();
     return createScope(descriptions);
   }
 
-  @Override public Collection<IEObjectDescription> allPossibleSourcesOf(CustomOption option) {
-    OptionType optionType = typeOf(option);
+  @Override public Collection<IEObjectDescription> allPossibleSourcesOf(AbstractCustomOption option) {
+    OptionType optionType = typeOf((AbstractOption) option);
     Collection<IEObjectDescription> descriptions = emptySet();
     if (optionType != null) {
       descriptions = astWalker.traverseAst(option, customOptionScopeFinder, optionType);
@@ -147,16 +140,8 @@
     return descriptions;
   }
 
-  @Override public Collection<IEObjectDescription> allPossibleSourcesOf(CustomFieldOption option) {
-    OptionType optionType = typeOf(option);
-    Collection<IEObjectDescription> descriptions = emptySet();
-    if (optionType != null) {
-      descriptions = astWalker.traverseAst(option, customOptionScopeFinder, optionType);
-    }
-    return descriptions;
-  }
-
-  @SuppressWarnings("unused") public IScope scope_OptionField_target(OptionField field, EReference r) {
+  @SuppressWarnings("unused")
+  public IScope scope_OptionField_target(OptionField field, EReference r) {
     return createScope(allPossibleSourcesOf(field));
   }
 
@@ -165,52 +150,34 @@
       return emptySet();
     }
     EObject container = field.eContainer();
-    if (container instanceof CustomOption) {
-      CustomOption option = (CustomOption) container;
-      if (field instanceof MessageOptionField) { return findSources(option, (MessageOptionField) field); }
-      return findSources(option, (ExtensionOptionField) field);
-    }
-    if (container instanceof CustomFieldOption) {
-      CustomFieldOption option = (CustomFieldOption) container;
-      if (field instanceof MessageOptionField) { return findSources(option, (MessageOptionField) field); }
+    if (container instanceof AbstractCustomOption) {
+      AbstractCustomOption option = (AbstractCustomOption) container;
+      if (field instanceof MessageOptionField) {
+        return findSources(option, (MessageOptionField) field);
+      }
       return findSources(option, (ExtensionOptionField) field);
     }
     return emptySet();
   }
 
-  @Override public Collection<IEObjectDescription> allPossibleNormalFieldsOf(CustomOption option) {
+  @Override public Collection<IEObjectDescription> allPossibleNormalFieldsOf(AbstractCustomOption option) {
     return findSources(option, (MessageOptionField) null);
   }
 
-  @Override public Collection<IEObjectDescription> allPossibleNormalFieldsOf(CustomFieldOption option) {
-    return findSources(option, (MessageOptionField) null);
-  }
-
-  @Override public Collection<IEObjectDescription> allPossibleExtensionFieldsOf(CustomOption option) {
+  @Override public Collection<IEObjectDescription> allPossibleExtensionFieldsOf(AbstractCustomOption option) {
     return findSources(option, (ExtensionOptionField) null);
   }
 
-  @Override public Collection<IEObjectDescription> allPossibleExtensionFieldsOf(CustomFieldOption option) {
-    return findSources(option, (ExtensionOptionField) null);
+  private Collection<IEObjectDescription> findSources(AbstractCustomOption option, MessageOptionField optionField) {
+    return customOptionFieldScopeFinder.findScope(option, optionField);
   }
 
-  private Collection<IEObjectDescription> findSources(CustomOption option, MessageOptionField field) {
-    return customOptionFieldScopeFinder.findScope(option, field);
+  private Collection<IEObjectDescription> findSources(AbstractCustomOption option, ExtensionOptionField optionField) {
+    return customOptionFieldScopeFinder.findScope(option, optionField);
   }
 
-  private Collection<IEObjectDescription> findSources(CustomOption option, ExtensionOptionField field) {
-    return customOptionFieldScopeFinder.findScope(option, field);
-  }
-
-  private Collection<IEObjectDescription> findSources(CustomFieldOption option, MessageOptionField field) {
-    return customOptionFieldScopeFinder.findScope(option, field);
-  }
-
-  private Collection<IEObjectDescription> findSources(CustomFieldOption option, ExtensionOptionField field) {
-    return customOptionFieldScopeFinder.findScope(option, field);
-  }
-
-  @SuppressWarnings("unused") public IScope scope_FieldName_target(FieldName name, EReference r) {
+  @SuppressWarnings("unused")
+  public IScope scope_FieldName_target(FieldName name, EReference r) {
     return createScope(findSources(name));
   }
 
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Scoping.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Scoping.java
index 9f526bf..b5659a3 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Scoping.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Scoping.java
@@ -25,17 +25,11 @@
 
   Collection<IEObjectDescription> allPossibleMessagesFor(Rpc rpc);
 
-  Collection<IEObjectDescription> allPossibleSourcesOf(CustomOption option);
+  Collection<IEObjectDescription> allPossibleSourcesOf(AbstractCustomOption option);
 
-  Collection<IEObjectDescription> allPossibleSourcesOf(CustomFieldOption option);
+  Collection<IEObjectDescription> allPossibleNormalFieldsOf(AbstractCustomOption option);
 
-  Collection<IEObjectDescription> allPossibleNormalFieldsOf(CustomOption option);
-
-  Collection<IEObjectDescription> allPossibleNormalFieldsOf(CustomFieldOption option);
-
-  Collection<IEObjectDescription> allPossibleExtensionFieldsOf(CustomOption option);
-
-  Collection<IEObjectDescription> allPossibleExtensionFieldsOf(CustomFieldOption option);
+  Collection<IEObjectDescription> allPossibleExtensionFieldsOf(AbstractCustomOption option);
 
   Collection<IEObjectDescription> allPossibleNamesOfNormalFieldsOf(ComplexValue value);
 
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/DataTypeValidator.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/DataTypeValidator.java
index f6eab43..821ed43 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/DataTypeValidator.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/DataTypeValidator.java
@@ -8,7 +8,7 @@
  */
 package com.google.eclipse.protobuf.validation;
 
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.FIELD_OPTION__VALUE;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.ABSTRACT_OPTION__VALUE;
 import static com.google.eclipse.protobuf.validation.Messages.*;
 
 import org.eclipse.xtext.naming.*;
@@ -34,69 +34,62 @@
   @Inject private MessageFields messageFields;
   @Inject private ModelFinder modelFinder;
   @Inject private INodes nodes;
-  @Inject private Options options;
 
-  @Check public void checkValueOfDefaultTypeMatchesFieldType(FieldOption option) {
-    if (options.isDefaultValueOption(option)) {
-      MessageField field = (MessageField) option.eContainer();
-      checkValueTypeMatchesFieldType(option, field);
-    }
-  }
-
-  private void checkValueTypeMatchesFieldType(FieldOption option, MessageField field) {
-    if (validateBool(option, field)) {
+  @Check public void checkValueOfDefaultTypeMatchesFieldType(DefaultValueFieldOption option) {
+    MessageField field = (MessageField) option.eContainer();
+    if (messageFields.isBool(field)) {
+      validateBool(option);
       return;
     }
-    if (validateFloatingPointNumber(option, field)) {
+    if (messageFields.isFloatingPointNumber(field)) {
+      validateFloatingPointNumber(option);
       return;
     }
-    if (validateInteger(option, field)) {
+    if (messageFields.isInteger(field)) {
+      validateInteger(option);
       return;
     }
-    if (validateString(option, field)) {
-      return;
-    }
-    validateEnumLiteral(option, field);
-  }
-
-  private boolean validateBool(FieldOption option, MessageField field) {
-    if (!messageFields.isBool(field)) {
-      return false;
-    }
-    Value value = option.getValue();
-    if (!(value instanceof BooleanLink)) {
-      error(expectedTrueOrFalse, option, FIELD_OPTION__VALUE, EXPECTED_BOOL_ERROR);
-    }
-    return true;
-  }
-
-  private boolean validateFloatingPointNumber(FieldOption option, MessageField field) {
-    if (!messageFields.isFloatingPointNumber(field)) {
-      return false;
-    }
-    Value value = option.getValue();
-    if (!(value instanceof DoubleLink) && !isInteger(value)) {
-      error(expectedNumber, FIELD_OPTION__VALUE);
-    }
-    return true;
-  }
-
-  private boolean validateInteger(FieldOption option, MessageField field) {
-    if (!messageFields.isInteger(field)) {
-      return false;
-    }
-    Value value = option.getValue();
-    if (!isInteger(value)) {
-      error(expectedInteger, FIELD_OPTION__VALUE);
-      return true;
-    }
     if (messageFields.isUnsignedInteger(field)) {
-      long longValue = longValueIn(value);
-      if (longValue < 0) {
-        error(expectedPositiveNumber, FIELD_OPTION__VALUE);
-      }
+      validateUnsignedInteger(option);
+      return;
     }
-    return true;
+    if (messageFields.isBytes(field) || messageFields.isString(field)) {
+      validateString(option);
+      return;
+    }
+    Enum anEnum = modelFinder.enumTypeOf(field);
+    if (anEnum != null) {
+      validateEnumLiteral(option, anEnum);
+    }
+  }
+
+  private void validateBool(DefaultValueFieldOption option) {
+    Value value = option.getValue();
+    if (!(value instanceof BooleanLink)) {
+      error(expectedTrueOrFalse, option, ABSTRACT_OPTION__VALUE, EXPECTED_BOOL_ERROR);
+    }
+  }
+
+  private void validateFloatingPointNumber(DefaultValueFieldOption option) {
+    Value value = option.getValue();
+    if (!(value instanceof DoubleLink) && !isInteger(value)) {
+      error(expectedNumber, ABSTRACT_OPTION__VALUE);
+    }
+  }
+
+  private void validateInteger(DefaultValueFieldOption option) {
+    Value value = option.getValue();
+    if (!isInteger(value)) {
+      error(expectedInteger, ABSTRACT_OPTION__VALUE);
+    }
+  }
+
+  private void validateUnsignedInteger(DefaultValueFieldOption option) {
+    Value value = option.getValue();
+    long longValue = longValueIn(value);
+    if (longValue < 0) {
+      error(expectedPositiveNumber, ABSTRACT_OPTION__VALUE);
+    }
   }
 
   private boolean isInteger(Value value) {
@@ -115,25 +108,20 @@
     throw new IllegalArgumentException(value + " does not belong to an integer type");
   }
 
-  private boolean validateString(FieldOption option, MessageField field) {
-    if (!messageFields.isBytes(field) && !messageFields.isString(field)) {
-      return false;
-    }
+  private void validateString(DefaultValueFieldOption option) {
     Value value = option.getValue();
     if (!(value instanceof StringLink)) {
-      error(expectedString, option, FIELD_OPTION__VALUE, EXPECTED_STRING_ERROR);
+      error(expectedString, option, ABSTRACT_OPTION__VALUE, EXPECTED_STRING_ERROR);
     }
-    return true;
   }
 
-  private boolean validateEnumLiteral(FieldOption option, MessageField field) {
+  private boolean validateEnumLiteral(DefaultValueFieldOption option, Enum anEnum) {
     Value value = option.getValue();
-    Enum anEnum = modelFinder.enumTypeOf(field);
     if (anEnum == null) {
       return false;
     }
     if (!(value instanceof LiteralLink)) {
-      error(expectedIdentifier, FIELD_OPTION__VALUE);
+      error(expectedIdentifier, ABSTRACT_OPTION__VALUE);
       return true;
     }
     Literal literal = ((LiteralLink) value).getTarget();
@@ -141,12 +129,12 @@
       QualifiedName enumFqn = fqnProvider.getFullyQualifiedName(anEnum);
       String literalName = nodes.textOf(nodeForValueFeatureIn(option));
       String msg = String.format(literalNotInEnum, enumFqn, literalName);
-      error(msg, FIELD_OPTION__VALUE);
+      error(msg, ABSTRACT_OPTION__VALUE);
     }
     return true;
   }
 
-  private INode nodeForValueFeatureIn(FieldOption option) {
-    return nodes.firstNodeForFeature(option, FIELD_OPTION__VALUE);
+  private INode nodeForValueFeatureIn(DefaultValueFieldOption option) {
+    return nodes.firstNodeForFeature(option, ABSTRACT_OPTION__VALUE);
   }
 }