Code cleanup. Adding more tests.
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/XtextRule.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/XtextRule.java
index ea542eb..aae9b9a 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/XtextRule.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/XtextRule.java
@@ -8,21 +8,24 @@
  */
 package com.google.eclipse.protobuf.junit.core;
 
+import static com.google.eclipse.protobuf.junit.util.SystemProperties.lineSeparator;
 import static org.eclipse.emf.common.util.URI.createURI;
 import static org.eclipse.emf.ecore.util.EcoreUtil.resolveAll;
 import static org.eclipse.xtext.util.CancelIndicator.NullImpl;
 
-import java.io.*;
+import com.google.eclipse.protobuf.protobuf.Protobuf;
+import com.google.inject.Injector;
 
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.xtext.linking.lazy.LazyLinkingResource;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.parser.IParseResult;
 import org.eclipse.xtext.resource.*;
 import org.eclipse.xtext.util.StringInputStream;
 import org.junit.rules.MethodRule;
 import org.junit.runners.model.*;
 
-import com.google.eclipse.protobuf.protobuf.Protobuf;
-import com.google.inject.Injector;
+import java.io.*;
 
 /**
  * Rule that performs configuration of a standalone Xtext environment.
@@ -47,7 +50,14 @@
 
   public Protobuf parse(String text) {
     XtextResource resource = resourceFrom(new StringInputStream(text));
-    return (Protobuf) resource.getParseResult().getRootASTElement();
+    IParseResult parseResult = resource.getParseResult();
+    if (!parseResult.hasSyntaxErrors()) return (Protobuf) parseResult.getRootASTElement();
+    Iterable<INode> syntaxErrors = parseResult.getSyntaxErrors();
+    StringBuilder builder = new StringBuilder();
+    builder.append("Syntax errors:");
+    for (INode error : parseResult.getSyntaxErrors()) 
+      builder.append(lineSeparator()).append("- ").append(error.getSyntaxErrorMessage());
+    throw new IllegalStateException(builder.toString());
   }
 
   private XtextResource resourceFrom(InputStream input) {
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/util/SystemProperties.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/util/SystemProperties.java
new file mode 100644
index 0000000..69a11be
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/util/SystemProperties.java
@@ -0,0 +1,23 @@
+/*
+ * 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.junit.util;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public final class SystemProperties {
+
+  private static final String LINE_SEPARATOR = System.getProperty("line.separator");
+  
+  public static String lineSeparator() {
+    return LINE_SEPARATOR;
+  }
+  
+  private SystemProperties() {}
+}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/util/ModelNodes_firstNodeForFeature_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/util/ModelNodes_firstNodeForFeature_Test.java
new file mode 100644
index 0000000..6da5d5b
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/util/ModelNodes_firstNodeForFeature_Test.java
@@ -0,0 +1,48 @@
+/*
+ * 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 com.google.eclipse.protobuf.junit.util.Finder.findProperty;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.FIELD__NAME;
+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.*;
+
+import org.eclipse.emf.ecore.*;
+import org.eclipse.xtext.nodemodel.INode;
+import org.junit.*;
+
+/**
+ * Tests for <code>{@link ModelNodes#firstNodeForFeature(EObject, EStructuralFeature)}</code>
+ * 
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ModelNodes_firstNodeForFeature_Test {
+
+  @Rule public XtextRule xtext = new XtextRule();
+
+  private ModelNodes nodes;
+  
+  @Before public void setUp() {
+    nodes = xtext.getInstanceOf(ModelNodes.class);
+  }
+  
+  @Test public void should_return_first_node_for_feature() {
+    StringBuilder proto = new StringBuilder();
+    proto.append("message Person {           ")
+         .append("  optional bool active = 1;")
+         .append("}                          ");
+    Protobuf root = xtext.parse(proto);
+    Property active = findProperty("active", root);
+    INode node = nodes.firstNodeForFeature(active, FIELD__NAME);
+    assertThat(node.getText().trim(), equalTo("active"));
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/documentation/SingleLineCommentDocumentationProvider_getDocumentation_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/documentation/SingleLineCommentDocumentationProvider_getDocumentation_Test.java
new file mode 100644
index 0000000..99d5a9b
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/documentation/SingleLineCommentDocumentationProvider_getDocumentation_Test.java
@@ -0,0 +1,59 @@
+/*
+ * 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.ui.documentation;
+
+import static com.google.eclipse.protobuf.junit.util.Finder.findProperty;
+import static com.google.eclipse.protobuf.junit.util.SystemProperties.lineSeparator;
+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.*;
+
+import org.eclipse.emf.ecore.EObject;
+import org.junit.*;
+
+/**
+ * Tests for <code>{@link SingleLineCommentDocumentationProvider#getDocumentation(EObject)}</code>
+ * 
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class SingleLineCommentDocumentationProvider_getDocumentation_Test {
+
+  @Rule public XtextRule xtext = new XtextRule();
+
+  private SingleLineCommentDocumentationProvider provider;
+  
+  @Before public void setUp() {
+    provider = xtext.getInstanceOf(SingleLineCommentDocumentationProvider.class);
+  }
+  
+  @Test public void should_return_single_line_comment_of_element() {
+    StringBuilder proto = new StringBuilder();
+    proto.append("message Person {           ").append(lineSeparator())
+         .append("  // Indicates whether the person is active or not.").append(lineSeparator())
+         .append("  optional bool active = 1;").append(lineSeparator())
+         .append("}                          ");
+    Protobuf root = xtext.parse(proto);
+    Property active = findProperty("active", root);
+    String documentation = provider.getDocumentation(active);
+    assertThat(documentation, equalTo("Indicates whether the person is active or not."));
+  }
+  
+  @Test public void should_return_empty_String_if_element_does_not_have_single_line_comment() {
+    StringBuilder proto = new StringBuilder();
+    proto.append("message Person {           ")
+         .append("  optional bool active = 1;")
+         .append("}                          ");
+    Protobuf root = xtext.parse(proto);
+    Property active = findProperty("active", root);
+    String documentation = provider.getDocumentation(active);
+    assertThat(documentation, equalTo(""));
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java
index d6d6190..444632d 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java
@@ -66,8 +66,7 @@
           int offset = styledText.getCaretOffset();
           ContentAssistContext[] context = contextFactory.create(editor.getInternalSourceViewer(), offset, state);
           for (ContentAssistContext c : context) {
-            INode currentNode = c.getCurrentNode();
-            if (nodes.wasCreatedByAnyComment(currentNode) || wasCreatedByString(currentNode)) break;
+            if (isCommentOrString(c.getCurrentNode())) break;
             EObject model = c.getCurrentModel();
             if (model instanceof FieldOption) {
               FieldOption option = (FieldOption) model;
@@ -100,6 +99,10 @@
     return ContentToInsert.NONE;
   }
 
+  private boolean isCommentOrString(INode currentNode) {
+    return nodes.wasCreatedByAnyComment(currentNode) || wasCreatedByString(currentNode);
+  }
+
   private boolean wasCreatedByString(INode node) {
     EObject grammarElement = node.getGrammarElement();
     if (!(grammarElement instanceof RuleCall)) return false;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/documentation/SingleLineCommentDocumentationProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/documentation/SingleLineCommentDocumentationProvider.java
index 1f787f6..efda1a0 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/documentation/SingleLineCommentDocumentationProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/documentation/SingleLineCommentDocumentationProvider.java
@@ -51,7 +51,7 @@
         commentBuilder.append(cleanUp(comment));
       }
     }
-    return commentBuilder.toString();
+    return commentBuilder.toString().trim();
   }
 
   private EObject findRealTarget(EObject o) {