Fixed: [Issue 125] Support for custom options
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_PropertyRef_property_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_PropertyRef_property_Test.java
index 3d08c08..c66743d 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_PropertyRef_property_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_PropertyRef_property_Test.java
@@ -90,7 +90,30 @@
 
   // // Create file custom-options.proto
   // 
-  // package com.google.test;
+  // package test.proto;
+  //
+  // import "google/protobuf/descriptor.proto";
+  //
+  // extend google.protobuf.FileOptions {
+  //   optional int32 code = 1000;
+  //   optional int32 info = 1002;
+  // }  
+  
+  // package com.google.proto;
+  //  
+  // import 'custom-options.proto';
+  //
+  // option (test.proto.code) = 68;
+  @Test public void should_provide_imported_Property_fields_for_custom_option() {
+    Option option = xtext.find("code", ")", Option.class);
+    IScope scope = provider.scope_PropertyRef_property(option.getProperty(), reference);
+    assertThat(descriptionsIn(scope), containAll("test.proto.code", ".test.proto.code",
+                                                 "test.proto.info", ".test.proto.info"));
+  }
+
+  // // Create file custom-options.proto
+  // 
+  // package com.google.proto;
   //
   // import "google/protobuf/descriptor.proto";
   //
@@ -104,15 +127,15 @@
   // import 'custom-options.proto';
   //
   // option (code) = 68;
-  @Test public void should_provide_imported_Property_fields_for_custom_option() {
+  @Test public void should_provide_imported_Property_fields_for_custom_option_with_equal_package() {
     Option option = xtext.find("code", ")", Option.class);
     IScope scope = provider.scope_PropertyRef_property(option.getProperty(), reference);
-    assertThat(descriptionsIn(scope), containAll("code", "test.code", "google.test.code", "com.google.test.code", 
-                                                 ".com.google.test.code",
-                                                 "info", "test.info", "google.test.info", "com.google.test.info", 
-                                                 ".com.google.test.info"));
+    assertThat(descriptionsIn(scope), containAll("code", "proto.code", "google.proto.code", "com.google.proto.code", 
+                                                 ".com.google.proto.code",
+                                                 "info", "proto.info", "google.proto.info", "com.google.proto.info",
+                                                 ".com.google.proto.info"));
   }
-
+ 
   // package com.google.proto;
   // import 'google/protobuf/descriptor.proto';
   //  
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_TypeRef_type_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_TypeRef_type_Test.java
index bbd6b84..578d94c 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_TypeRef_type_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_TypeRef_type_Test.java
@@ -60,7 +60,7 @@
   // message Contact {
   //   optional Type type = 1;  
   // }
-  @Test public void should_provide_Property_fields_for_custom_option_field() {
+  @Test public void should_provide_Types() {
     Property p = xtext.find("type", Property.class);
     IScope scope = provider.scope_TypeRef_type(typeOf(p), reference);
     assertThat(descriptionsIn(scope), containAll("Type", "proto.Type", "google.proto.Type", "com.google.proto.Type", 
@@ -71,6 +71,142 @@
                                                  "com.google.proto.Contact", ".com.google.proto.Contact"));
   }
   
+  // // Create file types.proto
+  // 
+  // package test.proto;
+  //
+  // enum Type {
+  //   PERSONAL = 0;
+  //   BUSINESS = 1;
+  // }
+  //
+  // message Address {
+  //   optional int32 number = 1;
+  //   optional string street = 2;
+  //   optional string city = 3;
+  //   optional int32 zipCode = 4;
+  // }
+  
+  // package com.google.proto;
+  // 
+  // import "types.proto";
+  //
+  // message Contact {
+  //   optional com.google.test.Type type = 1;  
+  // }
+  @Test public void should_provide_imported_Types() {
+    Property p = xtext.find("type", " =", Property.class);
+    IScope scope = provider.scope_TypeRef_type(typeOf(p), reference);
+    assertThat(descriptionsIn(scope), containAll("test.proto.Type", ".test.proto.Type",
+                                                 "test.proto.Address", ".test.proto.Address",
+                                                 "Contact", "proto.Contact", "google.proto.Contact", 
+                                                 "com.google.proto.Contact", ".com.google.proto.Contact"));
+  }
+
+  // // Create file types.proto
+  // 
+  // package com.google.proto;
+  //
+  // enum Type {
+  //   PERSONAL = 0;
+  //   BUSINESS = 1;
+  // }
+  //
+  // message Address {
+  //   optional int32 number = 1;
+  //   optional string street = 2;
+  //   optional string city = 3;
+  //   optional int32 zipCode = 4;
+  // }
+  
+  // package com.google.proto;
+  // 
+  // import "types.proto";
+  //
+  // message Contact {
+  //   optional com.google.test.Type type = 1;  
+  // }
+  @Test public void should_provide_imported_Types_with_equal_package() {
+    Property p = xtext.find("type", " =", Property.class);
+    IScope scope = provider.scope_TypeRef_type(typeOf(p), reference);
+    assertThat(descriptionsIn(scope), containAll("Type", "proto.Type", "google.proto.Type", "com.google.proto.Type",
+                                                 ".com.google.proto.Type",
+                                                 "Address", "proto.Address", "google.proto.Address",
+                                                 "com.google.proto.Address", ".com.google.proto.Address",
+                                                 "Contact", "proto.Contact", "google.proto.Contact", 
+                                                 "com.google.proto.Contact", ".com.google.proto.Contact"));
+  }
+
+  // // Create file types.proto
+  // 
+  // package test.proto;
+  //
+  // enum Type {
+  //   PERSONAL = 0;
+  //   BUSINESS = 1;
+  // }
+  //
+  // message Address {
+  //   optional int32 number = 1;
+  //   optional string street = 2;
+  //   optional string city = 3;
+  //   optional int32 zipCode = 4;
+  // }
+  
+  // package com.google.proto;
+  // 
+  // import public "types.proto";
+  //
+  // message Contact {
+  //   optional test.proto.Type type = 1;  
+  // }
+  @Test public void should_provide_public_imported_Types() {
+    Property p = xtext.find("type", " =", Property.class);
+    IScope scope = provider.scope_TypeRef_type(typeOf(p), reference);
+    assertThat(descriptionsIn(scope), containAll("test.proto.Type", ".test.proto.Type",
+                                                 "test.proto.Address", ".test.proto.Address",
+                                                 "Contact", "proto.Contact", "google.proto.Contact", 
+                                                 "com.google.proto.Contact", ".com.google.proto.Contact"));
+  }
+
+  // // Create file public-types.proto
+  // 
+  // package test.proto;
+  //
+  // enum Type {
+  //   PERSONAL = 0;
+  //   BUSINESS = 1;
+  // }
+  //
+  // message Address {
+  //   optional int32 number = 1;
+  //   optional string street = 2;
+  //   optional string city = 3;
+  //   optional int32 zipCode = 4;
+  // }
+
+  // // Create file types.proto
+  // 
+  // package com.google.proto;
+  // 
+  // import public "public-types.proto";
+
+  // package com.google.proto;
+  // 
+  // import "types.proto";
+  //
+  // message Contact {
+  //   optional test.proto.Type type = 1;  
+  // }
+  @Test public void should_provide_public_imported_Types_with_more_than_one_level() {
+    Property p = xtext.find("type", " =", Property.class);
+    IScope scope = provider.scope_TypeRef_type(typeOf(p), reference);
+    assertThat(descriptionsIn(scope), containAll("test.proto.Type", ".test.proto.Type",
+                                                 "test.proto.Address", ".test.proto.Address",
+                                                 "Contact", "proto.Contact", "google.proto.Contact", 
+                                                 "com.google.proto.Contact", ".com.google.proto.Contact"));
+  }
+
   private static TypeRef typeOf(Property p) {
     return (TypeRef) p.getType();
   }
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentProcessor.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentProcessor.java
index 8423fb0..acdf358 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentProcessor.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentProcessor.java
@@ -8,8 +8,7 @@
  */
 package com.google.eclipse.protobuf.junit.core;
 
-import static com.google.eclipse.protobuf.junit.core.GeneratedProtoFiles.PARENT_DIRECTORY_NAME;
-import static java.io.File.separator;
+import static com.google.eclipse.protobuf.junit.core.GeneratedProtoFiles.*;
 
 import java.io.*;
 import java.util.Scanner;
@@ -36,8 +35,8 @@
   }
 
   private File createFile(String fileName, String contents) {
-    verifyParentDirectoryExists();
-    File file = new File(PARENT_DIRECTORY_NAME + separator + fileName);
+    ensureParentDirectoryExists();
+    File file = protoFile(fileName);
     if (file.isFile()) file.delete();
     Writer out = null;
     try {
@@ -50,12 +49,6 @@
     }
     return file;
   }
-
-  private void verifyParentDirectoryExists() {
-    File directory = new File(PARENT_DIRECTORY_NAME);
-    if (directory.isDirectory()) return;
-    directory.mkdir();
-  }
   
   private void closeQuietly(Writer out) {
     if (out == null) return;
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/GeneratedProtoFiles.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/GeneratedProtoFiles.java
index c281b7c..bed18ac 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/GeneratedProtoFiles.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/GeneratedProtoFiles.java
@@ -8,12 +8,29 @@
  */
 package com.google.eclipse.protobuf.junit.core;
 
+import static java.io.File.separator;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import java.io.File;
+
 /**
  * @author alruiz@google.com (Alex Ruiz)
  */
 final class GeneratedProtoFiles {
 
-  static final String PARENT_DIRECTORY_NAME = "test-protos";
+  private static final String PARENT_DIRECTORY_NAME = "test-protos";
+  
+  static File protoFile(String fileName) {
+    return new File(PARENT_DIRECTORY_NAME + separator + fileName);
+  }
+  
+  static void ensureParentDirectoryExists() {
+    File parent = new File(PARENT_DIRECTORY_NAME);
+    if (!parent.isDirectory()) {
+      assertThat(parent.mkdir(), equalTo(true));
+    }
+  }
   
   private GeneratedProtoFiles() {}
 }
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestSetup.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestSetup.java
index 4eae4e7..647c6cc 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestSetup.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestSetup.java
@@ -8,19 +8,18 @@
  */
 package com.google.eclipse.protobuf.junit.core;
 
-import static com.google.eclipse.protobuf.junit.core.GeneratedProtoFiles.PARENT_DIRECTORY_NAME;
-import static java.io.File.separator;
+import static com.google.eclipse.protobuf.junit.core.GeneratedProtoFiles.protoFile;
 import static org.eclipse.xtext.util.Strings.isEmpty;
 
-import java.io.File;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.resource.Resource;
-
 import com.google.eclipse.protobuf.*;
 import com.google.eclipse.protobuf.scoping.IFileUriResolver;
 import com.google.inject.*;
 
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+
+import java.io.File;
+
 /**
  * @author alruiz@google.com (Alex Ruiz)
  */
@@ -44,7 +43,7 @@
     public String resolveUri(String importUri, Resource declaringResource) {
       URI uri = URI.createURI(importUri);
       if (!isEmpty(uri.scheme())) return importUri; // already resolved.
-      File file = new File(PARENT_DIRECTORY_NAME + separator + importUri);
+      File file = protoFile(importUri);
       if (!file.exists()) throw new IllegalArgumentException("File: " + importUri + " does not exist.");
       return file.toURI().toString();
     }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/CustomOptionProperties.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/CustomOptionProperties.java
deleted file mode 100644
index 177d077..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/CustomOptionProperties.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.ui.contentassist;
-
-import static java.util.Collections.*;
-import static org.eclipse.emf.ecore.util.EcoreUtil.getAllContents;
-
-import com.google.eclipse.protobuf.model.OptionType;
-import com.google.eclipse.protobuf.model.util.*;
-import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.protobuf.Package;
-import com.google.inject.Inject;
-
-import org.eclipse.emf.common.util.TreeIterator;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.*;
-
-import java.util.*;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class CustomOptionProperties {
-
-  @Inject private Imports imports;
-  @Inject private ModelFinder finder;
-  @Inject private Options options;
-  @Inject private Packages packages;
-  @Inject private Resources resources;
-
-  Collection<Property> propertiesFor(CustomOption option) {
-    OptionType type = OptionType.typeOf(option);
-    if (type == null) return emptyList();
-    Protobuf root = finder.rootOf(option);
-    if (root == null) return emptyList();
-    List<Property> properties = new ArrayList<Property>();
-    properties.addAll(local(root, type));
-    properties.addAll(imported(root, type));
-    return unmodifiableList(properties);
-  }
-
-  private Collection<Property> local(Protobuf root, OptionType type) {
-    return local(root, type, 0);
-  }
-
-  private Collection<Property> local(EObject root, OptionType optionType, int level) {
-    List<Property> properties = new ArrayList<Property>();
-    for (EObject element : root.eContents()) {
-      if (options.isExtendingOptionMessage(element, optionType)) {
-        ExtendMessage extend = (ExtendMessage) element;
-        for (MessageElement e : extend.getElements()) {
-          if (!(e instanceof Property)) continue;
-          properties.add((Property) e);
-        }
-      }
-      if (element instanceof Message) {
-        properties.addAll(local(element, optionType, level + 1));
-      }
-    }
-    return unmodifiableList(properties);
-  }
-
-  private Collection<Property> imported(Protobuf root, OptionType optionType) {
-    List<Import> allImports = finder.importsIn(root);
-    if (allImports.isEmpty()) return emptyList();
-    ResourceSet resourceSet = root.eResource().getResourceSet();
-    return imported(allImports, finder.packageOf(root), resourceSet, optionType);
-  }
-
-  private Collection<Property> imported(List<Import> allImports, Package aPackage,
-      ResourceSet resourceSet, OptionType optionType) {
-    List<Property> properties = new ArrayList<Property>();
-    for (Import anImport : allImports) {
-      if (imports.isImportingDescriptor(anImport)) continue;
-      Resource importedResource = resources.importedResource(anImport, resourceSet);
-      Protobuf importedRoot = finder.rootOf(importedResource);
-      if (importedRoot != null) {
-        properties.addAll(publicImported(importedRoot, optionType));
-        if (arePackagesRelated(aPackage, importedRoot)) {
-          properties.addAll(local(importedRoot, optionType));
-          continue;
-        }
-      }
-      properties.addAll(local(importedResource, optionType));
-    }
-    return unmodifiableList(properties);
-  }
-
-  private Collection<Property> publicImported(Protobuf root, OptionType optionType) {
-    List<Import> allImports = finder.publicImportsIn(root);
-    if (allImports.isEmpty()) return emptyList();
-    ResourceSet resourceSet = root.eResource().getResourceSet();
-    return imported(allImports, finder.packageOf(root), resourceSet, optionType);
-  }
-
-  private boolean arePackagesRelated(Package aPackage, EObject root) {
-    Package p = finder.packageOf(root);
-    return packages.areRelated(aPackage, p);
-  }
-
-  private Collection<Property> local(Resource resource, OptionType optionType) {
-    List<Property> properties = new ArrayList<Property>();
-    TreeIterator<Object> contents = getAllContents(resource, true);
-    while (contents.hasNext()) {
-      Object next = contents.next();
-      if (!options.isExtendingOptionMessage((EObject) next, optionType)) continue;
-      ExtendMessage extend = (ExtendMessage) next;
-      for (MessageElement e : extend.getElements()) {
-        if (e instanceof Property) properties.add((Property) e);
-      }
-    }
-    return properties;
-  }
-}
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 25c5245..bbb4853 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
@@ -25,6 +25,8 @@
 import org.eclipse.swt.graphics.Image;
 import org.eclipse.xtext.*;
 import org.eclipse.xtext.naming.*;
+import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.scoping.IScope;
 import org.eclipse.xtext.ui.PluginImageHelper;
 import org.eclipse.xtext.ui.editor.contentassist.*;
 
@@ -46,7 +48,7 @@
  */
 public class ProtobufProposalProvider extends AbstractProtobufProposalProvider {
 
-  @Inject private CustomOptionProperties customOptionProperties;
+  @Inject private ProtobufScopeProvider scopes;
   @Inject private ProtoDescriptorProvider descriptorProvider;
   @Inject private FieldOptions fieldOptions;
   @Inject private ModelFinder finder;
@@ -54,7 +56,6 @@
   @Inject private Images images;
   @Inject private PluginImageHelper imageHelper;
   @Inject private Literals literals;
-  @Inject private IQualifiedNameProvider nameProvider;
   @Inject private Options options;
   @Inject private Properties properties;
   
@@ -410,27 +411,59 @@
   @Override public void completeCustomOption_Property(EObject model, Assignment assignment,
       ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
     if (!(model instanceof CustomOption)) return;
-    Image image = imageForOption();
-    for (Property p : customOptionProperties.propertiesFor((CustomOption) model)) {
-      QualifiedName name = nameProvider.getFullyQualifiedName(p);
-      proposeAndAccept(name.toString(), image, context, acceptor);
-    }
+    CustomOption option = (CustomOption) model;
+    IScope scope = scopes.scope_PropertyRef_property(option.getProperty(), null);
+    proposeAndAcceptOptions(scope, context, acceptor);
   }
 
+  @Override public void completeCustomFieldOption_Property(EObject model, Assignment assignment,
+      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+    if (!(model instanceof CustomFieldOption)) return;
+    CustomFieldOption option = (CustomFieldOption) model;
+    IScope scope = scopes.scope_PropertyRef_property(option.getProperty(), null);
+    proposeAndAcceptOptions(scope, context, acceptor);
+  }
+  
+  private void proposeAndAcceptOptions(IScope scope, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+    Image image = imageForOption();
+    for (IEObjectDescription d : scope.getAllElements()) {
+      proposeAndAccept(d, image, context, acceptor);
+    }
+  }
+  
   private Image imageForOption() {
     return imageHelper.getImage(images.imageFor(Option.class));
   }
+
+  private void proposeAndAccept(IEObjectDescription d, Image image, ContentAssistContext context,
+      ICompletionProposalAcceptor acceptor) {
+    QualifiedName name = d.getName();
+    String display = name.getLastSegment()  + " - " + name.toString();
+    ICompletionProposal proposal = createCompletionProposal(name.toString(), display, image, context);
+    acceptor.accept(proposal);
+  }
   
   @Override public void completeCustomOption_PropertyField(EObject model, Assignment assignment,
       ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
     if (!(model instanceof CustomOption)) return;
     Property property = options.propertyFrom((CustomOption) model);
-    if (property == null) return;
+    proposeAndAcceptOptionFields(property, context, acceptor);
+  }
+  
+  @Override public void completeCustomFieldOption_PropertyField(EObject model, Assignment assignment,
+      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+    if (!(model instanceof CustomFieldOption)) return;
+    Property property = fieldOptions.propertyFrom((CustomFieldOption) model);
+    proposeAndAcceptOptionFields(property, context, acceptor);
+  }
+  
+  private void proposeAndAcceptOptionFields(Property property, ContentAssistContext context,
+      ICompletionProposalAcceptor acceptor) {
     Message message = finder.messageTypeOf(property);
-    if (message != null) {
-      Image image = imageHelper.getImage("property.gif");
-      for (Property p : finder.propertiesOf(message))
-        proposeAndAccept(p.getName(), image, context, acceptor);
+    if (message == null) return;
+    Image image = imageHelper.getImage("property.gif");
+    for (Property p : finder.propertiesOf(message)) {
+      proposeAndAccept(p.getName(), image, context, acceptor);
     }
   }
 
@@ -440,6 +473,21 @@
     CustomOption option = (CustomOption) model;
     Property property = options.fieldFrom(option);
     if (property == null) property = options.propertyFrom(option);
+    proposeAndAcceptOptionFieldValue(property, context, acceptor);
+  }
+  
+  @Override public void completeCustomFieldOption_Value(EObject model, Assignment assignment,
+      ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+    // TODO content assist returns "{"
+    if (!(model instanceof CustomFieldOption)) return;
+    CustomFieldOption option = (CustomFieldOption) model;
+    Property property = fieldOptions.fieldFrom(option);
+    if (property == null) property = fieldOptions.propertyFrom(option);
+    proposeAndAcceptOptionFieldValue(property, context, acceptor);
+  }
+
+  private void proposeAndAcceptOptionFieldValue(Property property, ContentAssistContext context,
+      ICompletionProposalAcceptor acceptor) {
     if (property == null) return;
     if (proposePrimitiveValues(property, context, acceptor)) return;
     Enum enumType = finder.enumTypeOf(property);
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/OptionType.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/OptionType.java
index 339cf77..a0dec62 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/OptionType.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/OptionType.java
@@ -23,6 +23,8 @@
  */
 public enum OptionType {
   
+  // TODO move back to package "com.google.eclipse.protobuf.scoping" and make it package-protected.
+  
   FILE("FileOptions"), MESSAGE("MessageOptions"), FIELD("FieldOptions"), ENUM("EnumOptions"),
       LITERAL("EnumValueOptions"), SERVICE("ServiceOptions"), RPC("MethodOptions");
 
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionDescriptions.java
index 5963194..c459561 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionDescriptions.java
@@ -33,7 +33,6 @@
 class CustomOptionDescriptions {
 
   @Inject private ModelFinder finder;
-  @Inject private ImportedNamesProvider importedNamesProvider;
   @Inject private Imports imports;
   @Inject private LocalNamesProvider localNamesProvider;
   @Inject private Options options;
@@ -41,16 +40,16 @@
   @Inject private QualifiedNameDescriptions qualifiedNamesDescriptions;
   @Inject private Resources resources;
 
-  Collection <IEObjectDescription> properties(CustomOption option) {
+  public Collection <IEObjectDescription> properties(CustomOption option) {
     return allProperties(option, typeOf(option));
   }
 
-  Collection <IEObjectDescription> properties(CustomFieldOption option) {
+  public Collection <IEObjectDescription> properties(CustomFieldOption option) {
     return allProperties(option, typeOf(option));
   }
 
   private Collection <IEObjectDescription> allProperties(EObject option, OptionType type) {
-    Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
+    Set<IEObjectDescription> descriptions = new LinkedHashSet<IEObjectDescription>();
     EObject current = option.eContainer();
     while (current != null) {
       descriptions.addAll(local(current, type));
@@ -67,7 +66,7 @@
 
   private Collection <IEObjectDescription> local(EObject root, OptionType optionType, int level) {
     if (optionType == null) return emptyList();
-    Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
+    Set<IEObjectDescription> descriptions = new LinkedHashSet<IEObjectDescription>();
     for (EObject element : root.eContents()) {
       if (options.isExtendingOptionMessage(element, optionType)) {
         ExtendMessage extend = (ExtendMessage) element;
@@ -98,7 +97,7 @@
 
   private Collection<IEObjectDescription> imported(List<Import> allImports, Package aPackage,
       ResourceSet resourceSet, OptionType optionType) {
-    List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
+    Set<IEObjectDescription> descriptions = new LinkedHashSet<IEObjectDescription>();
     for (Import anImport : allImports) {
       if (imports.isImportingDescriptor(anImport)) continue;
       Resource importedResource = resources.importedResource(anImport, resourceSet);
@@ -138,9 +137,7 @@
         if (!(e instanceof Property)) continue;
         Property p = (Property) e;
         descriptions.addAll(qualifiedNamesDescriptions.qualifiedNames(p));
-        for (QualifiedName name : importedNamesProvider.namesOf(p)) {
-          descriptions.add(create(name, e));
-        }
+        // TODO verify that call to 'importedNamesProvider.namesOf' is not necessary
       }
     }
     return descriptions;
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 71c3955..1e050c7 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
@@ -43,7 +43,7 @@
   @Inject private TypeDescriptions typeDescriptions;
 
   @SuppressWarnings("unused")
-  IScope scope_TypeRef_type(TypeRef typeRef, EReference reference) {
+  public IScope scope_TypeRef_type(TypeRef typeRef, EReference reference) {
     EObject c = typeRef.eContainer();
     if (c instanceof Property) {
       Property property = (Property) c;
@@ -54,13 +54,13 @@
   }
 
   @SuppressWarnings("unused")
-  IScope scope_MessageRef_type(MessageRef messageRef, EReference reference) {
+  public IScope scope_MessageRef_type(MessageRef messageRef, EReference reference) {
     Protobuf root = finder.rootOf(messageRef);
     return createScope(typeDescriptions.messages(root));
   }
 
   @SuppressWarnings("unused")
-  IScope scope_LiteralRef_literal(LiteralRef literalRef, EReference reference) {
+  public IScope scope_LiteralRef_literal(LiteralRef literalRef, EReference reference) {
     EObject c = literalRef.eContainer();
     Enum anEnum = null;
     if (c instanceof DefaultValueFieldOption) {
@@ -94,7 +94,7 @@
   }
 
   @SuppressWarnings("unused")
-  IScope scope_PropertyRef_property(PropertyRef propertyRef, EReference reference) {
+  public IScope scope_PropertyRef_property(PropertyRef propertyRef, EReference reference) {
     EObject c = propertyRef.eContainer();
     if (c instanceof NativeOption) {
       NativeOption option = (NativeOption) c;
@@ -117,7 +117,7 @@
   }
   
   @SuppressWarnings("unused") 
-  IScope scope_SimplePropertyRef_property(SimplePropertyRef propertyRef, EReference reference) {
+  public IScope scope_SimplePropertyRef_property(SimplePropertyRef propertyRef, EReference reference) {
     EObject c = propertyRef.eContainer();
     Property property = null;
     if (c instanceof CustomOption) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java
index c9b78e6..2258513 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java
@@ -32,7 +32,6 @@
 
   @Inject private ProtoDescriptorProvider descriptorProvider;
   @Inject private ModelFinder finder;
-  @Inject private ImportedNamesProvider importedNamesProvider;
   @Inject private Imports imports;
   @Inject private LocalNamesProvider localNamesProvider;
   @Inject private Packages packages;
@@ -98,11 +97,11 @@
         continue;
       }
       Resource importedResource = resources.importedResource(anImport, resourceSet);
-      Protobuf importedRoot = finder.rootOf(importedResource);
-      if (importedRoot != null) {
-        descriptions.addAll(publicImported(importedRoot, targetType));
-        if (arePackagesRelated(aPackage, importedRoot)) {
-          descriptions.addAll(local(importedRoot, targetType));
+      Protobuf rootOfImported = finder.rootOf(importedResource);
+      if (rootOfImported != null) {
+        descriptions.addAll(publicImported(rootOfImported, targetType));
+        if (arePackagesRelated(aPackage, rootOfImported)) {
+          descriptions.addAll(local(rootOfImported, targetType));
           continue;
         }
       }
@@ -142,9 +141,7 @@
       if (!targetType.isInstance(next)) continue;
       T type = targetType.cast(next);
       descriptions.addAll(qualifiedNamesDescriptions.qualifiedNames(type));
-      for (QualifiedName name : importedNamesProvider.namesOf(type)) {
-        descriptions.add(create(name, type));
-      }
+      // TODO verify that call to 'importedNamesProvider.namesOf' is not necessary
     }
     return descriptions;
   }