In progress: [Issue 155] Editor does not support complex custom options.

Code cleanup.
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/FieldOptions_fieldFrom_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/FieldOptions_lastFieldSourceFrom_Test.java
similarity index 87%
rename from com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/FieldOptions_fieldFrom_Test.java
rename to com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/FieldOptions_lastFieldSourceFrom_Test.java
index 63ed81e..766733d 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/FieldOptions_fieldFrom_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/FieldOptions_lastFieldSourceFrom_Test.java
@@ -19,11 +19,11 @@
 import org.junit.*;
 
 /**
- * Tests for <code>{@link FieldOptions#fieldFrom(CustomFieldOption)}</code>.
+ * Tests for <code>{@link FieldOptions#lastFieldSourceFrom(CustomFieldOption)}</code>.
  * 
  * alruiz@google.com (Alex Ruiz)
  */
-public class FieldOptions_fieldFrom_Test {
+public class FieldOptions_lastFieldSourceFrom_Test {
 
   @Rule public XtextRule xtext = createWith(integrationTestSetup());
 
@@ -48,7 +48,7 @@
   //  }
   @Test public void should_return_property_field() {
     CustomFieldOption option = xtext.find("custom", ").", CustomFieldOption.class);
-    Property p = fieldOptions.fieldFrom(option);
+    Property p = (Property) fieldOptions.lastFieldSourceFrom(option);
     assertThat(p.getName(), equalTo("count"));
   }
 }
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_fieldFrom_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_lastFieldSourceFrom_Test.java
similarity index 87%
rename from com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_fieldFrom_Test.java
rename to com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_lastFieldSourceFrom_Test.java
index 4be5b3f..0df73bd 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_fieldFrom_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/model/util/Options_lastFieldSourceFrom_Test.java
@@ -19,11 +19,11 @@
 import org.junit.*;
 
 /**
- * Tests for <code>{@link Options#fieldFrom(CustomOption)}</code>.
+ * Tests for <code>{@link Options#lastFieldSourceFrom(CustomOption)}</code>.
  * 
  * alruiz@google.com (Alex Ruiz)
  */
-public class Options_fieldFrom_Test {
+public class Options_lastFieldSourceFrom_Test {
 
   @Rule public XtextRule xtext = createWith(integrationTestSetup());
 
@@ -46,7 +46,7 @@
   // option (custom).count = 6;
   @Test public void should_return_property_field() {
     CustomOption option = xtext.find("custom", ")", CustomOption.class);
-    Property p = options.fieldFrom(option);
+    Property p = (Property) options.lastFieldSourceFrom(option);
     assertThat(p.getName(), equalTo("count"));
   }
 }
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 5efc73c..8923b87 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
@@ -481,7 +481,7 @@
       ICompletionProposalAcceptor acceptor) {
     if (!(model instanceof CustomOption)) return;
     CustomOption option = (CustomOption) model;
-    Field f = options.fieldFrom(option);
+    Field f = options.lastFieldSourceFrom(option);
     if (f == null) f = options.sourceOf(option);
     if (f instanceof Property) {
       proposeAndAcceptOptionFieldValue((Property) f, context, acceptor);
@@ -493,9 +493,11 @@
     // TODO content assist returns "{"
     if (!(model instanceof CustomFieldOption)) return;
     CustomFieldOption option = (CustomFieldOption) model;
-    Property property = fieldOptions.fieldFrom(option);
-    if (property == null) property = fieldOptions.fieldFrom(option);
-    proposeAndAcceptOptionFieldValue(property, context, acceptor);
+    Field field = fieldOptions.lastFieldSourceFrom(option);
+    if (field == null) field = fieldOptions.sourceOf(option);
+    if (field instanceof Property) {
+      proposeAndAcceptOptionFieldValue((Property) field, context, acceptor);
+    }
   }
 
   private void proposeAndAcceptOptionFieldValue(Property property, ContentAssistContext context,
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/FieldOptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/FieldOptions.java
index 9717eb6..8cfd6cc 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/FieldOptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/FieldOptions.java
@@ -9,7 +9,9 @@
 package com.google.eclipse.protobuf.model.util;
 
 import com.google.eclipse.protobuf.protobuf.*;
-import com.google.inject.Singleton;
+import com.google.inject.*;
+
+import java.util.List;
 
 /**
  * Utility methods related to field options.
@@ -19,6 +21,8 @@
 @Singleton
 public class FieldOptions {
 
+  private @Inject OptionFields optionFields;
+
   /**
    * Indicates whether the given option is the "default value" one.
    * @param option the given option to check.
@@ -63,19 +67,20 @@
   }
 
   /**
-   * Returns the field of the <code>{@link Field}</code> the given <code>{@link CustomFieldOption}</code> is referring 
-   * to. In the following example
+   * Returns the last field of the given <code>{@link CustomFieldOption}</code>.
+   * In the following example
    * <pre>
-   * [(myFieldOption).field = true]
+   * [(myOption).foo = true];
    * </pre>
-   * this method will return the <code>{@link Field}</code> "field" is pointing to.
-   * @param option the given {@code FieldOption}.
-   * @return the field of the {@code Field} the given {@code CustomFieldOption} is referring to, or {@code null} if 
-   * one cannot be found.
+   * 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 Property fieldFrom(CustomFieldOption option) {
-    return null;
-    // SimplePropertyRef ref = option.getPropertyField();
-    // return (ref == null) ? null : ref.getProperty();
+  public Field lastFieldSourceFrom(CustomFieldOption option) {
+    List<OptionFieldSource> fields = option.getOptionFields();
+    if (fields.isEmpty()) return null;
+    OptionFieldSource last = fields.get(fields.size() - 1);
+    return optionFields.sourceOf(last);
   }
 }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/OptionFields.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/OptionFields.java
new file mode 100644
index 0000000..b3110e2
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/OptionFields.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011 Google Inc.
+ *
+ * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
+ * Public License v1.0 which accompanies this distribution, and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package com.google.eclipse.protobuf.model.util;
+
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.inject.Singleton;
+
+/**
+ * Utility methods related to fields in <code>{@link Option}</code>s
+ * 
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@Singleton
+public class OptionFields {
+
+  /**
+   * Returns the field the given option field is referring to.
+   * @param fieldSource the given option field.
+   * @return the field the given option field is referring to, or {@code null} if one cannot be found.
+   */
+  public Field sourceOf(OptionFieldSource fieldSource) {
+    if (fieldSource instanceof OptionMessageFieldSource) {
+      OptionMessageFieldSource source = (OptionMessageFieldSource) fieldSource;
+      return source.getOptionMessageField();
+    }
+    if (fieldSource instanceof OptionExtendMessageFieldSource) {
+      OptionExtendMessageFieldSource source = (OptionExtendMessageFieldSource) fieldSource;
+      return source.getOptionExtendMessageField();
+    }
+    return null;
+  }
+}
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 d199747..a4e4fdc 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
@@ -9,7 +9,9 @@
 package com.google.eclipse.protobuf.model.util;
 
 import com.google.eclipse.protobuf.protobuf.*;
-import com.google.inject.Singleton;
+import com.google.inject.*;
+
+import java.util.List;
 
 /**
  * Utility methods related to <code>{@link Option}</code>.
@@ -19,6 +21,8 @@
 @Singleton
 public class Options {
 
+  private @Inject OptionFields optionFields;
+  
   /**
    * Returns the <code>{@link Field}</code> the given <code>{@link Option}</code> is referring to. In the
    * following example
@@ -36,19 +40,19 @@
   }
 
   /**
-   * Returns the field of the <code>{@link Property}</code> the given <code>{@link CustomOption}</code> is referring to.
+   * Returns the last field of the given <code>{@link CustomOption}</code>.
    * In the following example
    * <pre>
-   * option (myOption).field = true;
+   * option (myOption).foo = true;
    * </pre>
-   * this method will return the <code>{@link Property}</code> "field" is pointing to.
-   * @param option the given {@code Option}.
-   * @return the field of the {@code Property} the given {@code CustomOption} is referring to, or {@code null} if one
-   * cannot be found.
+   * 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.
    */
-  public Property fieldFrom(CustomOption option) {
-    return null;
-    // SimplePropertyRef ref = option.getPropertyField();
-    // return (ref == null) ? null : ref.getProperty();
+  public Field lastFieldSourceFrom(CustomOption option) {
+    List<OptionFieldSource> fields = option.getOptionFields();
+    if (fields.isEmpty()) return null;
+    OptionFieldSource last = fields.get(fields.size() - 1);
+    return optionFields.sourceOf(last);
   }
 }
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 21a625f..f61076f 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
@@ -27,6 +27,7 @@
 
   @Inject private FieldOptions fieldOptions;
   @Inject private ModelFinder modelFinder;
+  @Inject private OptionFields optionFields;
   @Inject private Options options;
   @Inject private QualifiedNameDescriptions qualifiedNamesDescriptions;
 
@@ -93,7 +94,7 @@
   private Field referredField(EObject fieldSource, final CustomFieldOption option) {
     return referredField(fieldSource, option.getOptionFields(), new Provider<Field>() {
       @Override public Field get() {
-        return fieldOptions.fieldFrom(option);
+        return fieldOptions.sourceOf(option);
       }
     });
   }
@@ -104,25 +105,13 @@
     boolean isFirstField = true;
     for (OptionFieldSource s : allFieldSources) {
       if (s == fieldSource) {
-        return (isFirstField) ? provider.get() : fieldFrom(previous);
+        return (isFirstField) ? provider.get() : optionFields.sourceOf(previous);
       }
       previous = s;
       isFirstField = false;
     }
     return null;
   }
-
-  private Field fieldFrom(OptionFieldSource fieldSource) {
-    if (fieldSource instanceof OptionMessageFieldSource) {
-      OptionMessageFieldSource source = (OptionMessageFieldSource) fieldSource;
-      return source.getOptionMessageField();
-    }
-    if (fieldSource instanceof OptionExtendMessageFieldSource) {
-      OptionExtendMessageFieldSource source = (OptionExtendMessageFieldSource) fieldSource;
-      return source.getOptionExtendMessageField();
-    }
-    return null;
-  }
   
   private static interface IEObjectDescriptionsProvider {
     Collection<IEObjectDescription> fieldsInType(Field f);
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 33c7d1c..c4b2893 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
@@ -73,22 +73,22 @@
     if (c instanceof NativeOption) {
       ProtoDescriptor descriptor = descriptorProvider.primaryDescriptor();
       Field f = options.sourceOf((Option) c);
-      if (f instanceof Property) anEnum = descriptor.enumTypeOf((Property) f);
+      anEnum = descriptor.enumTypeOf((Property) f);
     }
     if (c instanceof CustomOption) {
       CustomOption option = (CustomOption) c;
-      c = options.fieldFrom(option);
+      c = options.lastFieldSourceFrom(option);
       if (c == null) c = options.sourceOf(option);
     }
     if (c instanceof NativeFieldOption) {
       ProtoDescriptor descriptor = descriptorProvider.primaryDescriptor();
       Field f = fieldOptions.sourceOf((FieldOption) c);
-      if (f instanceof Property) anEnum = descriptor.enumTypeOf((Property) f);
+      anEnum = descriptor.enumTypeOf((Property) f);
     }
     if (c instanceof CustomFieldOption) {
       CustomFieldOption option = (CustomFieldOption) c;
-      c = fieldOptions.fieldFrom(option);
-      if (c == null) c = fieldOptions.fieldFrom(option);
+      c = fieldOptions.lastFieldSourceFrom(option);
+      if (c == null) c = fieldOptions.sourceOf(option);
     }
     if (c instanceof Property) {
       anEnum = modelFinder.enumTypeOf((Property) c);