Fixed: [ Issue 36 ] Resolution of "Import URIs" does not work if such URI and the resource URI have overlapping folders
https://code.google.com/p/protobuf-dt/issues/detail?id=36

Fixed: [ Issue 37 ] Groups can end with a semicolon
https://code.google.com/p/protobuf-dt/issues/detail?id=37

Fixed: [ Issue 38 ] "extend message" should be allowed inside a message definition
https://code.google.com/p/protobuf-dt/issues/detail?id=38

Fixed: [ Issue 39 ] Message fields can have a default value and deprecation inside a single pair of brackets
https://code.google.com/p/protobuf-dt/issues/detail?id=39
diff --git a/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF
index d9ceabf..646fe3f 100644
--- a/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF
@@ -9,5 +9,6 @@
  org.junit.source;bundle-version="4.8.1",
  org.eclipse.xtext.junit;bundle-version="2.0.0",
  org.eclipse.xtext.junit4;bundle-version="2.0.0",
- com.google.eclipse.protobuf.junit;bundle-version="1.0.0"
+ com.google.eclipse.protobuf.junit;bundle-version="1.0.0",
+ org.mockito;bundle-version="1.8.5"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver_apply_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver_apply_Test.java
deleted file mode 100644
index f5e9a1a..0000000
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver_apply_Test.java
+++ /dev/null
@@ -1,54 +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.scoping;
-
-import static org.hamcrest.core.IsEqual.equalTo;
-import static org.junit.Assert.assertThat;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.scoping.impl.ImportUriResolver;
-import org.junit.*;
-
-import com.google.eclipse.protobuf.junit.core.XtextRule;
-import com.google.eclipse.protobuf.protobuf.*;
-
-/**
- * Tests for <code>{@link ImportUriFixerAndResolver#apply(EObject)}</code>.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class ImportUriFixerAndResolver_apply_Test {
-
-  @Rule public XtextRule xtext = new XtextRule();
-
-  private ImportUriFixerAndResolver resolver;
-
-  @Before public void setUp() {
-    resolver = (ImportUriFixerAndResolver) xtext.getInstanceOf(ImportUriResolver.class);
-  }
-
-  @Test public void should_fix_import_URI_if_missing_scheme() {
-    StringBuilder proto = new StringBuilder();
-    proto.append("import \"folder1/test.proto\";");
-    Protobuf root = xtext.parse(proto);
-    Import anImport = root.getImports().get(0);
-    String resolved = resolver.apply(anImport);
-    assertThat(resolved, equalTo("platform:/resource/folder1/test.proto"));
-  }
-
-
-  @Test public void should_not_fix_import_URI_if_not_missing_scheme() {
-    StringBuilder proto = new StringBuilder();
-    proto.append("import \"platform:/resource/folder1/test.proto\";");
-    Protobuf root = xtext.parse(proto);
-    Import anImport = root.getImports().get(0);
-    String resolved = resolver.apply(anImport);
-    assertThat(resolved, equalTo("platform:/resource/folder1/test.proto"));
-  }
-}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixer_fixUri_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixer_fixUri_Test.java
new file mode 100644
index 0000000..982eb39
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ImportUriFixer_fixUri_Test.java
@@ -0,0 +1,49 @@
+/*
+ * 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.emf.common.util.URI.createURI;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import org.eclipse.emf.common.util.URI;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for <code>{@link ImportUriFixer#fixUri(String, URI)}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ImportUriFixer_fixUri_Test {
+
+  private ImportUriFixer fixer;
+  private URI resourceUri;
+
+  @Before public void setUp() {
+    resourceUri = createURI("platform:/resource/testing/src/test.proto");
+    fixer = new ImportUriFixer();
+  }
+
+  @Test public void should_fix_import_URI_if_missing_scheme() {
+    String fixed = fixer.fixUri("folder1/test.proto", resourceUri);
+    assertThat(fixed, equalTo("platform:/resource/testing/src/folder1/test.proto"));  
+  }
+
+  @Test public void should_not_fix_import_URI_if_not_missing_scheme() {
+    String importUri = "platform:/resource/testing/src/folder1/test.proto";
+    String fixed = fixer.fixUri(importUri, resourceUri);
+    assertThat(fixed, equalTo(importUri));
+  }
+  
+  @Test public void should_fix_import_URI_even_if_overlapping_folders_with_resource_URI() {
+    String fixed = fixer.fixUri("testing/src/folder1/test.proto", resourceUri);
+    assertThat(fixed, equalTo("platform:/resource/testing/src/folder1/test.proto"));  
+  }
+}
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 0b1c2c8..5a320c3 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
@@ -47,16 +47,17 @@
   '}'(';')?;
 
 MessageElement:
-  Type | Property | Group;
+  Type | Property | Group | ExtendMessage;
 
 Group:
   modifier=Modifier 'group' name=ID '=' index=INT '{'
   elements+=Property*
-  '}';
+  '}'(';')?;
 
 Property:
   modifier=Modifier type=AbstractTypeReference name=ID '=' index=INT (('[' 'default' '=' default=ValueRef
-  ']') | ('[' 'packed' '=' packed=BooleanRef ']') | ('[' 'deprecated' '=' deprecated=BooleanRef ']') )? ';';
+  ']') | ('[' 'packed' '=' packed=BooleanRef ']') | ('[' 'deprecated' '=' deprecated=BooleanRef ']')
+  | ('[' 'default' '=' default=ValueRef ',' 'deprecated' '=' deprecated=BooleanRef ']') )? ';';
 
 enum Modifier:
   required
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Globals.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Globals.java
index e8e8b26..abda482 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Globals.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/Globals.java
@@ -87,12 +87,18 @@
         addFileOption((Property) e);
         continue;
       }
-      if (e instanceof Enum && "OptimizeMode".equals(e.getName())) {
+      if (isOptimizeModeEnum(e)) {
         optimizedMode = (Enum) e;
         continue;
       }
     }
   }
+  
+  private boolean isOptimizeModeEnum(MessageElement e) {
+    if (!(e instanceof Enum)) return false;
+    Enum anEnum = (Enum) e;
+    return "OptimizeMode".equals(anEnum.getName());
+  }
 
   private Message fileOptionsMessage() {
     for (Message m : getAllContentsOfType(root, Message.class))
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixer.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixer.java
new file mode 100644
index 0000000..eec205d
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixer.java
@@ -0,0 +1,55 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package com.google.eclipse.protobuf.scoping;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class ImportUriFixer {
+  
+  static final String PREFIX = "platform:/resource";
+
+  private static final String SEPARATOR = "/";
+
+  /*
+   * The import URI is relative to the file where the import is. Protoc works fine, but the editor doesn't.
+   * In order for the editor to see the import, we need to add to the import URI "platform:resource" and the parent
+   * folder of the file containing the import.
+   *
+   * For example: given the following file hierarchy:
+   *
+   * - protobuf-test (project)
+   *   - folder
+   *     - proto2.proto
+   *   - proto1.proto
+   *
+   * If we import "folder/proto2.proto" into proto1.proto, proto1.proto will compile fine, but the editor will complain.
+   * We need to have the import URI as "platform:/resource/protobuf-test/folder/proto2.proto" for the editor to see it.
+   */
+  String fixUri(String importUri, URI resourceUri) {
+    if (importUri.startsWith(PREFIX)) return importUri;
+    String prefix = uriPrefix(URI.createURI(importUri).segmentsList(), resourceUri);
+    if (importUri.startsWith(prefix)) return importUri;
+    if (!prefix.endsWith(SEPARATOR)) prefix += SEPARATOR;
+    String fixed = prefix + importUri;
+    System.out.println(resourceUri + " : " + importUri + " : " + fixed);
+    return fixed;
+  }
+
+  private String uriPrefix(List<String> importUri, URI resourceUri) {
+    StringBuilder prefix = new StringBuilder();
+    prefix.append(PREFIX);
+    String firstSegment = importUri.get(0);
+    List<String> segments = resourceUri.segmentsList();
+    int end = segments.size() - 1; // ignore file name (at the end of the URI)
+    for (int j = 1; j < end; j++) {
+      if (segments.get(j).equals(firstSegment)) break;
+      prefix.append(SEPARATOR).append(segments.get(j));
+    }
+    return prefix.toString();
+  }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver.java
index 2faf1c5..50a351d 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ImportUriFixerAndResolver.java
@@ -8,13 +8,13 @@
  */
 package com.google.eclipse.protobuf.scoping;
 
-import java.util.List;
+import static com.google.eclipse.protobuf.scoping.ImportUriFixer.PREFIX;
 
-import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.xtext.scoping.impl.ImportUriResolver;
 
 import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.inject.Inject;
 
 /**
  * Resolves URIs. This implementation mimics how protoc understands imported file URIs. For example, the URI
@@ -29,8 +29,8 @@
  */
 public class ImportUriFixerAndResolver extends ImportUriResolver {
 
-  private static final String PREFIX = "platform:/resource";
-
+  @Inject private ImportUriFixer uriFixer;
+  
   /**
    * Prefix used by EMF for resource URIs: "platform:/resource/".
    */
@@ -47,38 +47,8 @@
     return super.apply(from);
   }
 
-  /*
-   * The import URI is relative to the file where the import is. Protoc works fine, but the editor doesn't.
-   * In order for the editor to see the import, we need to add to the import URI "platform:resource" and the parent
-   * folder of the file containing the import.
-   *
-   * For example: given the following file hierarchy:
-   *
-   * - protobuf-test (project)
-   *   - folder
-   *     - proto2.proto
-   *   - proto1.proto
-   *
-   * If we import "folder/proto2.proto" into proto1.proto, proto1.proto will compile fine, but the editor will complain.
-   * We need to have the import URI as "platform:/resource/protobuf-test/folder/proto2.proto" for the editor to see it.
-   */
   private void fixUri(Import i) {
-    String prefix = uriPrefix(i.eResource().getURI());
-    String uri = i.getImportURI();
-    if (!uri.startsWith(prefix)) {
-      if (!uri.startsWith(prefix)) prefix += "/";
-      i.setImportURI(prefix + uri);
-    }
-  }
-
-  private String uriPrefix(URI containerUri) {
-    StringBuilder prefix = new StringBuilder();
-    prefix.append(PREFIX);
-    int start = (containerUri.scheme() == null) ? 0 : 1; // ignore the scheme if present (e.g. "platform")
-    List<String> segments = containerUri.segmentsList();
-    int end = segments.size() - 1; // ignore file name (at the end of the URI)
-    for (int j = start; j < end; j++)
-      prefix.append("/").append(segments.get(j));
-    return prefix.toString();
+    String fixed = uriFixer.fixUri(i.getImportURI(), i.eResource().getURI());
+    i.setImportURI(fixed);
   }
 }