Adding tests.
diff --git a/com.google.eclipse.protobuf.junit/src/com/google/eclipse/protobuf/junit/KeywordHasValueMatcher.java b/com.google.eclipse.protobuf.junit/src/com/google/eclipse/protobuf/junit/KeywordHasValueMatcher.java
deleted file mode 100644
index be27bce..0000000
--- a/com.google.eclipse.protobuf.junit/src/com/google/eclipse/protobuf/junit/KeywordHasValueMatcher.java
+++ /dev/null
@@ -1,41 +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.junit;
-
-import org.eclipse.xtext.Keyword;
-import org.hamcrest.BaseMatcher;
-import org.hamcrest.Description;
-
-/**
- * Matches that verifies that a value of a <code>{@link Keyword}</code> is equal to the expected value.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class KeywordHasValueMatcher extends BaseMatcher<Keyword> {
-
-  private final String expectedValue;
-
-  public static KeywordHasValueMatcher hasValue(String expected) {
-    return new KeywordHasValueMatcher(expected);
-  }
-  
-  private KeywordHasValueMatcher(String expectedValue) {
-    this.expectedValue = expectedValue;
-  }
-  
-  public boolean matches(Object arg) {
-    if (!(arg instanceof Keyword)) return false;
-    Keyword keyword = (Keyword) arg;
-    return keyword.getValue().equals(expectedValue);
-  }
-
-  public void describeTo(Description description) {
-    description.appendValue(expectedValue);
-  }
-}
diff --git a/com.google.eclipse.protobuf.junit/src/com/google/eclipse/protobuf/junit/XtextRule.java b/com.google.eclipse.protobuf.junit/src/com/google/eclipse/protobuf/junit/XtextRule.java
index 222353f..0fc6b9f 100644
--- a/com.google.eclipse.protobuf.junit/src/com/google/eclipse/protobuf/junit/XtextRule.java
+++ b/com.google.eclipse.protobuf.junit/src/com/google/eclipse/protobuf/junit/XtextRule.java
@@ -12,16 +12,14 @@
 import static org.eclipse.emf.ecore.util.EcoreUtil.resolveAll;
 import static org.eclipse.xtext.util.CancelIndicator.NullImpl;
 
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.xtext.linking.lazy.LazyLinkingResource;
 import org.eclipse.xtext.resource.*;
 import org.eclipse.xtext.util.StringInputStream;
 import org.junit.rules.MethodRule;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.Statement;
+import org.junit.runners.model.*;
 
 import com.google.eclipse.protobuf.ProtobufStandaloneSetup;
 import com.google.eclipse.protobuf.protobuf.Protobuf;
@@ -54,7 +52,7 @@
   }
 
   private XtextResource resourceFrom(InputStream input) {
-    return resourceFrom(input, createURI("mytestmodel.proto"));
+    return resourceFrom(input, createURI("mytestmodel.proto")); //$NON-NLS-1$
   }
 
   private XtextResource resourceFrom(InputStream input, URI uri) {
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword_hasValue_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword_hasValue_Test.java
new file mode 100644
index 0000000..3c0f7a3
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword_hasValue_Test.java
@@ -0,0 +1,42 @@
+/*
+ * 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.grammar;
+
+import static com.google.eclipse.protobuf.ui.grammar.CommonKeyword.*;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+/**
+ * Tests for <code>{@link CommonKeyword#hasValue(String)}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CommonKeyword_hasValue_Test {
+
+  @Test public void should_return_true_if_value_is_equal_to_String() {
+    assertThat(BOOL.hasValue("bool"), equalTo(true));
+    assertThat(TRUE.hasValue("true"), equalTo(true));
+    assertThat(FALSE.hasValue("false"), equalTo(true));
+    assertThat(BYTES.hasValue("bytes"), equalTo(true));
+    assertThat(OPENING_BRACKET.hasValue("["), equalTo(true));
+    assertThat(CLOSING_BRACKET.hasValue("]"), equalTo(true));
+    assertThat(DEFAULT.hasValue("default"), equalTo(true));
+    assertThat(EQUAL.hasValue("="), equalTo(true));
+    assertThat(PACKED.hasValue("packed"), equalTo(true));
+    assertThat(SEMICOLON.hasValue(";"), equalTo(true));
+    assertThat(STRING.hasValue("string"), equalTo(true));
+  }
+
+  @Test public void should_return_false_if_value_is_not_equal_to_String() {
+    assertThat(STRING.hasValue(";"), equalTo(false));
+  }
+
+}
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword_toString_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword_toString_Test.java
new file mode 100644
index 0000000..d7335fa
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword_toString_Test.java
@@ -0,0 +1,28 @@
+/*
+ * 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.grammar;
+
+import static com.google.eclipse.protobuf.ui.grammar.CommonKeyword.BOOL;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+/**
+ * Tests for <code>{@link CommonKeyword#toString()}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CommonKeyword_toString_Test {
+
+  @Test public void should_return_keyword_value() {
+    assertThat(BOOL.toString(), equalTo("bool"));
+  }
+
+}
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement_hasValue_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement_hasValue_Test.java
new file mode 100644
index 0000000..2b5329b
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement_hasValue_Test.java
@@ -0,0 +1,37 @@
+/*
+ * 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.grammar;
+
+import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.*;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+/**
+ * Tests for <code>{@link CompoundElement#hasValue(String)}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CompoundElement_hasValue_Test {
+
+  @Test public void should_return_true_if_value_is_equal_to_String() {
+    assertThat(DEFAULT_EQUAL.hasValue("default ="), equalTo(true));
+    assertThat(DEFAULT_EQUAL_IN_BRACKETS.hasValue("[default =]"), equalTo(true));
+    assertThat(EMPTY_STRING.hasValue("\"\""), equalTo(true));
+    assertThat(DEFAULT_EQUAL_STRING.hasValue("default = \"\""), equalTo(true));
+    assertThat(DEFAULT_EQUAL_STRING_IN_BRACKETS.hasValue("[default = \"\"]"), equalTo(true));
+    assertThat(PACKED_EQUAL_TRUE.hasValue("packed = true"), equalTo(true));
+    assertThat(PACKED_EQUAL_TRUE_IN_BRACKETS.hasValue("[packed = true]"), equalTo(true));
+  }
+
+  @Test public void should_return_false_if_value_is_not_equal_to_String() {
+    assertThat(DEFAULT_EQUAL.hasValue("packed ="), equalTo(false));
+  }
+}
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement_toString_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement_toString_Test.java
new file mode 100644
index 0000000..a8c40c6
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement_toString_Test.java
@@ -0,0 +1,28 @@
+/*
+ * 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.grammar;
+
+import static com.google.eclipse.protobuf.ui.grammar.CompoundElement.DEFAULT_EQUAL;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+/**
+ * Tests for <code>{@link CompoundElement#toString()}</code>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CompoundElement_toString_Test {
+
+  @Test public void should_return_keyword_value() {
+    assertThat(DEFAULT_EQUAL.toString(), equalTo("default ="));
+  }
+
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
index 6c8cf04..9f58cae 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
@@ -141,7 +141,7 @@
     for (AbstractElement e : grammarElements) {
       if (!(e instanceof Assignment)) continue;
       Assignment a = (Assignment) e;
-      if (feature.hasValueEqualTo(a.getFeature()) && EQUAL.hasValueEqualTo(a.getOperator())) return true;
+      if (feature.hasValue(a.getFeature()) && EQUAL.hasValue(a.getOperator())) return true;
     }
     return false;
   }
@@ -149,33 +149,37 @@
   @Override public void completeKeyword(Keyword keyword, ContentAssistContext context,
       ICompletionProposalAcceptor acceptor) {
     if (keyword == null) return;
-    if (isKeywordEqualToPreviousWordInEditor(keyword, context)) return;
-    if (TRUE.hasValueEqualTo(keyword) || FALSE.hasValueEqualTo(keyword)) {
-      if (!isBoolProposalValid(context)) return;
-    }
-    if (OPENING_BRACKET.hasValueEqualTo(keyword)) {
-      boolean proposalWasHandledAlready = proposeOpenBracket(context, acceptor);
-      if (proposalWasHandledAlready) return;
-    }
-    if (PACKED.hasValueEqualTo(keyword)) {
-      proposePackedOption(context, acceptor);
-      return;
-    }
-    if (DEFAULT.hasValueEqualTo(keyword)) {
-      proposeDefaultValue(context, acceptor);
-      return;
-    }
+    boolean proposalWasHandledAlready = completeKeyword(keyword.getValue(), context, acceptor);
+    if (proposalWasHandledAlready) return;
     super.completeKeyword(keyword, context, acceptor);
   }
 
-  private boolean isKeywordEqualToPreviousWordInEditor(Keyword keyword, ContentAssistContext context) {
+  private boolean completeKeyword(String keyword, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+    if (isKeywordEqualToPreviousWordInEditor(keyword, context)) return true;
+    if (TRUE.hasValue(keyword) || FALSE.hasValue(keyword)) {
+      if (!isBoolProposalValid(context)) return true;
+    }
+    if (OPENING_BRACKET.hasValue(keyword)) {
+      return proposeOpenBracket(context, acceptor);
+    }
+    if (PACKED.hasValue(keyword)) {
+      proposePackedOption(context, acceptor);
+      return true;
+    }
+    if (DEFAULT.hasValue(keyword)) {
+      proposeDefaultValue(context, acceptor);
+      return true;
+    }
+    return false;
+  }
+
+  private boolean isKeywordEqualToPreviousWordInEditor(String keyword, ContentAssistContext context) {
     StyledText styledText = context.getViewer().getTextWidget();
-    String value = keyword.getValue();
-    int valueLength = value.length();
+    int valueLength = keyword.length();
     int start = styledText.getCaretOffset() - valueLength;
     if (start < 0) return false;
     String previousWord = styledText.getTextRange(start, valueLength);
-    return value.equals(previousWord);
+    return keyword.equals(previousWord);
   }
 
   private boolean isBoolProposalValid(ContentAssistContext context) {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword.java
index 24efb42..ff3cd6a 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword.java
@@ -8,8 +8,6 @@
  */
 package com.google.eclipse.protobuf.ui.grammar;
 
-import org.eclipse.xtext.Keyword;
-
 /**
  * A commonly used keyword.
  *
@@ -18,10 +16,11 @@
 public enum CommonKeyword {
 
   // we used to get keywords from IGrammarAccess. The problem was that we still had to hardcode the keyword we were
-  // looking for. The code was too complicated and we had to change our implementation anyway.
+  // looking for. The code was too complicated and if the grammar changed for some reason, we had to change our
+  // implementation anyway.
 
   BOOL("bool"), TRUE("true"), FALSE("false"), BYTES("bytes"), OPENING_BRACKET("["), CLOSING_BRACKET("]"),
-    DEFAULT("default"), EQUAL("="), PACKED("packet"), SEMICOLON(";"), STRING("string");
+    DEFAULT("default"), EQUAL("="), PACKED("packed"), SEMICOLON(";"), STRING("string");
 
   private final String value;
 
@@ -29,14 +28,19 @@
     this.value = value;
   }
 
-  public boolean hasValueEqualTo(Keyword k) {
-    return hasValueEqualTo(k.getValue());
-  }
-
-  public boolean hasValueEqualTo(String s) {
+  /**
+   * Indicates whether the value of this keyword is equal to the given {@code String}.
+   * @param s the value to compare to.
+   * @return {@code true} if the value of this keyword is equal to the given {@code String}, {@code false} otherwise.
+   */
+  public boolean hasValue(String s) {
     return value.equals(s);
   }
 
+  /**
+   * Returns the textual value of this keyword.
+   * @return the textual value of this keyword.
+   */
   @Override public String toString() {
     return value;
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement.java
index 5fe9ed8..18612a5 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement.java
@@ -55,14 +55,38 @@
     this.value = value;
   }
 
+  /**
+   * Indicates whether the value of this compound element is equal to the given {@code String}.
+   * @param s the value to compare to.
+   * @return {@code true} if the value of this compound element is equal to the given {@code String}, {@code false}
+   * otherwise.
+   */
+  public boolean hasValue(String s) {
+    return value.equals(s);
+  }
+
+  /**
+   * Returns the number of characters in this compound element.
+   * @return the number of characters in this compound element.
+   */
   public int charCount() {
     return value.length();
   }
 
+  /**
+   * Returns the index within this compound element of the first occurrence of the value of the specified keyword.
+   * @param keyword the given keyword.
+   * @return the index within this compound element of the first occurrence of the value of the specified keyword; -1
+   * if the value of the given keyword is not found.
+   */
   public int indexOf(CommonKeyword keyword) {
     return value.indexOf(keyword.toString());
   }
 
+  /**
+   * Returns the textual value of this compound element.
+   * @return the textual value of this compound element.
+   */
   @Override public String toString() {
     return value;
   }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Properties.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Properties.java
index ebd00e4..b9dd4f1 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Properties.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Properties.java
@@ -37,7 +37,7 @@
     AbstractTypeReference r = p.getType();
     if (!(r instanceof ScalarTypeReference)) return false;
     String typeName = ((ScalarTypeReference) r).getScalar().getName();
-    return !STRING.hasValueEqualTo(typeName) && !BYTES.hasValueEqualTo(typeName);
+    return !STRING.hasValue(typeName) && !BYTES.hasValue(typeName);
   }
 
   /**
@@ -59,7 +59,7 @@
   }
 
   private boolean isScalarType(Property p, CommonKeyword typeKeyword) {
-    return typeKeyword.hasValueEqualTo(typeNameOf(p));
+    return typeKeyword.hasValue(typeNameOf(p));
   }
 
   /**