Fixed: [Issue 87] Protobuf editor does not recognize "import public"
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/PropertyHasType.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/PropertyHasType.java
index 1a4464b..a5ce4d3 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/PropertyHasType.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/PropertyHasType.java
@@ -36,10 +36,10 @@
   }
   
   private String typeNameOf(Property property) {
-    AbstractTypeReference r = property.getType();
-    if (r instanceof ScalarTypeReference) return ((ScalarTypeReference) r).getScalar().getName();
-    if (r instanceof TypeReference) {
-      Type type = ((TypeReference) r).getType();
+    AbstractTypeRef r = property.getType();
+    if (r instanceof ScalarTypeRef) return ((ScalarTypeRef) r).getScalar().getName();
+    if (r instanceof TypeRef) {
+      Type type = ((TypeRef) r).getType();
       return type == null ? null : type.getName();
     }
     return r.toString();
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 e5208d4..f256ca4 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
@@ -151,9 +151,9 @@
   }
 
   private void highlightPropertyType(Property property, IHighlightedPositionAcceptor acceptor) {
-    AbstractTypeReference ref = property.getType();
-    if (!(ref instanceof TypeReference)) return;
-    Type type = ((TypeReference) ref).getType();
+    AbstractTypeRef ref = property.getType();
+    if (!(ref instanceof TypeRef)) return;
+    Type type = ((TypeRef) ref).getType();
     if (type instanceof Message) {
       highlightFirstFeature(property, PROPERTY__TYPE, acceptor, MESSAGE_ID);
       return;
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 de2465b..e5f7485 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
@@ -8,26 +8,25 @@
  * 
  * Author: alruiz@google.com (Alex Ruiz)
  */
-
 grammar com.google.eclipse.protobuf.Protobuf with org.eclipse.xtext.common.Terminals
 
 import "http://www.eclipse.org/emf/2002/Ecore" as ecore
 generate protobuf "http://www.google.com/eclipse/protobuf/Protobuf"
 
 Protobuf:
-  (syntax=Syntax)?  
+  (syntax=Syntax)?
   (elements+=ProtobufElement)*;
 
 Syntax:
-  'syntax' '=' name=STRING ';';  
+  'syntax' '=' name=STRING ';';
 
 ProtobufElement:
   Package | Import | Option | Type | ExtendMessage | Service;
-  
+
 Package:
   'package' name=QualifiedName ';';
 
-Import: 
+Import:
   RegularImport | PublicImport;
 
 RegularImport:
@@ -41,11 +40,11 @@
 
 Option:
   BuiltInOption | CustomOption;
-  
-BuiltInOption:  
+
+BuiltInOption:
   'option' name=Name '=' value=ValueRef ';';
 
-CustomOption:  
+CustomOption:
   'option' '(' name=QualifiedName ')' '=' value=ValueRef ';';
 
 Type:
@@ -54,7 +53,7 @@
 Message:
   'message' name=Name '{'
   elements+=MessageElement*
-  '}'(';')?;
+  '}' (';')?;
 
 MessageElement:
   Extensions | Type | Field | ExtendMessage | Option;
@@ -72,26 +71,25 @@
   Property | Group;
 
 Group:
-  modifier=Modifier 'group' name=Name '=' index=(INT | HEX) 
+  modifier=Modifier 'group' name=Name '=' index=(INT | HEX)
   ('[' (fieldOptions+=FieldOption (',' fieldOptions+=FieldOption)*) ']')? '{'
   elements+=GroupElement*
-  '}'(';')?;
+  '}' (';')?;
 
 GroupElement:
-  Field | Option | Enum
-;
+  Field | Option | Enum;
 
 Property:
-  modifier=Modifier type=AbstractTypeReference name=Name '=' index=(INT | HEX) 
+  modifier=Modifier type=AbstractTypeRef name=Name '=' index=(INT | HEX)
   ('[' fieldOptions+=FieldOption (',' fieldOptions+=FieldOption)* ']')? ';';
 
 FieldOption:
   BuiltInFieldOption | CustomFieldOption;
-    
-BuiltInFieldOption:  
+
+BuiltInFieldOption:
   name=Name '=' value=ValueRef;
 
-CustomFieldOption:  
+CustomFieldOption:
   '(' name=QualifiedName ')' '=' value=ValueRef;
 
 enum Modifier:
@@ -99,38 +97,21 @@
   | optional
   | repeated;
 
-AbstractTypeReference:
-  ScalarTypeReference | TypeReference;
+AbstractTypeRef:
+  ScalarTypeRef | TypeRef;
 
-ScalarTypeReference:
+ScalarTypeRef:
   scalar=ScalarType;
 
 enum ScalarType:
-  double
-  | float
-  | int32
-  | int64
-  | uint32
-  | uint64
-  | sint32
-  | sint64
-  | fixed32
-  | fixed64
-  | sfixed32
-  | sfixed64
-  | bool
-  | string
-  | bytes;
+  double | float | int32 | int64 | uint32 | uint64 | sint32 | sint64 | fixed32 | fixed64 | sfixed32 | sfixed64 | bool |
+  string | bytes;
 
-TypeReference:
-  type=[Type | QualifiedName];
+TypeRef:
+  type=[Type|QualifiedName];
 
 ValueRef:
-  LiteralRef
-  | BooleanRef
-  | NumberRef
-  | StringRef
-  | Nan;
+  LiteralRef | BooleanRef | NumberRef | StringRef | Nan;
 
 LiteralRef:
   literal=[Literal];
@@ -151,12 +132,14 @@
 IntRef:
   int=INT;
 
-terminal INT returns ecore::EInt: SIGNED_INT;  
-  
+terminal INT returns ecore::EInt:
+  SIGNED_INT;
+
 LongRef:
   long=LONG;
 
-terminal LONG returns ecore::ELong: SIGNED_INT;  
+terminal LONG returns ecore::ELong:
+  SIGNED_INT;
 
 terminal SIGNED_INT:
   ('-')? (NUMBER)+;
@@ -164,25 +147,26 @@
 FloatRef:
   float=FLOAT;
 
-terminal FLOAT returns ecore::EFloat: DECIMAL;
+terminal FLOAT returns ecore::EFloat:
+  DECIMAL;
 
 DoubleRef:
   double=DOUBLE;
 
-terminal DOUBLE returns ecore::EDouble: DECIMAL;
+terminal DOUBLE returns ecore::EDouble:
+  DECIMAL;
 
 terminal DECIMAL:
-  ('-')? (NUMBER)* ('.' (NUMBER)+)?
-;
+  ('-')? (NUMBER)* ('.' (NUMBER)+)?;
 
 StringRef:
   string=STRING;
 
-terminal STRING: 
+terminal STRING:
   SL_STRING (SL_STRING)*;
 
 terminal SL_STRING:
-      '"' ( '\\' ('b'|'t'|'n'|'f'|'r'|'u'|'"'|"'"|'\\') | !('\\'|'"') )* '"' (WS)*;
+  '"' ('\\' ('b' | 't' | 'n' | 'f' | 'r' | 'u' | '"' | "'" | '\\') | !('\\' | '"'))* '"' (WS)*;
 
 Nan:
   number='nan';
@@ -198,7 +182,8 @@
 Literal:
   name=Name '=' index=(INT | HEX) ';';
 
-terminal HEX returns ecore::EInt: '0x'(NUMBER|'a'..'f'|'A'..'F')+;
+terminal HEX returns ecore::EInt:
+  '0x' (NUMBER | 'a'..'f' | 'A'..'F')+;
 
 terminal NUMBER:
   '0'..'9';
@@ -206,17 +191,16 @@
 ExtendMessage:
   'extend' message=MessageRef '{'
   elements+=MessageElement*
-  '}'(';')?;
+  '}' (';')?;
 
 Service:
- 'service' name=Name '{'
-   rpcs+=Rpc*
- '}'(';')?;
+  'service' name=Name '{'
+  rpcs+=Rpc*
+  '}' (';')?;
 
-Rpc: 
-  'rpc' name=Name  '(' argType=MessageRef ')' 'returns' '(' returnType=MessageRef ')' 
-  (('{' options+=Option* '}')(';')? | ';')
-;
+Rpc:
+  'rpc' name=Name '(' argType=MessageRef ')' 'returns' '(' returnType=MessageRef ')'
+  (('{' options+=Option* '}') (';')? | ';');
 
 Name:
   ID | 'package' | 'import' | 'public' | 'option' | 'extend' | 'message' | 'optional' | 'required' | 'repeated' |
@@ -225,5 +209,5 @@
   'sfixed32' | 'sfixed64' | 'bool' | 'string' | 'bytes';
 
 MessageRef:
-  type=[Message | QualifiedName];
+  type=[Message|QualifiedName];
   
\ No newline at end of file
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 d2f9d05..8ed5113 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
@@ -52,7 +52,7 @@
   @Inject private PackageResolver packageResolver;
 
   @SuppressWarnings("unused")
-  IScope scope_TypeReference_type(TypeReference typeRef, EReference reference) {
+  IScope scope_TypeRef_type(TypeRef typeRef, EReference reference) {
     Protobuf root = finder.rootOf(typeRef);
     Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
     EObject current = typeRef.eContainer().eContainer(); // get message of the property containing the TypeReference
@@ -69,7 +69,7 @@
   }
 
   @SuppressWarnings("unused")
-  IScope scope_MessageReference_type(MessageRef msgRef, EReference reference) {
+  IScope scope_MessageRef_type(MessageRef msgRef, EReference reference) {
     Protobuf root = finder.rootOf(msgRef);
     Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
     descriptions.addAll(messagesIn(root));
@@ -106,21 +106,32 @@
   private <T extends Type> Collection<IEObjectDescription> importedTypes(Protobuf root, Class<T> targetType) {
     List<Import> imports = finder.importsIn(root);
     if (imports.isEmpty()) return emptyList();
-    Package importRootPackage = finder.packageOf(root);
+    return importedTypes(imports, finder.packageOf(root), targetType);
+  }
+
+  private <T extends Type> Collection<IEObjectDescription> importedTypes(List<Import> imports, Package aPackage,
+      Class<T> targetType) {
     List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
     for (Import anImport : imports) {
-      Resource imported = importedResource(anImport);
-      EObject importedRoot = rootElementOf(imported);
-      if (importedRoot != null && arePackagesRelated(importRootPackage, importedRoot)) {
+      Resource importedResource = importedResourceFrom(anImport);
+      Protobuf importedRoot = rootElementOf(importedResource);
+      descriptions.addAll(publicImportedTypes(importedRoot, targetType));
+      if (importedRoot != null && arePackagesRelated(aPackage, importedRoot)) {
         descriptions.addAll(typesIn(importedRoot));
         continue;
       }
-      descriptions.addAll(children(imported, targetType));
+      descriptions.addAll(children(importedResource, targetType));
     }
     return descriptions;
   }
 
-  private Resource importedResource(Import anImport) {
+  private <T extends Type> Collection<IEObjectDescription> publicImportedTypes(Protobuf root, Class<T> targetType) {
+    List<Import> imports = finder.publicImportsIn(root);
+    if (imports.isEmpty()) return emptyList();
+    return importedTypes(imports, finder.packageOf(root), targetType);
+  }
+
+  private Resource importedResourceFrom(Import anImport) {
     ResourceSet resourceSet = finder.rootOf(anImport).eResource().getResourceSet();
     URI importUri = createURI(uriResolver.apply(anImport));
     try {
@@ -130,12 +141,15 @@
     }
   }
 
-  private /* Protobuf */ EObject rootElementOf(Resource resource) {
-    if (resource instanceof XtextResource) return ((XtextResource) resource).getParseResult().getRootASTElement();
+  private Protobuf rootElementOf(Resource resource) {
+    if (resource instanceof XtextResource) {
+      EObject root = ((XtextResource) resource).getParseResult().getRootASTElement();
+      return (Protobuf) root;
+    }
     TreeIterator<Object> contents = getAllContents(resource, true);
     if (contents.hasNext()) {
       Object next = contents.next();
-      if (next instanceof EObject) return (EObject) next;
+      if (next instanceof Protobuf) return (Protobuf) next;
     }
     return null;
   }
@@ -211,6 +225,4 @@
   private static IScope createScope(Iterable<IEObjectDescription> descriptions) {
     return new SimpleScope(descriptions, DO_NOT_IGNORE_CASE);
   }
-
-
 }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java
index 6762680..f556355 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/Properties.java
@@ -40,9 +40,9 @@
    * @return {@code true} if the type of the given property is primitive, {@code false} otherwise.
    */
   public boolean isPrimitive(Property p) {
-    AbstractTypeReference r = p.getType();
-    if (!(r instanceof ScalarTypeReference)) return false;
-    String typeName = ((ScalarTypeReference) r).getScalar().getName();
+    AbstractTypeRef r = p.getType();
+    if (!(r instanceof ScalarTypeRef)) return false;
+    String typeName = ((ScalarTypeRef) r).getScalar().getName();
     return !STRING.hasValue(typeName) && !BYTES.hasValue(typeName);
   }
 
@@ -79,10 +79,10 @@
    * @return the name of the type of the given {@code Property}.
    */
   public String typeNameOf(Property p) {
-    AbstractTypeReference r = p.getType();
-    if (r instanceof ScalarTypeReference) return ((ScalarTypeReference) r).getScalar().getName();
-    if (r instanceof TypeReference) {
-      Type type = ((TypeReference) r).getType();
+    AbstractTypeRef r = p.getType();
+    if (r instanceof ScalarTypeRef) return ((ScalarTypeRef) r).getScalar().getName();
+    if (r instanceof TypeRef) {
+      Type type = ((TypeRef) r).getType();
       return type == null ? null : type.getName();
     }
     return r.toString();
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/ProtobufElementFinder.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/ProtobufElementFinder.java
index 571f197..64ba56d 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/ProtobufElementFinder.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/ProtobufElementFinder.java
@@ -33,9 +33,9 @@
    * @return the enum type of the given property or {@code null} if the type of the given property is not enum.
    */
   public Enum enumTypeOf(Property p) {
-    AbstractTypeReference aTypeRef = (p).getType();
-    if (aTypeRef instanceof TypeReference) {
-      Type type = ((TypeReference) aTypeRef).getType();
+    AbstractTypeRef aTypeRef = (p).getType();
+    if (aTypeRef instanceof TypeRef) {
+      Type type = ((TypeRef) aTypeRef).getType();
       if (type instanceof Enum) return (Enum) type;
     }
     return null;
@@ -47,9 +47,9 @@
    * @return the scalar type of the given property or {@code null} if the type of the given property is not a scalar.
    */
   public ScalarType scalarTypeOf(Property p) {
-    AbstractTypeReference aTypeRef = (p).getType();
-    if (aTypeRef instanceof ScalarTypeReference)
-      return ((ScalarTypeReference) aTypeRef).getScalar();
+    AbstractTypeRef aTypeRef = (p).getType();
+    if (aTypeRef instanceof ScalarTypeRef)
+      return ((ScalarTypeRef) aTypeRef).getScalar();
     return null;
   }
 
@@ -90,4 +90,17 @@
     }
     return unmodifiableList(imports);
   }
+
+  /**
+   * Returns all the public import definitions in the given proto.
+   * @param root the given proto.
+   * @return all the public import definitions in the given proto.
+   */
+  public List<Import> publicImportsIn(Protobuf root) {
+    List<Import> imports = new ArrayList<Import>();
+    for (ProtobufElement e : root.getElements()) {
+      if (e instanceof PublicImport) imports.add((Import) e);
+    }
+    return unmodifiableList(imports);
+  }
 }