Adding support for converting scoping errors into warnings if non-proto2
files are imported. Code cleanup.
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/CodeGenerationErrorParser_parseAndAddMarkerIfNecessary_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/CodeGenerationErrorParser_parseAndAddMarkerIfNecessary_Test.java
similarity index 96%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/CodeGenerationErrorParser_parseAndAddMarkerIfNecessary_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/CodeGenerationErrorParser_parseAndAddMarkerIfNecessary_Test.java
index 2338707..fc36213 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/CodeGenerationErrorParser_parseAndAddMarkerIfNecessary_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/CodeGenerationErrorParser_parseAndAddMarkerIfNecessary_Test.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static org.mockito.Mockito.*;
 
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/LineSpecificErrorParser_parseAndAddMarkerIfNecessary_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/LineSpecificErrorParser_parseAndAddMarkerIfNecessary_Test.java
similarity index 96%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/LineSpecificErrorParser_parseAndAddMarkerIfNecessary_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/LineSpecificErrorParser_parseAndAddMarkerIfNecessary_Test.java
index 13b1cc8..4f0f512 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/LineSpecificErrorParser_parseAndAddMarkerIfNecessary_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/LineSpecificErrorParser_parseAndAddMarkerIfNecessary_Test.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static org.mockito.Mockito.*;
 
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/ProtoDescriptorPathFinder_findRootOf_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtoDescriptorPathFinder_findRootOf_Test.java
similarity index 92%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/ProtoDescriptorPathFinder_findRootOf_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtoDescriptorPathFinder_findRootOf_Test.java
index 9639d8f..36ea148 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/ProtoDescriptorPathFinder_findRootOf_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtoDescriptorPathFinder_findRootOf_Test.java
@@ -6,12 +6,14 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static org.hamcrest.core.IsEqual.equalTo;
 import static org.junit.Assert.*;
 import static org.junit.rules.ExpectedException.none;
 
+import com.google.eclipse.protobuf.ui.builder.protoc.ProtoDescriptorPathFinder;
+
 import org.junit.*;
 import org.junit.rules.ExpectedException;
 
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/ProtocMarkerFactory_createErrorIfNecessary_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocMarkerFactory_createErrorIfNecessary_Test.java
similarity index 94%
rename from com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/ProtocMarkerFactory_createErrorIfNecessary_Test.java
rename to com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocMarkerFactory_createErrorIfNecessary_Test.java
index ea42a3d..f081c72 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/ProtocMarkerFactory_createErrorIfNecessary_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocMarkerFactory_createErrorIfNecessary_Test.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static com.google.eclipse.protobuf.junit.stubs.resources.MarkerStub.error;
 import static org.eclipse.xtext.ui.MarkerTypes.FAST_VALIDATION;
@@ -19,6 +19,7 @@
 import org.junit.*;
 
 import com.google.eclipse.protobuf.junit.stubs.resources.*;
+import com.google.eclipse.protobuf.ui.builder.protoc.ProtocMarkerFactory;
 
 /**
  * Tests for <code>{@link ProtocMarkerFactory#createErrorIfNecessary(String, String, int)}</code>.
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 7978be7..87ba97d 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
@@ -26,7 +26,7 @@
 import org.eclipse.xtext.ui.editor.syntaxcoloring.*;
 
 import com.google.eclipse.protobuf.scoping.IFileUriResolver;
-import com.google.eclipse.protobuf.ui.builder.AutoAddNatureEditorCallback;
+import com.google.eclipse.protobuf.ui.builder.nature.AutoAddNatureEditorCallback;
 import com.google.eclipse.protobuf.ui.documentation.ProtobufDocumentationProvider;
 import com.google.eclipse.protobuf.ui.editor.ProtobufUriEditorOpener;
 import com.google.eclipse.protobuf.ui.editor.hyperlinking.ProtobufHyperlinkDetector;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/AutoAddNatureEditorCallback.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/nature/AutoAddNatureEditorCallback.java
similarity index 95%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/AutoAddNatureEditorCallback.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/nature/AutoAddNatureEditorCallback.java
index 88b0e7c..cdeffa0 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/AutoAddNatureEditorCallback.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/nature/AutoAddNatureEditorCallback.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.nature;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/CodeGenerationErrorParser.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/CodeGenerationErrorParser.java
similarity index 94%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/CodeGenerationErrorParser.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/CodeGenerationErrorParser.java
index 2237fce..7d1bdfa 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/CodeGenerationErrorParser.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/CodeGenerationErrorParser.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static java.util.regex.Pattern.compile;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/CompoundParser.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/CompoundParser.java
similarity index 94%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/CompoundParser.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/CompoundParser.java
index 1fa2de4..4a6d464 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/CompoundParser.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/CompoundParser.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static java.util.Arrays.asList;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/LineSpecificErrorParser.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/LineSpecificErrorParser.java
similarity index 95%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/LineSpecificErrorParser.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/LineSpecificErrorParser.java
index 49ea2cf..18745be 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/LineSpecificErrorParser.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/LineSpecificErrorParser.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static java.lang.Integer.parseInt;
 import static java.util.regex.Pattern.compile;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/OutputDirectories.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectories.java
similarity index 97%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/OutputDirectories.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectories.java
index 08ca941..3777932 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/OutputDirectories.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/OutputDirectories.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static com.google.eclipse.protobuf.ui.util.Paths.segmentsOf;
 import static java.io.File.separator;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtoDescriptorPathFinder.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtoDescriptorPathFinder.java
similarity index 95%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtoDescriptorPathFinder.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtoDescriptorPathFinder.java
index 30aa2c8..0a01887 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtoDescriptorPathFinder.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtoDescriptorPathFinder.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static java.io.File.separator;
 import static java.util.Arrays.asList;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtobufBuildParticipant.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtobufBuildParticipant.java
similarity index 97%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtobufBuildParticipant.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtobufBuildParticipant.java
index 8de58ae..7c7d5bb 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtobufBuildParticipant.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtobufBuildParticipant.java
@@ -6,9 +6,9 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
-import static com.google.eclipse.protobuf.ui.builder.OutputDirectories.findOrCreateOutputDirectories;
+import static com.google.eclipse.protobuf.ui.builder.protoc.OutputDirectories.findOrCreateOutputDirectories;
 import static com.google.eclipse.protobuf.ui.exception.CoreExceptions.error;
 import static com.google.eclipse.protobuf.ui.preferences.pages.compiler.PostCompilationRefreshTarget.PROJECT;
 import static com.google.eclipse.protobuf.ui.preferences.pages.paths.PathResolutionType.MULTIPLE_DIRECTORIES;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtocCommandFactory.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocCommandFactory.java
similarity index 96%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtocCommandFactory.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocCommandFactory.java
index 32ab772..f81bb1a 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtocCommandFactory.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocCommandFactory.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static com.google.eclipse.protobuf.util.CommonWords.space;
 
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtocMarkerFactory.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocMarkerFactory.java
similarity index 96%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtocMarkerFactory.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocMarkerFactory.java
index 5a5fe76..478bfcc 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtocMarkerFactory.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocMarkerFactory.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import static org.eclipse.core.resources.IMarker.*;
 import static org.eclipse.core.resources.IResource.DEPTH_INFINITE;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtocOutputParser.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocOutputParser.java
similarity index 91%
rename from com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtocOutputParser.java
rename to com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocOutputParser.java
index ee50aca..2fae3f1 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/ProtocOutputParser.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/builder/protoc/ProtocOutputParser.java
@@ -6,7 +6,7 @@
  *
  * http://www.eclipse.org/legal/epl-v10.html
  */
-package com.google.eclipse.protobuf.ui.builder;
+package com.google.eclipse.protobuf.ui.builder.protoc;
 
 import com.google.inject.ImplementedBy;
 
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/ProtobufRuntimeModule.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/ProtobufRuntimeModule.java
index 50bddd8..d6d73c0 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/ProtobufRuntimeModule.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/ProtobufRuntimeModule.java
@@ -1,9 +1,10 @@
 /*
  * 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
- *
+ * 
+ * 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;
@@ -12,10 +13,12 @@
 import org.eclipse.xtext.conversion.IValueConverterService;
 import org.eclipse.xtext.naming.IQualifiedNameProvider;
 import org.eclipse.xtext.parser.antlr.ISyntaxErrorMessageProvider;
-import org.eclipse.xtext.resource.IGlobalServiceProvider;
+import org.eclipse.xtext.resource.*;
 import org.eclipse.xtext.scoping.impl.ImportUriResolver;
+import org.eclipse.xtext.validation.IResourceValidator;
 
 import com.google.eclipse.protobuf.conversion.ProtobufTerminalConverters;
+import com.google.eclipse.protobuf.linking.ProtobufResource;
 import com.google.eclipse.protobuf.naming.ProtobufQualifiedNameProvider;
 import com.google.eclipse.protobuf.parser.Proto2OnlyParser;
 import com.google.eclipse.protobuf.resource.ResourceServiceProvider;
@@ -24,18 +27,19 @@
 import com.google.inject.Binder;
 
 /**
- * Use this class to register components to be used at runtime / without the Equinox extension registry.
+ * Use this class to register components to be used at runtime / without the
+ * Equinox extension registry.
  */
 public class ProtobufRuntimeModule extends com.google.eclipse.protobuf.AbstractProtobufRuntimeModule {
 
   public Class<? extends IGlobalServiceProvider> bindIGlobalServiceProvider() {
     return ResourceServiceProvider.class;
   }
-  
+
   public Class<? extends ImportUriResolver> bindImportUriResolver() {
     return ProtobufImportUriResolver.class;
   }
-  
+
   @Override public Class<? extends org.eclipse.xtext.parser.IParser> bindIParser() {
     return Proto2OnlyParser.class;
   }
@@ -44,14 +48,22 @@
     return ProtobufQualifiedNameProvider.class;
   }
 
+  public Class<? extends IResourceValidator> bindIResourceValidator() {
+    return ProtobufResourceValidator.class;
+  }
+
   public Class<? extends ISyntaxErrorMessageProvider> bindISyntaxErrorMessageProvider() {
     return ProtobufSyntaxErrorMessageProvider.class;
   }
-  
+
   @Override public Class<? extends IValueConverterService> bindIValueConverterService() {
     return ProtobufTerminalConverters.class;
   }
-  
+
+  @Override public Class<? extends XtextResource> bindXtextResource() {
+    return ProtobufResource.class;
+  }
+
   public void configureExtensionRegistry(Binder binder) {
     binder.bind(IExtensionRegistry.class).toProvider(ExtensionRegistryProvider.class);
   }
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/linking/ProtobufLinkingDiagnostic.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/linking/ProtobufLinkingDiagnostic.java
new file mode 100644
index 0000000..57a6ce1
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/linking/ProtobufLinkingDiagnostic.java
@@ -0,0 +1,81 @@
+/*
+ * 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.linking;
+
+import static java.util.Arrays.copyOf;
+import static org.eclipse.xtext.util.Arrays.contains;
+
+import org.eclipse.xtext.diagnostics.AbstractDiagnostic;
+import org.eclipse.xtext.nodemodel.INode;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProtobufLinkingDiagnostic extends AbstractDiagnostic {
+
+  private final String code;
+  private final String[] data;
+  private final StringBuilder message;
+  private final INode node;
+
+  public ProtobufLinkingDiagnostic(String code, String[] data, String message, INode node) {
+    if (contains(data, null)) {
+      throw new NullPointerException("data may not contain null");
+    }
+    if (node == null) throw new NullPointerException("node may not be null");
+    this.code = code;
+    this.data = copyOf(data, data.length);
+    this.message = new StringBuilder();
+    this.message.append(message);
+    this.node = node;
+  }
+
+  @Override public String getCode() {
+    return code;
+  }
+
+  @Override public String[] getData() {
+    return copyOf(data, data.length);
+  }
+
+  @Override public String getMessage() {
+    return message.toString();
+  }
+
+  @Override protected INode getNode() {
+    return node;
+  }
+
+  public void appendToMessage(String s) {
+    message.append(s);
+  }
+  
+  @Override public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + ((message == null) ? 0 : message.hashCode());
+    result = prime * result + ((node == null) ? 0 : node.hashCode());
+    return result;
+  }
+
+  @Override public boolean equals(Object obj) {
+    if (this == obj) return true;
+    if (obj == null) return false;
+    if (getClass() != obj.getClass()) return false;
+    ProtobufLinkingDiagnostic other = (ProtobufLinkingDiagnostic) obj;
+    if (message == null) {
+      if (other.message != null) return false;
+    } else if (!message.equals(other.message)) return false;
+    if (node == null) {
+      if (other.node != null) return false;
+    } else if (!node.equals(other.node)) return false;
+    return true;
+  }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/linking/ProtobufResource.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/linking/ProtobufResource.java
new file mode 100644
index 0000000..4a58eb0
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/linking/ProtobufResource.java
@@ -0,0 +1,27 @@
+/*
+ * 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.linking;
+
+import org.eclipse.emf.ecore.*;
+import org.eclipse.xtext.diagnostics.DiagnosticMessage;
+import org.eclipse.xtext.linking.lazy.LazyLinkingResource;
+import org.eclipse.xtext.nodemodel.INode;
+import org.eclipse.xtext.util.Triple;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProtobufResource extends LazyLinkingResource {
+
+  @Override protected Diagnostic createDiagnostic(Triple<EObject, EReference, INode> t, DiagnosticMessage message) {
+    INode node = t.getThird();
+    return new ProtobufLinkingDiagnostic(message.getIssueCode(), message.getIssueData(), message.getMessage(), node);
+  }
+}
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
new file mode 100644
index 0000000..b161765
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ImportValidator.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.validation;
+
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
+import static com.google.eclipse.protobuf.validation.Messages.importingNonProto2;
+
+import com.google.eclipse.protobuf.model.util.*;
+import com.google.eclipse.protobuf.parser.NonProto2;
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.inject.Inject;
+
+import org.eclipse.emf.ecore.resource.*;
+import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
+import org.eclipse.xtext.validation.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ImportValidator extends AbstractDeclarativeValidator {
+
+  @Inject private ModelFinder finder;
+  @Inject private Resources resources;
+
+  @Override public void register(EValidatorRegistrar registrar) {}
+
+  @Check
+  public void checkNonProto2Imports(Protobuf root) {
+    warnIfNonProto2ImportsFound(root.eResource());
+  }
+
+  private void warnIfNonProto2ImportsFound(Resource resource) {
+    Protobuf root = finder.rootOf(resource);
+    if (isNotProto2(root)) return;
+    ResourceSet resourceSet = resource.getResourceSet();
+    for (Import anImport : finder.importsIn(root)) {
+      Resource imported = resources.importedResource(anImport, resourceSet);
+      if (isNotProto2(finder.rootOf(imported))) {
+        acceptWarning(importingNonProto2, anImport, IMPORT__IMPORT_URI, INSIGNIFICANT_INDEX, null);
+        continue;
+      }
+      for (Diagnostic d : imported.getWarnings()) {
+        if (importingNonProto2.equals(d.getMessage())) {
+          acceptWarning(importingNonProto2, anImport, IMPORT__IMPORT_URI, INSIGNIFICANT_INDEX, null);
+        }
+      }
+    }
+  }
+  
+  private boolean isNotProto2(Protobuf root) {
+    return root instanceof NonProto2;
+  }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties
index c84ff3f..1faeb4b 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/Messages.properties
@@ -5,7 +5,7 @@
 expectedTrueOrFalse = Expected "true" or "false".
 fieldNumberAlreadyUsed = Field number %d has already been used in \"%s\" by field \"%s\".
 fieldNumbersMustBePositive = Field numbers must be positive integers.
-importingNonProto2 = Importing non-proto2 file. This may result in errors related to unresolved references.
+importingNonProto2 = Importing non-proto2 file (directly or indirectly.) This may result in errors related to unresolved references.
 importNotFound = Import \"%s\" was not found.
 missingFieldNumber = Missing field number.
 multiplePackages = Multiple package definitions.
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 ca2221d..a15d70c 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,22 +13,22 @@
 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.emf.ecore.resource.*;
-import org.eclipse.xtext.naming.*;
-import org.eclipse.xtext.scoping.impl.ImportUriResolver;
-import org.eclipse.xtext.validation.Check;
-
 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.*;
+
 /**
  * @author alruiz@google.com (Alex Ruiz)
  */
+@ComposedChecks(validators = { ImportValidator.class })
 public class ProtobufJavaValidator extends AbstractProtobufJavaValidator {
 
   public static final String SYNTAX_IS_NOT_PROTO2_ERROR = "syntaxIsNotProto2";
@@ -36,11 +36,9 @@
   public static final String MORE_THAN_ONE_PACKAGE_ERROR = "moreThanOnePackage";
 
   @Inject private FieldOptions fieldOptions;
-  @Inject private ModelFinder finder;
   @Inject private ImportUriResolver uriResolver;
   @Inject private IQualifiedNameProvider qualifiedNameProvider;
   @Inject private Properties properties;
-  @Inject private Resources resources;
 
   @Check public void checkIsProto2(Protobuf protobuf) {
     if (protobuf instanceof NonProto2) {
@@ -62,25 +60,6 @@
     }
   }
   
-  @Check public void checkIsImportingNonProto2File(Import anImport) {
-    if (!retryUntilItIsResolved(anImport)) return;
-    Resource imported = importedResource(anImport);
-    Protobuf root = finder.rootOf(imported);
-    if (root instanceof NonProto2) {
-      warning(importingNonProto2, IMPORT__IMPORT_URI);
-    }
-  }
-  
-  private Resource importedResource(Import anImport) {
-    ResourceSet resourceSet = resourceSet(anImport);
-    return resources.importedResource(anImport, resourceSet);
-  }
-  
-  private ResourceSet resourceSet(EObject e) {
-    Protobuf root = finder.rootOf(e);
-    return root.eResource().getResourceSet();
-  }
-
   @Check public void checkImportIsResolved(Import anImport) {
     if (retryUntilItIsResolved(anImport)) return;
     error(format(importNotFound, anImport.getImportURI()), IMPORT__IMPORT_URI);
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufResourceValidator.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufResourceValidator.java
new file mode 100644
index 0000000..4a2ef0b
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ProtobufResourceValidator.java
@@ -0,0 +1,108 @@
+/*
+ * 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.validation;
+
+import static com.google.common.collect.Lists.newArrayListWithExpectedSize;
+import static com.google.common.collect.Maps.newHashMap;
+import static com.google.eclipse.protobuf.validation.Messages.importingNonProto2;
+import static org.eclipse.xtext.diagnostics.Severity.*;
+import static org.eclipse.xtext.validation.AbstractInjectableValidator.CURRENT_LANGUAGE_NAME;
+import static org.eclipse.xtext.validation.CancelableDiagnostician.CANCEL_INDICATOR;
+import static org.eclipse.xtext.validation.CheckMode.KEY;
+import static org.eclipse.xtext.validation.CheckType.FAST;
+import static org.eclipse.xtext.validation.impl.ConcreteSyntaxEValidator.DISABLE_CONCRETE_SYNTAX_EVALIDATOR;
+
+import com.google.eclipse.protobuf.linking.ProtobufLinkingDiagnostic;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.ecore.*;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.xtext.diagnostics.Severity;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.util.*;
+import org.eclipse.xtext.validation.*;
+
+import java.util.*;
+
+/**
+ * Adds support for converting scoping errors into warnings if non-proto2 files are imported.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProtobufResourceValidator extends ResourceValidatorImpl {
+
+  private static final Logger log = Logger.getLogger(ProtobufResourceValidator.class);
+  
+  @Override public List<Issue> validate(Resource resource, CheckMode mode, CancelIndicator indicator) {
+    CancelIndicator monitor = indicator == null ? CancelIndicator.NullImpl : indicator;
+    resolveProxies(resource, monitor);
+    if (monitor.isCanceled()) return null;
+    List<Issue> result = newArrayListWithExpectedSize(resource.getErrors().size() + resource.getWarnings().size());
+    try {
+      IAcceptor<Issue> acceptor = createAcceptor(result);
+      boolean hasNonProto2Import = false;
+      for (EObject element : resource.getContents()) {
+        try {
+          if (monitor.isCanceled()) return null;
+          Diagnostic diagnostic = getDiagnostician().validate(element, validationOptions(resource, mode, monitor));
+          if (!diagnostic.getChildren().isEmpty()) {
+            for (Diagnostic child : diagnostic.getChildren()) {
+              if (importingNonProto2.equals(child.getMessage())) hasNonProto2Import = true;
+              issueFromEValidatorDiagnostic(child, acceptor);
+            }
+          } else {
+            issueFromEValidatorDiagnostic(diagnostic, acceptor);
+          }
+        } catch (RuntimeException e) {
+          log.error(e.getMessage(), e);
+        }
+      }
+      if (mode.shouldCheck(FAST)) {
+        for (Resource.Diagnostic error : resource.getErrors()) {
+          if (monitor.isCanceled()) return null;
+          Severity severity = ERROR;
+          if (hasNonProto2Import && isUnresolveReferenceError(error)) {
+            severity = WARNING;
+            ProtobufLinkingDiagnostic d = (ProtobufLinkingDiagnostic) error;
+            if (!d.getMessage().endsWith(".")) d.appendToMessage(".");
+            d.appendToMessage(" It may be caused by a non-proto2 file imported directly or indirectly.");
+          }
+          issueFromXtextResourceDiagnostic(error, severity, acceptor);
+        }
+        for (Resource.Diagnostic warning : resource.getWarnings()) {
+          if (monitor.isCanceled()) return null;
+          issueFromXtextResourceDiagnostic(warning, WARNING, acceptor);
+        }
+      }
+    } catch (RuntimeException e) {
+      log.error(e.getMessage(), e);
+    }
+    return result;
+  }
+
+  private Map<Object, Object> validationOptions(Resource resource, CheckMode mode, CancelIndicator monitor) {
+    Map<Object, Object> options = newHashMap();
+    options.put(KEY, mode);
+    options.put(CANCEL_INDICATOR, monitor);
+    options.put(DISABLE_CONCRETE_SYNTAX_EVALIDATOR, true);
+    options.put(EValidator.class, getDiagnostician());
+    if (resource instanceof XtextResource) {
+      options.put(CURRENT_LANGUAGE_NAME, ((XtextResource) resource).getLanguageName());
+    }
+    return options;
+  }
+
+  private boolean isUnresolveReferenceError(Resource.Diagnostic error) {
+    if (!(error instanceof ProtobufLinkingDiagnostic)) return false;
+    ProtobufLinkingDiagnostic d = (ProtobufLinkingDiagnostic) error;
+    if (!"org.eclipse.xtext.diagnostics.Diagnostic.Linking".equals(d.getCode())) return false;
+    return error.getMessage().startsWith("Couldn't resolve");
+  }
+}