Fixed: [  Issue 58  ] protobuf-dt expects imports and options to be grouped together
https://code.google.com/p/protobuf-dt/issues/detail?id=58
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/util/Finder.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/util/Finder.java
index 31583dc..b530ec6 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/util/Finder.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/util/Finder.java
@@ -33,7 +33,7 @@
   }
 
   public static Option findOption(String name, Protobuf root) {
-    for (Option option : root.getOptions())
+    for (Option option : getAllContentsOfType(root, Option.class))
       if (name.equals(option.getName())) return option;
     return null;
   }
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/util/ProtobufElementFinder_importsIn_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/util/ProtobufElementFinder_importsIn_Test.java
new file mode 100644
index 0000000..bc73f66
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/util/ProtobufElementFinder_importsIn_Test.java
@@ -0,0 +1,58 @@
+/*
+ * 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.util;
+
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.junit.*;
+
+import com.google.eclipse.protobuf.junit.core.XtextRule;
+import com.google.eclipse.protobuf.protobuf.*;
+
+/**
+ * Tests for <code>{@link ProtobufElementFinder#importsIn(Protobuf)}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProtobufElementFinder_importsIn_Test {
+
+  @Rule public XtextRule xtext = new XtextRule();
+
+  private ProtobufElementFinder finder;
+
+  @Before public void setUp() {
+    finder = xtext.getInstanceOf(ProtobufElementFinder.class);
+  }
+
+  @Test public void should_return_all_imports() {
+    StringBuilder proto = new StringBuilder();
+    proto.append("import \"luke.proto\"")
+         .append("import \"leia.proto\"");
+    Protobuf root = xtext.parse(proto);
+    List<Import> allImports = finder.importsIn(root);
+    assertThat(allImports.size(), equalTo(2));
+    assertThat(allImports.get(0).getImportURI(), equalTo("luke.proto"));
+    assertThat(allImports.get(1).getImportURI(), equalTo("leia.proto"));
+  }
+
+  @Test public void should_return_empty_if_no_imports_found() {
+    StringBuilder proto = new StringBuilder();
+    proto.append("enum PhoneType {")
+         .append("  MOBILE = 0;   ")
+         .append("  HOME = 1;     ")
+         .append("  WORK = 2;     ")
+         .append("}               ");
+    Protobuf root = xtext.parse(proto);
+    List<Import> allImports = finder.importsIn(root);
+    assertThat(allImports.size(), equalTo(0));
+  }
+}
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 5a730de..043be93 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
@@ -39,25 +39,15 @@
   }
 
   private void highlightAllNames(Protobuf protobuf, IHighlightedPositionAcceptor acceptor, String highlightId) {
-    highlightPackageName(protobuf, acceptor, highlightId);
-    highlightFileOptionNames(protobuf, acceptor, highlightId);
     highlightElementNames(protobuf, acceptor, highlightId);
   }
 
-  private void highlightPackageName(Protobuf protobuf, IHighlightedPositionAcceptor acceptor, String highlightId) {
-    Package aPackage = protobuf.getPackage();
-    if (aPackage == null) return;
-    highlightName(aPackage, acceptor, highlightId);
-  }
-
-  private void highlightFileOptionNames(Protobuf protobuf, IHighlightedPositionAcceptor acceptor, String highlightId) {
-    for (Option option : protobuf.getOptions()) {
-      highlightName(option, acceptor, highlightId);
-    }
-  }
-
   private void highlightElementNames(Protobuf protobuf, IHighlightedPositionAcceptor acceptor, String highlightId) {
     for (ProtobufElement element : protobuf.getElements()) {
+      if (element instanceof Package || element instanceof Option) {
+        highlightName(element, acceptor, highlightId);
+        continue;
+      }
       if (element instanceof Type) {
         highlightName(element, acceptor, highlightId);
         if (element instanceof Message) highlightElementNames((Message) element, acceptor, highlightId);
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/outline/ProtobufOutlineTreeProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/outline/ProtobufOutlineTreeProvider.java
index a7c6603..7294426 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/outline/ProtobufOutlineTreeProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/outline/ProtobufOutlineTreeProvider.java
@@ -8,19 +8,13 @@
  */
 package com.google.eclipse.protobuf.ui.outline;
 
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.*;
-import static com.google.eclipse.protobuf.ui.outline.Messages.*;
-
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.xtext.ui.editor.outline.IOutlineNode;
-import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider;
-import org.eclipse.xtext.ui.editor.outline.impl.DocumentRootNode;
+import org.eclipse.xtext.ui.editor.outline.impl.*;
 
 import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.protobuf.Package;
 
 /**
  * Customization of the default outline structure.
@@ -30,13 +24,13 @@
 public class ProtobufOutlineTreeProvider extends DefaultOutlineTreeProvider {
 
   private static final List<Class<? extends EObject>> IGNORED_ELEMENT_TYPES = new ArrayList<Class<? extends EObject>>();
-  
+
   static {
     IGNORED_ELEMENT_TYPES.add(BooleanRef.class);
     IGNORED_ELEMENT_TYPES.add(FieldOption.class);
     IGNORED_ELEMENT_TYPES.add(MessageReference.class);
   }
-  
+
   boolean _isLeaf(Option o) {
     return true;
   }
@@ -46,18 +40,18 @@
   }
 
   protected void _createChildren(DocumentRootNode parentNode, Protobuf protobuf) {
-    Package aPackage = protobuf.getPackage();
-    if (aPackage != null) {
-      createNode(parentNode, aPackage);
-    }
-    if (!protobuf.getImports().isEmpty()) {
-      createEStructuralFeatureNode(parentNode, protobuf, PROTOBUF__IMPORTS,
-          labelProvider.getImage("imports"), importDeclarations, false);
-    }
-    if (!protobuf.getOptions().isEmpty()) {
-      createEStructuralFeatureNode(parentNode, protobuf, PROTOBUF__OPTIONS,
-          labelProvider.getImage("options"), optionDeclarations, false);
-    }
+//    Package aPackage = protobuf.getPackage();
+//    if (aPackage != null) {
+//      createNode(parentNode, aPackage);
+//    }
+//    if (!protobuf.getImports().isEmpty()) {
+//      createEStructuralFeatureNode(parentNode, protobuf, PROTOBUF__IMPORTS,
+//          labelProvider.getImage("imports"), importDeclarations, false);
+//    }
+//    if (!protobuf.getOptions().isEmpty()) {
+//      createEStructuralFeatureNode(parentNode, protobuf, PROTOBUF__OPTIONS,
+//          labelProvider.getImage("options"), optionDeclarations, false);
+//    }
     for (ProtobufElement e : protobuf.getElements()) {
       createNode(parentNode, e);
     }
@@ -67,7 +61,7 @@
     if (isIgnored(modelElement)) return;
     super.createNode(parent, modelElement);
   }
-  
+
   private boolean isIgnored(EObject modelElement) {
     for (Class<? extends EObject> ignoredType : IGNORED_ELEMENT_TYPES)
       if (ignoredType.isInstance(modelElement)) return true;
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 303bc4a..d27a97b 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
@@ -16,11 +16,13 @@
 
 Protobuf:
   (syntax=Syntax)?	
-  ((package=Package)? & (imports+=Import)* & (options+=Option)*)
   (elements+=ProtobufElement)*;
 
 Syntax:
   'syntax' '=' name=STRING ';';  
+
+ProtobufElement:
+  Package | Import | Option | Type | ExtendMessage | Service;
   
 Package:
   'package' name=QualifiedName ';';
@@ -34,9 +36,6 @@
 Option:
   'option' name=Name '=' value=ValueRef ';';
 
-ProtobufElement:
-  Type | ExtendMessage | Service;
-
 Type:
   Message | Enum;
 
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 f4a09d7..0798fb2 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
@@ -14,14 +14,10 @@
 
 import java.util.*;
 
-import org.eclipse.emf.common.util.TreeIterator;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.resource.Resource;
-import org.eclipse.emf.ecore.resource.ResourceSet;
-import org.eclipse.xtext.naming.IQualifiedNameProvider;
-import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.emf.common.util.*;
+import org.eclipse.emf.ecore.*;
+import org.eclipse.emf.ecore.resource.*;
+import org.eclipse.xtext.naming.*;
 import org.eclipse.xtext.resource.IEObjectDescription;
 import org.eclipse.xtext.scoping.IScope;
 import org.eclipse.xtext.scoping.impl.*;
@@ -99,7 +95,7 @@
   private <T extends Type> Collection<IEObjectDescription> importedTypes(Protobuf root, Class<T> targetType) {
     ResourceSet resourceSet = root.eResource().getResourceSet();
     List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
-    for (Import anImport : root.getImports()) {
+    for (Import anImport : finder.importsIn(root)) {
       URI importUri = createURI(uriResolver.apply(anImport));
       Resource imported = resourceSet.getResource(importUri, true);
       descriptions.addAll(innerTypes(imported, targetType));
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 952cdf0..571f197 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
@@ -8,6 +8,10 @@
  */
 package com.google.eclipse.protobuf.util;
 
+import static java.util.Collections.unmodifiableList;
+
+import java.util.*;
+
 import org.eclipse.emf.ecore.EObject;
 
 import com.google.eclipse.protobuf.protobuf.*;
@@ -56,17 +60,34 @@
    * package.
    */
   public Package packageOf(EObject o) {
-    return rootOf(o).getPackage();
+    Protobuf root = rootOf(o);
+    for (ProtobufElement e : root.getElements()) {
+      if (e instanceof Package) return (Package) e;
+    }
+    return null;
   }
 
   /**
-   * Returns the root element of the proto file containing the given object.
-   * @param o the given object.
-   * @return the root element of the proto file containing the given object.
+   * Returns the root element of the proto file containing the given element.
+   * @param o the given element.
+   * @return the root element of the proto file containing the given element.
    */
   public Protobuf rootOf(EObject o) {
     EObject current = o;
     while (!(current instanceof Protobuf)) current = current.eContainer();
     return (Protobuf) current;
   }
+
+  /**
+   * Returns all the import definitions in the given proto.
+   * @param root the given proto.
+   * @return all the import definitions in the given proto.
+   */
+  public List<Import> importsIn(Protobuf root) {
+    List<Import> imports = new ArrayList<Import>();
+    for (ProtobufElement e : root.getElements()) {
+      if (e instanceof Import) imports.add((Import) e);
+    }
+    return unmodifiableList(imports);
+  }
 }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.java
index 93dee55..cbd6fa0 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.java
@@ -22,6 +22,7 @@
   public static String fieldNumbersMustBePositive;
   public static String importNotFound;
   public static String missingFieldNumber;
+  public static String multiplePackages;
   public static String unrecognizedSyntaxIdentifier;
 
   static {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties
index 4cf6b11..dbb5a26 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties
@@ -5,4 +5,5 @@
 fieldNumbersMustBePositive = Field numbers must be positive integers.
 importNotFound = Import \"%s\" was not found.
 missingFieldNumber = Missing field number.
+multiplePackages = Multiple package definitions.
 unrecognizedSyntaxIdentifier = Unrecognized syntax identifier \"%s\".  This parser only recognizes \"proto2\".
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
index baca753..22a6323 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator.java
@@ -15,11 +15,11 @@
 
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.naming.IQualifiedNameProvider;
-import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.naming.*;
 import org.eclipse.xtext.validation.Check;
 
 import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.protobuf.Package;
 import com.google.inject.Inject;
 
 /**
@@ -73,6 +73,18 @@
     error(msg, FIELD__INDEX);
   }
 
+  @Check public void checkOnlyOnePackageDefinition(Package aPackage) {
+    boolean firstFound = false;
+    Protobuf root = (Protobuf) aPackage.eContainer();
+    for (ProtobufElement e : root.getElements()) {
+      if (e == aPackage) {
+        if (firstFound) error(multiplePackages, PACKAGE__NAME);
+        return;
+      }
+      if (e instanceof Package && !firstFound) firstFound = true;
+    }
+  }
+
   private boolean isNameNull(Field field) {
     return field.getName() == null;
   }