Packages can now have keywords as segment identifiers.
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/Finder.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/Finder.java
index 65ffa42..17d8723 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/Finder.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/Finder.java
@@ -83,7 +83,6 @@
   }
   
   private String nameOf(Object o) {
-    if (o instanceof Package) return nameOf((Package) o);
     if (!(o instanceof EObject)) return null;
     EObject e = (EObject) o;
     for (String name : FEATURE_NAMES) {
@@ -94,18 +93,6 @@
     return null;
   }
 
-  private String nameOf(Package p) {
-    List<Name> segments = p.getSegments();
-    int segmentCount = segments.size();
-    if (segmentCount == 0) return null;
-    StringBuilder b = new StringBuilder();
-    for (int i = 0; i < segmentCount; i++) {
-      b.append(segments.get(i).getValue());
-      if (i < segmentCount - 1) b.append(".");
-    }
-    return b.toString();
-  }
-
   private Object feature(EObject e, String featureName) {
     EStructuralFeature f = e.eClass().getEStructuralFeature(featureName);
     return (f != null) ? e.eGet(f) : null;
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/ModelFinder_packageOf_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/ModelFinder_packageOf_Test.java
index 47df3b7..c4bf6b0 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/ModelFinder_packageOf_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/ModelFinder_packageOf_Test.java
@@ -16,8 +16,6 @@
 import org.eclipse.emf.ecore.EObject;
 import org.junit.*;
 
-import java.util.List;
-
 import com.google.eclipse.protobuf.junit.core.XtextRule;
 import com.google.eclipse.protobuf.protobuf.*;
 import com.google.eclipse.protobuf.protobuf.Package;
@@ -47,9 +45,7 @@
   @Test public void should_return_package_if_proto_has_one() {
     MessageField field = xtext.find("id", MessageField.class);
     Package aPackage = finder.packageOf(field);
-    List<Name> segments = aPackage.getSegments();
-    assertThat(segments.get(0).getValue(), equalTo("person"));
-    assertThat(segments.get(1).getValue(), equalTo("test"));
+    assertThat(aPackage.getName(), equalTo("person.test"));
   }
 
   // syntax = "proto2";
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Packages_areRelated_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Packages_areRelated_Test.java
index aeef108..bfb904d 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Packages_areRelated_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/model/util/Packages_areRelated_Test.java
@@ -8,16 +8,11 @@
  */
 package com.google.eclipse.protobuf.model.util;
 
-import static java.util.Arrays.asList;
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 
-import org.eclipse.emf.common.util.*;
 import org.junit.*;
 
-import java.util.*;
-
-import com.google.eclipse.protobuf.protobuf.*;
 import com.google.eclipse.protobuf.protobuf.Package;
 
 /**
@@ -25,60 +20,59 @@
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
-// TODO reimplement
 public class Packages_areRelated_Test {
 
-//  private static Packages packages;
-//
-//  @BeforeClass public static void setUpOnce() {
-//    packages = new Packages();
-//  }
-//
-//  private EList<String> baseName;
-//  private List<BasicEList<String>> subpackageNames;
-//  private Package p1;
-//  private Package p2;
-//  
-//  @Before public void setUp() {
-//    baseName = new BasicEList<String>(asList("may", "the", "force", "be", "with", "you"));
-//    subpackageNames = asList(
-//        new BasicEList<String>(asList("may", "the", "force", "be", "with")),
-//        new BasicEList<String>(asList("may", "the", "force", "be")),
-//        new BasicEList<String>(asList("may", "the", "force")),
-//        new BasicEList<String>(asList("may", "the")),
-//        new BasicEList<String>(asList("may"))
-//    );
-//    p1 = mock(Package.class);
-//    when(p1.getSegments()).thenReturn(baseName);
-//    p2 = mock(Package.class);
-//  }
-//
-//  @Test public void should_return_true_if_packages_are_equal() {
-//    when(p2.getName()).thenReturn(baseName);
-//    assertTrue(packages.areRelated(p1, p2));
-//  }
-//
-//  @Test public void should_return_true_second_is_subPackage_of_first() {
-//    for (String name : subpackageNames) {
-//      when(p2.getName()).thenReturn(name);
-//      assertTrue(packages.areRelated(p1, p2));
-//    }
-//  }
-//
-//  @Test public void should_return_true_first_is_subPackage_of_second() {
-//    for (String name : subpackageNames) {
-//      when(p2.getName()).thenReturn(name);
-//      assertTrue(packages.areRelated(p2, p1));
-//    }
-//  }
-//
-//  @Test public void should_return_false_if_second_starts_with_few_segments_of_first_but_is_not_subpackage() {
-//    when(p2.getName()).thenReturn("may.the.ring");
-//    assertFalse(packages.areRelated(p1, p2));
-//  }
-//
-//  @Test public void should_return_false_if_names_are_completely_different() {
-//    when(p2.getName()).thenReturn("peace.dog");
-//    assertFalse(packages.areRelated(p1, p2));
-//  }
+  private static Packages packages;
+
+  @BeforeClass public static void setUpOnce() {
+    packages = new Packages();
+  }
+
+  private String baseName;
+  private String[] subpackageNames;
+  private Package p1;
+  private Package p2;
+
+  @Before public void setUp() {
+    baseName = "may.the.force.be.with.you";
+    subpackageNames = new String[] {
+        "may.the.force.be.with",
+        "may.the.force.be.",
+        "may.the.force.",
+        "may.the",
+        "may"
+    };
+    p1 = mock(Package.class);
+    when(p1.getName()).thenReturn(baseName);
+    p2 = mock(Package.class);
+  }
+
+  @Test public void should_return_true_if_packages_are_equal() {
+    when(p2.getName()).thenReturn(baseName);
+    assertTrue(packages.areRelated(p1, p2));
+  }
+
+  @Test public void should_return_true_second_is_subPackage_of_first() {
+    for (String name : subpackageNames) {
+      when(p2.getName()).thenReturn(name);
+      assertTrue(packages.areRelated(p1, p2));
+    }
+  }
+
+  @Test public void should_return_true_first_is_subPackage_of_second() {
+    for (String name : subpackageNames) {
+      when(p2.getName()).thenReturn(name);
+      assertTrue(packages.areRelated(p2, p1));
+    }
+  }
+
+  @Test public void should_return_false_if_second_starts_with_few_segments_of_first_but_is_not_subpackage() {
+    when(p2.getName()).thenReturn("may.the.ring");
+    assertFalse(packages.areRelated(p1, p2));
+  }
+
+  @Test public void should_return_false_if_names_are_completely_different() {
+    when(p2.getName()).thenReturn("peace.dog");
+    assertFalse(packages.areRelated(p1, p2));
+  }
 }
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/naming/NameResolver_nameOf_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/naming/NameResolver_nameOf_Test.java
index 7aaef29..2466c2e 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/naming/NameResolver_nameOf_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/naming/NameResolver_nameOf_Test.java
@@ -13,12 +13,13 @@
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.assertThat;
 
-import com.google.eclipse.protobuf.junit.core.XtextRule;
-import com.google.eclipse.protobuf.protobuf.Message;
-
 import org.eclipse.emf.ecore.EObject;
 import org.junit.*;
 
+import com.google.eclipse.protobuf.junit.core.XtextRule;
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.protobuf.Package;
+
 /**
  * Tests for <code>{@link NameResolver#nameOf(EObject)}</code>.
  * 
@@ -42,4 +43,13 @@
     String name = resolver.nameOf(message);
     assertThat(name, equalTo("Person"));
   }
+  
+  // syntax = "proto2";
+  //
+  // package com.google.proto.test;
+  @Test public void should_return_name_of_Package() {
+    Package aPackage = xtext.find("com.google.proto.test", Package.class);
+    String name = resolver.nameOf(aPackage);
+    assertThat(name, equalTo("com.google.proto.test"));    
+  }
 }
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator_checkOnlyOnePackageDefinition_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator_checkOnlyOnePackageDefinition_Test.java
index f309077..bf2e636 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator_checkOnlyOnePackageDefinition_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator_checkOnlyOnePackageDefinition_Test.java
@@ -10,7 +10,7 @@
 
 import static com.google.eclipse.protobuf.junit.core.Setups.unitTestSetup;
 import static com.google.eclipse.protobuf.junit.core.XtextRule.createWith;
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.PACKAGE__SEGMENTS;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.PACKAGE__NAME;
 import static com.google.eclipse.protobuf.validation.ProtobufJavaValidator.MORE_THAN_ONE_PACKAGE_ERROR;
 import static org.eclipse.xtext.validation.ValidationMessageAcceptor.INSIGNIFICANT_INDEX;
 import static org.mockito.Mockito.*;
@@ -47,7 +47,7 @@
     Package p = xtext.find("com.google.eclipse", Package.class);
     validator.checkOnlyOnePackageDefinition(p);
     String message = "Multiple package definitions.";
-    verify(messageAcceptor).acceptError(message, p, PACKAGE__SEGMENTS, INSIGNIFICANT_INDEX, MORE_THAN_ONE_PACKAGE_ERROR);
+    verify(messageAcceptor).acceptError(message, p, PACKAGE__NAME, INSIGNIFICANT_INDEX, MORE_THAN_ONE_PACKAGE_ERROR);
   }
 
   // syntax = "proto2";
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 f3d960a..c7d940b 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
@@ -44,7 +44,7 @@
   private void highlight(Protobuf protobuf, IHighlightedPositionAcceptor acceptor) {
     for (ProtobufElement element : protobuf.getElements()) {
       if (element instanceof Package) {
-        // highlightName(element, acceptor, DEFAULT_ID);
+        highlightName(element, acceptor, DEFAULT_ID);
         continue;
       }
       if (element instanceof Option) {
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 a7f79d8..0f2aa81 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
@@ -17,6 +17,7 @@
 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.
@@ -46,6 +47,10 @@
     return true;
   }
 
+  boolean _isLeaf(Package aPackage) {
+    return true;
+  }
+  
   protected void _createChildren(DocumentRootNode parent, Protobuf protobuf) {
     OutlineViewModel model = new OutlineViewModel(protobuf);
     for (EObject aPackage : model.packages()) createNode(parent, aPackage);
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 56ef9bb..7a0f0fe 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
@@ -24,7 +24,10 @@
   Package | Import | Option | ComplexType | MessageExtension | Service;
 
 Package:
-  'package' segments+=Name ('.' segments+=Name)* ';';
+  'package' name=PackageName ';';
+
+PackageName:
+  IdOrReservedWord ('.' IdOrReservedWord)*;
 
 Import:
   NormalImport | PublicImport;
@@ -65,7 +68,7 @@
   '}' (';')?;
 
 GroupElement:
-  Option | MessageField | Group | Enum | MessageExtension;
+  Option | IndexedElement | Enum | MessageExtension;
 
 MessageField:
   modifier=Modifier type=TypeLink name=Name '=' index=(LONG | HEX)
@@ -122,7 +125,10 @@
   (('{' options+=Option* '}') (';')? | ';');
 
 Name:
-  value=ID|ReservedWord;
+  value=IdOrReservedWord;
+
+IdOrReservedWord: 
+  ID | ReservedWord;
   
 ReservedWord:  
   'package' | 'import' | 'public' | 'option' | 'extend' | 'message' | 'optional' | 'required' | 'repeated' |
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Packages.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Packages.java
index 77bed86..4e2f435 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Packages.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Packages.java
@@ -9,25 +9,23 @@
 package com.google.eclipse.protobuf.model.util;
 
 import static java.util.Collections.*;
-
-import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.protobuf.Package;
-import com.google.inject.*;
-
-import org.eclipse.xtext.naming.QualifiedName;
+import static org.eclipse.xtext.util.Strings.isEmpty;
 
 import java.util.*;
 
+import org.eclipse.xtext.naming.*;
+
+import com.google.eclipse.protobuf.protobuf.Package;
+import com.google.inject.Inject;
+
 /**
  * Utility methods related to <code>{@link Package}</code>s.
  * 
  * @author alruiz@google.com (Alex Ruiz)
  */
-@Singleton
 public class Packages {
 
-  @Inject private Names names;
-  @Inject private QualifiedNames qualifiedNames;
+  @Inject private final IQualifiedNameConverter converter = new IQualifiedNameConverter.DefaultImpl();
 
   /**
    * Indicates whether the given packages are "related." "Related" means that the names of the packages are equal or one 
@@ -45,11 +43,6 @@
     return (isSubPackage(name1, name2));
   }
 
-  private QualifiedName nameOf(Package p) {
-    List<String> segments = segmentsOf(p);
-    if (segments.isEmpty()) return null;
-    return qualifiedNames.createFqn(segments);
-  }
 
   private boolean isSubPackage(QualifiedName name1, QualifiedName name2) {
     List<String> segments = name2.getSegments();
@@ -76,12 +69,14 @@
   }
 
   public List<String> segmentsOf(Package p) {
-    if (p == null) return emptyList();
-    List<String> segments = new ArrayList<String>();
-    for (Name segment : p.getSegments()) {
-      String value = names.valueOf(segment);
-      if (value != null) segments.add(value);
-    }
-    return unmodifiableList(segments);
+    QualifiedName name = (p == null) ? null : nameOf(p);
+    if (name == null) return emptyList();
+    return name.getSegments();
+  }
+
+  private QualifiedName nameOf(Package p) {
+    String name = p.getName();
+    if (isEmpty(name)) return null;
+    return converter.toQualifiedName(name);
   }
 }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NameResolver.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NameResolver.java
index 9a1b666..478cbd1 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NameResolver.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/NameResolver.java
@@ -8,13 +8,10 @@
  */
 package com.google.eclipse.protobuf.naming;
 
-import com.google.eclipse.protobuf.protobuf.Name;
-import com.google.eclipse.protobuf.protobuf.Package;
-import com.google.inject.Singleton;
-
 import org.eclipse.emf.ecore.*;
 
-import java.util.List;
+import com.google.eclipse.protobuf.protobuf.Name;
+import com.google.inject.Singleton;
 
 /**
  * @author alruiz@google.com (Alex Ruiz)
@@ -23,24 +20,11 @@
 public class NameResolver {
 
   public String nameOf(EObject o) {
-    if (o instanceof Package) return nameOf((Package) o);
     Object value = nameFeatureOf(o);
+    if (value instanceof String) return (String) value;
     if (value instanceof Name) return ((Name) value).getValue();
     return null;
   }
-
-  private String nameOf(Package p) {
-    List<Name> segments = p.getSegments();
-    int segmentCount = segments.size();
-    if (segmentCount == 0) return null;
-    StringBuilder b = new StringBuilder();
-    for (int i = 0; i < segmentCount; i++) {
-      b.append(segments.get(i).getValue());
-      if (i < segmentCount - 1) b.append(".");
-    }
-    return b.toString();
-  }
-  
   
   private Object nameFeatureOf(EObject e) {
     EStructuralFeature f = e.eClass().getEStructuralFeature("name");
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 74e7afc..0c680c4 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
@@ -120,8 +120,6 @@
     while (contents.hasNext()) {
       Object next = contents.next();
       descriptions.addAll(scopeFinder.imported(fromImporter, fromImported, next, criteria));
-      // TODO verify that call to 'importedNamesProvider.namesOf' is not necessary
-      
     }
     return descriptions;
   }
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 0d5005c..2b24b50 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
@@ -13,18 +13,18 @@
 import static java.lang.String.format;
 import static org.eclipse.xtext.util.Strings.isEmpty;
 
-import com.google.eclipse.protobuf.model.util.*;
-import com.google.eclipse.protobuf.parser.NonProto2;
-import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.protobuf.Package;
-import com.google.inject.Inject;
-
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.xtext.naming.*;
 import org.eclipse.xtext.scoping.impl.ImportUriResolver;
 import org.eclipse.xtext.validation.*;
 
+import com.google.eclipse.protobuf.model.util.*;
+import com.google.eclipse.protobuf.parser.NonProto2;
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.protobuf.Package;
+import com.google.inject.Inject;
+
 /**
  * @author alruiz@google.com (Alex Ruiz)
  */
@@ -124,7 +124,7 @@
     Protobuf root = (Protobuf) aPackage.eContainer();
     for (ProtobufElement e : root.getElements()) {
       if (e == aPackage) {
-        if (firstFound) error(multiplePackages, aPackage, PACKAGE__SEGMENTS, MORE_THAN_ONE_PACKAGE_ERROR);
+        if (firstFound) error(multiplePackages, aPackage, PACKAGE__NAME, MORE_THAN_ONE_PACKAGE_ERROR);
         return;
       }
       if (e instanceof Package && !firstFound) firstFound = true;