In progress: [Issue 161] package scope resolution.
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/IntersectedPackageDescriptions_createFqn_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/IntersectedPackageDescriptions_createFqn_Test.java
new file mode 100644
index 0000000..f026fd0
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/IntersectedPackageDescriptions_createFqn_Test.java
@@ -0,0 +1,41 @@
+/*
+ * 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.scoping;
+
+import static java.util.Arrays.asList;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import org.eclipse.xtext.naming.QualifiedName;
+import org.junit.*;
+
+import java.util.List;
+
+/**
+ * Tests for <code>{@link IntersectedPackageDescriptions#createFqn(String, List)}</code>
+ * 
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class IntersectedPackageDescriptions_createFqn_Test {
+
+  private String name;
+  private List<String> packageFqn;
+  private IntersectedPackageDescriptions descriptions;
+  
+  @Before public void setUp() {
+    name = "Person";
+    packageFqn = asList("com", "google", "test");
+    descriptions = new IntersectedPackageDescriptions();
+  }
+  
+  @Test public void should_concatenate_name_and_package_fqn() {
+    QualifiedName fqn = descriptions.createFqn(name, packageFqn);
+    assertThat(fqn.toString(), equalTo("com.google.test.Person"));
+  }
+}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/PackageIntersection_intersection_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/PackageIntersection_intersection_Test.java
index 1fe9675..915e11f 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/PackageIntersection_intersection_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/PackageIntersection_intersection_Test.java
@@ -61,4 +61,11 @@
     List<String> segments = intersection.intersection(p1, p2);
     assertTrue(segments.isEmpty());
   }
+
+  @Test public void should_return_empty_list_when_packages_are_different_and_first_name_of_first_package_is_shorter() {
+    when(p1.getName()).thenReturn("proto");
+    when(p2.getName()).thenReturn("project.shared");
+    List<String> segments = intersection.intersection(p1, p2);
+    assertTrue(segments.isEmpty());
+  }
 }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/ModelFinder.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/ModelFinder.java
index 81aeed8..b6783e7 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/ModelFinder.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/ModelFinder.java
@@ -20,6 +20,7 @@
 import org.eclipse.emf.common.util.TreeIterator;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.xtext.parser.IParseResult;
 import org.eclipse.xtext.resource.XtextResource;
 
 import java.util.*;
@@ -161,8 +162,11 @@
    */
   public Protobuf rootOf(Resource resource) {
     if (resource instanceof XtextResource) {
-      EObject root = ((XtextResource) resource).getParseResult().getRootASTElement();
-      return (Protobuf) root;
+      IParseResult parseResult = ((XtextResource) resource).getParseResult();
+      if (parseResult != null) {
+        EObject root = parseResult.getRootASTElement();
+        return (Protobuf) root;
+      }
     }
     TreeIterator<Object> contents = getAllContents(resource, true);
     if (contents.hasNext()) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/AstWalker.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/AstWalker.java
index f9031ea..74e7afc 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/AstWalker.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/AstWalker.java
@@ -84,6 +84,7 @@
         continue;
       }
       Resource imported = resources.importedResource(anImport, resourceSet);
+      if (imported == null) continue;
       Protobuf rootOfImported = modelFinder.rootOf(imported);
       if (rootOfImported instanceof NonProto2) continue;
       if (rootOfImported != null) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionScopeFinder.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionScopeFinder.java
index 3df57fa..07dc9c0 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionScopeFinder.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionScopeFinder.java
@@ -31,7 +31,8 @@
   @Inject private ModelFinder modelFinder;
   @Inject private QualifiedNameDescriptions qualifiedNamesDescriptions;
 
-  @Override public Collection<IEObjectDescription> imported(Package fromImporter, Package fromImported, Object target, Object criteria) {
+  @Override public Collection<IEObjectDescription> imported(Package fromImporter, Package fromImported, Object target,
+      Object criteria) {
     OptionType optionType = optionTypeFrom(criteria);
     if (!isExtendingOptionMessage(target, optionType)) return emptySet();
     Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/IntersectedPackageDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/IntersectedPackageDescriptions.java
new file mode 100644
index 0000000..64089ed
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/IntersectedPackageDescriptions.java
@@ -0,0 +1,43 @@
+/*
+ * 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.scoping;
+
+import static org.eclipse.xtext.resource.EObjectDescription.create;
+import static org.eclipse.xtext.util.SimpleAttributeResolver.newResolver;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.*;
+
+import java.util.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class IntersectedPackageDescriptions {
+
+  private final Function<EObject, String> resolver = newResolver(String.class, "name");
+
+  IEObjectDescription description(EObject e, List<String> packageFqn) {
+    if (packageFqn.isEmpty()) return null;
+    String name = resolver.apply(e);
+    QualifiedName fqn = createFqn(name, packageFqn);
+    return create(fqn, e);
+  }
+  
+  @VisibleForTesting 
+  QualifiedName createFqn(String name, List<String> packageFqn) {
+    List<String> nameSegments = new ArrayList<String>(packageFqn);
+    nameSegments.add(name);
+    return QualifiedName.create(nameSegments.toArray(new String[nameSegments.size()]));
+  }
+}
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 1a7bf63..44f0eca 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
@@ -26,19 +26,19 @@
 
   @Inject private ProtoDescriptorProvider descriptorProvider;
   
-  Collection <IEObjectDescription> properties(NativeOption option) {
-    return allProperties(option);
+  Collection <IEObjectDescription> sources(NativeOption option) {
+    return allSources(option);
   }
 
-  Collection <IEObjectDescription> properties(NativeFieldOption option) {
-    return allProperties(option);
+  Collection <IEObjectDescription> sources(NativeFieldOption option) {
+    return allSources(option);
   }
 
-  private Collection <IEObjectDescription> allProperties(EObject option) {
+  private Collection <IEObjectDescription> allSources(EObject option) {
     ProtoDescriptor descriptor = descriptorProvider.primaryDescriptor();
-    Collection<MessageField> fields = descriptor.availableOptionsFor(option.eContainer());
-    if (fields.isEmpty()) return emptyList();
-    return describe(fields);
+    Collection<MessageField> optionSources = descriptor.availableOptionsFor(option.eContainer());
+    if (optionSources.isEmpty()) return emptyList();
+    return describe(optionSources);
   }
 
   private Collection<IEObjectDescription> describe(Collection<MessageField> fields) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/PackageIntersection.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/PackageIntersection.java
index a98b316..ae498e7 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/PackageIntersection.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/PackageIntersection.java
@@ -25,7 +25,7 @@
   @Inject private final IQualifiedNameConverter converter = new IQualifiedNameConverter.DefaultImpl();
 
   List<String> intersection(Package p1, Package p2) {
-    if (p2 == null) return null;
+    if (p1 == null || p2 == null) return emptyList();
     return intersection(converter.toQualifiedName(p1.getName()), converter.toQualifiedName(p2.getName()));
   }
 
@@ -37,12 +37,16 @@
     List<String> intersection = new ArrayList<String>();
     int n1Count = n1.size();
     int n2Count = n2.size();
-    boolean differenceFound = false;
+    int start = -1;
     for (int i = 0; (i < n1Count && i < n2Count); i++) {
-      String n2Segment = n2.get(i);
-      if (differenceFound || !n1.get(i).equals(n2Segment)) {
-        differenceFound = true;
-        intersection.add(n2Segment);
+      if (!n1.get(i).equals(n2.get(i))) {
+        start = i;
+        break;
+      }
+    }
+    if (start >= 0) {
+      for (int i = start; i < n2Count; i++) {
+        intersection.add(n2.get(i));
       }
     }
     if (intersection.equals(n2)) return emptyList();
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 010a499..05da44b 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
@@ -48,9 +48,13 @@
 
   @SuppressWarnings("unused")
   public IScope scope_ComplexTypeLink_target(ComplexTypeLink link, EReference r) {
-    EObject c = link.eContainer();
-    if (c instanceof MessageField) {
-      return createScope(findScope((MessageField) c));
+    try {
+      EObject c = link.eContainer();
+      if (c instanceof MessageField) {
+        return createScope(findScope((MessageField) c));
+      }
+    } catch (Throwable t) {
+      t.printStackTrace();
     }
     Set<IEObjectDescription> descriptions = emptySet();
     return createScope(descriptions);
@@ -106,11 +110,11 @@
     EObject c = source.eContainer();
     if (c instanceof NativeOption) {
       NativeOption option = (NativeOption) c;
-      return createScope(nativeOptionDescriptions.properties(option));
+      return createScope(nativeOptionDescriptions.sources(option));
     }
     if (c instanceof NativeFieldOption) {
       NativeFieldOption option = (NativeFieldOption) c;
-      return createScope(nativeOptionDescriptions.properties(option));
+      return createScope(nativeOptionDescriptions.sources(option));
     }
     if (c instanceof CustomOption) {
       CustomOption option = (CustomOption) c;
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeScopeFinder.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeScopeFinder.java
index 6a483af..e37d3b8 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeScopeFinder.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeScopeFinder.java
@@ -27,15 +27,22 @@
  */
 class TypeScopeFinder implements ScopeFinder {
 
-  @Inject private PackageIntersection packageIntersection;
+  @Inject private IntersectedPackageDescriptions intersectedPackageDescriptions;
   @Inject private ProtoDescriptorProvider descriptorProvider;
   @Inject private LocalNamesProvider localNamesProvider;
+  @Inject private PackageIntersection packageIntersection;
   @Inject private QualifiedNameDescriptions qualifiedNamesDescriptions;
   
-  @Override public Collection<IEObjectDescription> imported(Package fromImporter, Package fromImported, Object target, Object criteria) {
+  @Override public Collection<IEObjectDescription> imported(Package fromImporter, Package fromImported, Object target,
+      Object criteria) {
     if (!isInstance(target, criteria)) return emptySet();
+    Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
     EObject e = (EObject) target;
-    return qualifiedNamesDescriptions.qualifiedNames(e);
+    descriptions.addAll(qualifiedNamesDescriptions.qualifiedNames(e));
+    List<String> intersection = packageIntersection.intersection(fromImporter, fromImported);
+    IEObjectDescription d = intersectedPackageDescriptions.description(e, intersection);
+//    if (d != null) descriptions.add(d);
+    return descriptions;
   }
 
   @Override public Collection<IEObjectDescription> inDescriptor(Import anImport, Object criteria) {