Code cleanup.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
index 76d3e0e..74c569e 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/ProtobufUiModule.java
@@ -154,6 +154,6 @@
     if (w == null || !(plugin instanceof ProtobufActivator)) {
       return;
     }
-    w.getPartService().addPartListener(new ValidateOnActivation());
+    w.getPartService().addPartListener(new ValidateFileOnActivation());
   }
 }
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
index 2df6944..ea34dc1 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/hyperlinking/ProtobufHyperlinkDetector.java
@@ -8,22 +8,20 @@
  */
 package com.google.eclipse.protobuf.ui.editor.hyperlinking;
 
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
 import static org.eclipse.emf.common.util.URI.createURI;
 
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.jface.text.*;
 import org.eclipse.jface.text.hyperlink.*;
 import org.eclipse.xtext.CrossReference;
-import org.eclipse.xtext.nodemodel.INode;
 import org.eclipse.xtext.resource.*;
 import org.eclipse.xtext.ui.editor.hyperlinking.DefaultHyperlinkDetector;
 import org.eclipse.xtext.ui.editor.model.IXtextDocument;
 import org.eclipse.xtext.util.concurrent.IUnitOfWork;
 
-import com.google.eclipse.protobuf.model.util.INodes;
 import com.google.eclipse.protobuf.protobuf.Import;
 import com.google.eclipse.protobuf.ui.editor.FileOpener;
+import com.google.eclipse.protobuf.ui.util.Imports;
 import com.google.inject.Inject;
 
 
@@ -38,7 +36,7 @@
 
   @Inject private EObjectAtOffsetHelper eObjectAtOffsetHelper;
   @Inject private FileOpener fileOpener;
-  @Inject private INodes nodes;
+  @Inject private Imports imports;
 
   @Override public IHyperlink[] detectHyperlinks(ITextViewer textViewer, final IRegion region,
       final boolean canShowMultipleHyperlinks) {
@@ -62,7 +60,7 @@
           return NO_HYPERLINKS;
         }
         Import anImport = (Import) resolved;
-        String importUri = rawUriIn(anImport);
+        String importUri = imports.uriAsEnteredByUser(anImport);
         if (importUri == null) {
           return NO_HYPERLINKS;
         }
@@ -81,18 +79,6 @@
     });
   }
 
-  private String rawUriIn(Import anImport) {
-    INode node = nodes.firstNodeForFeature(anImport, IMPORT__IMPORT_URI);
-    if (node == null) {
-      return null;
-    }
-    String text = node.getText();
-    if (text == null || text.length() < 3) {
-      return null;
-    }
-    return text.substring(1, text.length() - 1); // remove quotes
-  }
-
   private IRegion importUriRegion(IXtextDocument document, int offset, String importUri) throws BadLocationException {
     int lineNumber = document.getLineOfOffset(offset);
     int lineLength = document.getLineLength(lineNumber);
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ProtobufValidation.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ProtobufValidation.java
new file mode 100644
index 0000000..74a81c8
--- /dev/null
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ProtobufValidation.java
@@ -0,0 +1,82 @@
+/*
+ * 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.validation;
+
+import static org.eclipse.xtext.EcoreUtil2.getAllContentsOfType;
+
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.resource.impl.ListBasedDiagnosticConsumer;
+import org.eclipse.xtext.ui.editor.XtextEditor;
+import org.eclipse.xtext.ui.editor.model.*;
+import org.eclipse.xtext.util.concurrent.IUnitOfWork;
+
+import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.ui.ProtobufPlugIn;
+import com.google.eclipse.protobuf.ui.util.Imports;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+final class ProtobufValidation {
+  static void validate(IEditorPart editor) {
+    if (!(editor instanceof XtextEditor) || !(editor.getEditorInput() instanceof FileEditorInput)) {
+      return;
+    }
+    XtextEditor xtextEditor = (XtextEditor) editor;
+    if (!ProtobufPlugIn.languageName().equals(xtextEditor.getLanguageName())) {
+      return;
+    }
+    validate(xtextEditor);
+  }
+
+  private static void validate(XtextEditor editor) {
+    final IXtextDocument document = editor.getDocument();
+    if (!(document instanceof XtextDocument)) {
+      return;
+    }
+    document.readOnly(new IUnitOfWork.Void<XtextResource>() {
+      @Override public void process(XtextResource resource) {
+        EObject root = rootOf(resource);
+        if (root == null) {
+          return;
+        }
+        resetUriInImports(root);
+        resource.getLinker().linkModel(root, new ListBasedDiagnosticConsumer());
+        ((XtextDocument) document).checkAndUpdateAnnotations();
+      }
+    });
+  }
+
+  private static EObject rootOf(XtextResource resource) {
+    return resource == null ? null : resource.getParseResult().getRootASTElement();
+  }
+
+  private static void resetUriInImports(EObject root) {
+    List<Import> imports = getAllContentsOfType(root, Import.class);
+    for (Import anImport : imports) {
+      resetUri(anImport);
+    }
+  }
+
+  private static void resetUri(Import anImport) {
+    Imports imports = ProtobufPlugIn.getInstance(Imports.class);
+    String uri = imports.uriAsEnteredByUser(anImport);
+    if (uri == null) {
+      return;
+    }
+    anImport.setImportURI(uri);
+  }
+
+  private ProtobufValidation() {}
+}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateFileOnActivation.java
similarity index 95%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateFileOnActivation.java
index 38da096..a61053a 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateOnActivation.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidateFileOnActivation.java
@@ -10,7 +10,7 @@
 package com.google.eclipse.protobuf.ui.validation;
 
 import static com.google.eclipse.protobuf.ui.preferences.general.core.GeneralPreferences.generalPreferences;
-import static com.google.eclipse.protobuf.ui.validation.Validation.validate;
+import static com.google.eclipse.protobuf.ui.validation.ProtobufValidation.validate;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.ui.*;
@@ -25,7 +25,7 @@
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
-public class ValidateOnActivation implements IPartListener2 {
+public class ValidateFileOnActivation implements IPartListener2 {
   /**
    * Validates the active active editor in the given part that contains a .proto file in the Workspace.
    * @param partRef the part that was activated.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/Validation.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/Validation.java
deleted file mode 100644
index 477a07b..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/Validation.java
+++ /dev/null
@@ -1,124 +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.ui.validation;
-
-import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
-import static com.google.eclipse.protobuf.ui.ProtobufPlugIn.languageName;
-import static org.eclipse.xtext.EcoreUtil2.getAllContentsOfType;
-
-import java.util.List;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.part.FileEditorInput;
-import org.eclipse.xtext.nodemodel.INode;
-import org.eclipse.xtext.resource.XtextResource;
-import org.eclipse.xtext.resource.impl.ListBasedDiagnosticConsumer;
-import org.eclipse.xtext.ui.editor.XtextEditor;
-import org.eclipse.xtext.ui.editor.model.*;
-import org.eclipse.xtext.util.concurrent.IUnitOfWork;
-
-import com.google.eclipse.protobuf.conversion.STRINGValueConverter;
-import com.google.eclipse.protobuf.model.util.INodes;
-import com.google.eclipse.protobuf.protobuf.Import;
-import com.google.eclipse.protobuf.ui.ProtobufPlugIn;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-final class Validation {
-  static void validate(IEditorPart editor) {
-    XtextEditor protoEditor = asProtoEditor(editor);
-    if (protoEditor == null) {
-      return;
-    }
-    validate(protoEditor);
-  }
-
-  private static XtextEditor asProtoEditor(IEditorPart editor) {
-    XtextEditor xtextEditor = asXtextEditor(editor);
-    if (xtextEditor == null) {
-      return null;
-    }
-    if (!languageName().equals(xtextEditor.getLanguageName())) {
-      return null;
-    }
-    return xtextEditor;
-  }
-
-  private static XtextEditor asXtextEditor(IEditorPart editor) {
-    if (!isXtextEditorContainingWorkspaceFile(editor)) {
-      return null;
-    }
-    return (XtextEditor) editor;
-  }
-
-  private static boolean isXtextEditorContainingWorkspaceFile(IEditorPart editor) {
-    return editor instanceof XtextEditor && editor.getEditorInput() instanceof FileEditorInput;
-  }
-
-  private static void validate(XtextEditor editor) {
-    final IXtextDocument document = editor.getDocument();
-    if (!(document instanceof XtextDocument)) {
-      return;
-    }
-    document.readOnly(new IUnitOfWork.Void<XtextResource>() {
-      @Override public void process(XtextResource resource) {
-        EObject root = rootOf(resource);
-        if (root == null) {
-          return;
-        }
-        resetImports(root);
-        resource.getLinker().linkModel(root, new ListBasedDiagnosticConsumer());
-        ((XtextDocument) document).checkAndUpdateAnnotations();
-      }
-    });
-  }
-
-  private static EObject rootOf(XtextResource resource) {
-    if (resource == null) {
-      return null;
-    }
-    return resource.getParseResult().getRootASTElement();
-  }
-
-  private static void resetImports(EObject root) {
-    List<Import> imports = getAllContentsOfType(root, Import.class);
-    for (Import anImport : imports) {
-      resetUri(anImport);
-    }
-  }
-
-  private static void resetUri(Import anImport) {
-    String uri = uriAsEnteredInEditor(anImport);
-    if (uri == null) {
-      return;
-    }
-    anImport.setImportURI(uri);
-  }
-
-  private static String uriAsEnteredInEditor(Import anImport) {
-    INode node = nodes().firstNodeForFeature(anImport, IMPORT__IMPORT_URI);
-    if (node == null) {
-      return null;
-    }
-    String text = node.getText();
-    if (text == null) {
-      return null;
-    }
-    STRINGValueConverter converter = ProtobufPlugIn.getInstance(STRINGValueConverter.class);
-    return converter.toValue(text, node);
-  }
-
-  private static INodes nodes() {
-    return ProtobufPlugIn.getInstance(INodes.class);
-  }
-
-  private Validation() {}
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidationTrigger.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidationTrigger.java
index aa07a44..5370560 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidationTrigger.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/validation/ValidationTrigger.java
@@ -9,7 +9,7 @@
 package com.google.eclipse.protobuf.ui.validation;
 
 import static com.google.common.base.Objects.equal;
-import static com.google.eclipse.protobuf.ui.validation.Validation.validate;
+import static com.google.eclipse.protobuf.ui.validation.ProtobufValidation.validate;
 
 import java.net.URI;
 
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ImportValidator.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ImportValidator.java
index bddd692..4f06f51 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ImportValidator.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ImportValidator.java
@@ -10,13 +10,16 @@
 
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
-import static com.google.eclipse.protobuf.validation.Messages.importingNonProto2;
+import static com.google.eclipse.protobuf.validation.Messages.*;
+import static java.lang.String.format;
+import static org.eclipse.xtext.util.Strings.isEmpty;
 import static org.eclipse.xtext.util.Tuples.pair;
 
 import java.util.*;
 
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.resource.*;
+import org.eclipse.xtext.scoping.impl.ImportUriResolver;
 import org.eclipse.xtext.util.Pair;
 import org.eclipse.xtext.validation.*;
 
@@ -25,7 +28,7 @@
 import com.google.inject.Inject;
 
 /**
- * Verifies that imports only refer to "proto2" files.
+ * Verifies that "imports" contain correct values.
  *
  * @author alruiz@google.com (Alex Ruiz)
  */
@@ -33,12 +36,13 @@
   @Inject private ModelFinder finder;
   @Inject private Protobufs protobufs;
   @Inject private Resources resources;
+  @Inject private ImportUriResolver uriResolver;
 
   @Override public void register(EValidatorRegistrar registrar) {}
 
   /**
-   * Verifies that the imports in the given root only refer to "proto2" files. If non-proto2 imports are found, this
-   * validator creates warning markers for such imports.
+   * Verifies that "imports" in the given root only refer to "proto2" files. If non-proto2 "imports" are found, this
+   * validator creates warning markers for such "imports".
    * @param root the root containing the imports to check.
    */
   @Check public void checkNonProto2Imports(Protobuf root) {
@@ -58,7 +62,7 @@
     for (Import anImport : finder.importsIn(root)) {
       Resource imported = resources.importedResource(anImport, resourceSet);
       checked.add(imported.getURI());
-      if (!isProto2(imported)) {
+      if (!protobufs.isProto2(finder.rootOf(imported))) {
         hasNonProto2 = true;
         warnNonProto2ImportFoundIn(anImport);
         continue;
@@ -76,7 +80,7 @@
     }
   }
 
-  private boolean hasNonProto2(Pair<Import, Resource> toCheck, Set<URI> checked, ResourceSet resourceSet) {
+  private boolean hasNonProto2(Pair<Import, Resource> toCheck, Set<URI> alreadyChecked, ResourceSet resourceSet) {
     Protobuf root = finder.rootOf(toCheck.getSecond());
     if (!protobufs.isProto2(root)) {
       return false;
@@ -84,27 +88,49 @@
     List<Pair<Import, Resource>> resourcesToCheck = newArrayList();
     for (Import anImport : finder.importsIn(root)) {
       Resource imported = resources.importedResource(anImport, resourceSet);
-      if (checked.contains(imported.getURI())) {
+      if (alreadyChecked.contains(imported.getURI())) {
         continue;
       }
-      if (!isProto2(imported)) {
+      if (!protobufs.isProto2(finder.rootOf(imported))) {
         return true;
       }
       resourcesToCheck.add(pair(toCheck.getFirst(), imported));
     }
     for (Pair<Import, Resource> p : resourcesToCheck) {
-      if (hasNonProto2(p, checked, resourceSet)) {
+      if (hasNonProto2(p, alreadyChecked, resourceSet)) {
         return true;
       }
     }
     return false;
   }
 
-  private boolean isProto2(Resource r) {
-    return protobufs.isProto2(finder.rootOf(r));
-  }
-
   private void warnNonProto2ImportFoundIn(Import anImport) {
     acceptWarning(importingNonProto2, anImport, IMPORT__IMPORT_URI, INSIGNIFICANT_INDEX, null);
   }
+
+  /**
+   * Verifies that the URI of the given "import" has been resolved. If the URI has not been resolved, the validator
+   * creates an error marker for the given "import."
+   * @param anImport the given "import."
+   */
+  @Check public void checkUriIsResolved(Import anImport) {
+    if (isResolved(anImport)) {
+      return;
+    }
+    uriResolver.apply(anImport);
+    if (!isResolved(anImport)) {
+      error(format(importNotFound, anImport.getImportURI()), IMPORT__IMPORT_URI);
+    }
+  }
+
+  private boolean isResolved(Import anImport) {
+    String importUri = anImport.getImportURI();
+    if (!isEmpty(importUri)) {
+      URI uri = URI.createURI(importUri);
+      if (!isEmpty(uri.scheme())) {
+        return true;
+      }
+    }
+    return false;
+  }
 }
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 c948992..9dac7b3 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
@@ -11,12 +11,9 @@
 import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.*;
 import static com.google.eclipse.protobuf.validation.Messages.*;
 import static java.lang.String.format;
-import static org.eclipse.xtext.util.Strings.isEmpty;
 
-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.grammar.Syntaxes;
@@ -39,7 +36,6 @@
   @Inject private NameResolver nameResolver;
   @Inject private Protobufs protobufs;
   @Inject private IQualifiedNameProvider qualifiedNameProvider;
-  @Inject private ImportUriResolver uriResolver;
 
   @Check public void checkIsProto2(Protobuf protobuf) {
     if (!protobufs.isProto2(protobuf)) {
@@ -47,32 +43,6 @@
     }
   }
 
-  @Check public void checkImportIsResolved(Import anImport) {
-    if (retryUntilItIsResolved(anImport)) {
-      return;
-    }
-    error(format(importNotFound, anImport.getImportURI()), IMPORT__IMPORT_URI);
-  }
-
-  private boolean retryUntilItIsResolved(Import anImport) {
-    if (isResolved(anImport)) {
-      return true;
-    }
-    uriResolver.apply(anImport);
-    return isResolved(anImport);
-  }
-
-  private boolean isResolved(Import anImport) {
-    String importUri = anImport.getImportURI();
-    if (!isEmpty(importUri)) {
-      URI uri = URI.createURI(importUri);
-      if (!isEmpty(uri.scheme())) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   @Check public void checkSyntaxIsProto2(Syntax syntax) {
     String name = syntax.getName();
     if (Syntaxes.proto2().equals(name)) {