Added -SourceLevel auto to match runtime vm spec version.

Also -SourceLevel auto is now the default, otherwise devmode
would choke on class files it itself compiled.

Change-Id: Ife59a3f5137f0cdd51a9acae99aea4d3a5eae837
(cherry picked from commit 8c5e655445b7bfc60b06f277640f98d7b565eae6)
diff --git a/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java b/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
index 23ef7a3..e174f68 100644
--- a/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
+++ b/dev/codeserver/java/com/google/gwt/dev/codeserver/Options.java
@@ -17,8 +17,8 @@
 package com.google.gwt.dev.codeserver;
 
 import com.google.gwt.dev.ArgProcessorBase;
-import com.google.gwt.dev.util.arg.ArgHandlerSource;
-import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.dev.util.arg.ArgHandlerSourceLevel;
+import com.google.gwt.dev.util.arg.OptionSourceLevel;
 import com.google.gwt.dev.util.arg.SourceLevel;
 import com.google.gwt.util.tools.ArgHandler;
 import com.google.gwt.util.tools.ArgHandlerDir;
@@ -175,7 +175,7 @@
       registerHandler(new SourceFlag());
       registerHandler(new ModuleNameArgument());
       registerHandler(new StrictResourcesFlag());
-      registerHandler(new ArgHandlerSource(new OptionSource() {
+      registerHandler(new ArgHandlerSourceLevel(new OptionSourceLevel() {
         @Override
         public SourceLevel getSourceLevel() {
           return sourceLevel;
diff --git a/dev/core/src/com/google/gwt/dev/CompileModule.java b/dev/core/src/com/google/gwt/dev/CompileModule.java
index 3b322f9..d242952 100644
--- a/dev/core/src/com/google/gwt/dev/CompileModule.java
+++ b/dev/core/src/com/google/gwt/dev/CompileModule.java
@@ -29,7 +29,7 @@
 import com.google.gwt.dev.util.arg.ArgHandlerLogLevel;
 import com.google.gwt.dev.util.arg.ArgHandlerModuleName;
 import com.google.gwt.dev.util.arg.ArgHandlerOutDir;
-import com.google.gwt.dev.util.arg.ArgHandlerSource;
+import com.google.gwt.dev.util.arg.ArgHandlerSourceLevel;
 import com.google.gwt.dev.util.arg.ArgHandlerStrict;
 import com.google.gwt.dev.util.arg.SourceLevel;
 import com.google.gwt.dev.util.log.speedtracer.CompilerEventType;
@@ -91,7 +91,7 @@
         }
       });
       registerHandler(new ArgHandlerModuleName(options));
-      registerHandler(new ArgHandlerSource(options));
+      registerHandler(new ArgHandlerSourceLevel(options));
       registerHandler(new ArgHandlerStrict(options));
     }
 
diff --git a/dev/core/src/com/google/gwt/dev/CompileModuleOptions.java b/dev/core/src/com/google/gwt/dev/CompileModuleOptions.java
index c0d6e90..08f8715 100644
--- a/dev/core/src/com/google/gwt/dev/CompileModuleOptions.java
+++ b/dev/core/src/com/google/gwt/dev/CompileModuleOptions.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2012 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -16,12 +16,12 @@
 package com.google.gwt.dev;
 
 import com.google.gwt.dev.util.arg.OptionOutDir;
-import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.dev.util.arg.OptionSourceLevel;
 import com.google.gwt.dev.util.arg.OptionStrict;
 
 /**
  * The complete set of options for {@link CompileModule}.
  */
 public interface CompileModuleOptions extends CompileTaskOptions, OptionOutDir, OptionStrict,
-    OptionSource {
+    OptionSourceLevel {
 }
diff --git a/dev/core/src/com/google/gwt/dev/DevMode.java b/dev/core/src/com/google/gwt/dev/DevMode.java
index 3716303..f3c955e 100644
--- a/dev/core/src/com/google/gwt/dev/DevMode.java
+++ b/dev/core/src/com/google/gwt/dev/DevMode.java
@@ -36,7 +36,7 @@
 import com.google.gwt.dev.util.arg.ArgHandlerDisableUpdateCheck;
 import com.google.gwt.dev.util.arg.ArgHandlerExtraDir;
 import com.google.gwt.dev.util.arg.ArgHandlerModuleName;
-import com.google.gwt.dev.util.arg.ArgHandlerSource;
+import com.google.gwt.dev.util.arg.ArgHandlerSourceLevel;
 import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
 import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
@@ -183,7 +183,7 @@
       registerHandler(new ArgHandlerExtraDir(options));
       registerHandler(new ArgHandlerWorkDirOptional(options));
       registerHandler(new ArgHandlerDisableUpdateCheck(options));
-      registerHandler(new ArgHandlerSource(options));
+      registerHandler(new ArgHandlerSourceLevel(options));
       registerHandler(new ArgHandlerModuleName(options) {
         @Override
         public String getPurpose() {
diff --git a/dev/core/src/com/google/gwt/dev/PrecompileTaskArgProcessor.java b/dev/core/src/com/google/gwt/dev/PrecompileTaskArgProcessor.java
index 0e2e836..750a194 100644
--- a/dev/core/src/com/google/gwt/dev/PrecompileTaskArgProcessor.java
+++ b/dev/core/src/com/google/gwt/dev/PrecompileTaskArgProcessor.java
@@ -41,7 +41,7 @@
 import com.google.gwt.dev.util.arg.ArgHandlerOptimize;
 import com.google.gwt.dev.util.arg.ArgHandlerSaveSource;
 import com.google.gwt.dev.util.arg.ArgHandlerScriptStyle;
-import com.google.gwt.dev.util.arg.ArgHandlerSource;
+import com.google.gwt.dev.util.arg.ArgHandlerSourceLevel;
 import com.google.gwt.dev.util.arg.ArgHandlerSoyc;
 import com.google.gwt.dev.util.arg.ArgHandlerSoycDetailed;
 import com.google.gwt.dev.util.arg.ArgHandlerStrict;
@@ -81,7 +81,7 @@
     registerHandler(new ArgHandlerStrict(options));
     registerHandler(new ArgHandlerStrictResources(options));
     registerHandler(new ArgHandlerValidateOnlyFlag(options));
-    registerHandler(new ArgHandlerSource(options));
+    registerHandler(new ArgHandlerSourceLevel(options));
   }
 
   @Override
diff --git a/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
index 8c28899..e5800f6 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/JJSOptions.java
@@ -31,7 +31,7 @@
 import com.google.gwt.dev.util.arg.OptionRemoveDuplicateFunctions;
 import com.google.gwt.dev.util.arg.OptionRunAsyncEnabled;
 import com.google.gwt.dev.util.arg.OptionScriptStyle;
-import com.google.gwt.dev.util.arg.OptionSource;
+import com.google.gwt.dev.util.arg.OptionSourceLevel;
 import com.google.gwt.dev.util.arg.OptionSoycDetailed;
 import com.google.gwt.dev.util.arg.OptionSoycEnabled;
 import com.google.gwt.dev.util.arg.OptionSoycHtmlDisabled;
@@ -47,5 +47,5 @@
     OptionRunAsyncEnabled, OptionScriptStyle, OptionSoycEnabled, OptionSoycDetailed,
     OptionOptimizePrecompile, OptionOrdinalizeEnums, OptionRemoveDuplicateFunctions, OptionStrict,
     OptionStrictResources, OptionSoycHtmlDisabled, OptionEnableClosureCompiler,
-    OptionFragmentsMerge, OptionFragmentCount, OptionSource {
+    OptionFragmentsMerge, OptionFragmentCount, OptionSourceLevel {
 }
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSource.java b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSourceLevel.java
similarity index 65%
rename from dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSource.java
rename to dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSourceLevel.java
index 0344448..cff6e98 100644
--- a/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSource.java
+++ b/dev/core/src/com/google/gwt/dev/util/arg/ArgHandlerSourceLevel.java
@@ -21,21 +21,23 @@
 /**
  * Set the Java source level compatibility.
  */
-public class ArgHandlerSource extends ArgHandlerString {
-  private final OptionSource options;
+public class ArgHandlerSourceLevel extends ArgHandlerString {
+  private static final String AUTO_SELECT = "auto";
+  private final OptionSourceLevel options;
 
-  public ArgHandlerSource(OptionSource options) {
+  public ArgHandlerSourceLevel(OptionSourceLevel options) {
     this.options = options;
   }
 
   @Override
   public String[] getDefaultArgs() {
-    return new String[]{getTag(), SourceLevel.DEFAULT_SOURCE_LEVEL.getStringValue()};
+    return new String[]{getTag(), AUTO_SELECT};
   }
 
   @Override
   public String getPurpose() {
-    return "Specifies Java source level (defaults to " + SourceLevel.DEFAULT_SOURCE_LEVEL + ")";
+    return "Specifies Java source level (defaults to " + AUTO_SELECT + ":" +
+        SourceLevel.DEFAULT_SOURCE_LEVEL + ")";
   }
 
   @Override
@@ -45,18 +47,22 @@
 
   @Override
   public String[] getTagArgs() {
-    return new String[]{"[" + Joiner.on(",").join(SourceLevel.values()) + "]"};
+    return new String[]{"[" + AUTO_SELECT + "," + Joiner.on(",").join(SourceLevel.values()) + "]"};
   }
 
   @Override
   public boolean setString(String value) {
+    if (value.equals(AUTO_SELECT)) {
+      options.setSourceLevel(SourceLevel.DEFAULT_SOURCE_LEVEL);
+      return true;
+    }
     SourceLevel level = SourceLevel.fromString(value);
     if (value == null) {
-      System.err.println("Source level must be one of [" +
+      System.err.println("Source level must be one of [" + AUTO_SELECT +
           Joiner.on(",").join(SourceLevel.values()) + "].");
       return false;
     }
     options.setSourceLevel(level);
     return true;
   }
-}
+}
\ No newline at end of file
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/OptionSource.java b/dev/core/src/com/google/gwt/dev/util/arg/OptionSourceLevel.java
similarity index 95%
rename from dev/core/src/com/google/gwt/dev/util/arg/OptionSource.java
rename to dev/core/src/com/google/gwt/dev/util/arg/OptionSourceLevel.java
index d57c7e7..7f23c5a 100644
--- a/dev/core/src/com/google/gwt/dev/util/arg/OptionSource.java
+++ b/dev/core/src/com/google/gwt/dev/util/arg/OptionSourceLevel.java
@@ -18,7 +18,7 @@
 /**
  * An option that can indicates the Java source level compatibility.
  */
-public interface OptionSource {
+public interface OptionSourceLevel {
 
   SourceLevel getSourceLevel();
 
diff --git a/dev/core/src/com/google/gwt/dev/util/arg/SourceLevel.java b/dev/core/src/com/google/gwt/dev/util/arg/SourceLevel.java
index 2b8796a..7c82554 100644
--- a/dev/core/src/com/google/gwt/dev/util/arg/SourceLevel.java
+++ b/dev/core/src/com/google/gwt/dev/util/arg/SourceLevel.java
@@ -15,22 +15,24 @@
  */
 package com.google.gwt.dev.util.arg;
 
+import com.google.gwt.thirdparty.guava.common.annotations.VisibleForTesting;
+import com.google.gwt.util.tools.Utility;
+
 /**
- * Java source level compatibility constants.
- * Java versions range from 1.0 to 1.7.
- * Versions 1.5, 1.6 and 1.7 are also referred as 5, 6 and 7 respectively.
+ * Java source level compatibility constants. Java versions range from 1.0 to 1.7. Versions 1.6 and
+ * 1.7 are also referred as 6 and 7 respectively.
  *
  * Both names can be used indistinctly.
  */
 public enum SourceLevel {
-  // Source levels must appear in ascending order in order.
+  // Source levels must appear in ascending order for the default setting logic to work.
   JAVA6("1.6", "6"),
   JAVA7("1.7", "7");
 
   /**
    * The default java sourceLevel.
    */
-  public static final SourceLevel DEFAULT_SOURCE_LEVEL = JAVA7;
+  public static final SourceLevel DEFAULT_SOURCE_LEVEL = getJvmBestMatchingSourceLevel();
 
   private final String stringValue;
   private final String altStringValue;
@@ -60,8 +62,8 @@
   }
 
   /**
-   * Returns the SourceLevel given the string or alternate string representation;
-   * returns {@code null} if none is found.
+   * Returns the SourceLevel given the string or alternate string representation; returns {@code
+   * null} if none is found.
    */
   public static SourceLevel fromString(String sourceLevelString) {
     if (sourceLevelString == null) {
@@ -76,4 +78,29 @@
     return null;
   }
 
+  private static SourceLevel getJvmBestMatchingSourceLevel() {
+    // If everything fails set default to JAVA7.
+    String javaSpecLevel = System.getProperty("java.specification.version");
+    return getBestMatchingVersion(javaSpecLevel);
+  }
+
+  @VisibleForTesting
+  public static SourceLevel getBestMatchingVersion(String javaVersionString) {
+    try {
+      // Find the first version that is less than or equal to javaSpecLevel by iterating in reverse
+      // order.
+      SourceLevel[] sourceLevels = SourceLevel.values();
+      for (int i = sourceLevels.length - 1; i >= 0; i--) {
+        if (Utility.versionCompare(javaVersionString, sourceLevels[i].stringValue) >= 0) {
+          // sourceLevel is <= javaSpecLevel, so keep this one.
+          return sourceLevels[i];
+        }
+      }
+    } catch (IllegalArgumentException e) {
+      // If the version can not be parsed fallback to JAVA7.
+    }
+    // If everything fails set default to JAVA7.
+    return JAVA7;
+  }
 }
+
diff --git a/dev/core/test/com/google/gwt/dev/CompilerTest.java b/dev/core/test/com/google/gwt/dev/CompilerTest.java
index e3100dd..643ecf3 100644
--- a/dev/core/test/com/google/gwt/dev/CompilerTest.java
+++ b/dev/core/test/com/google/gwt/dev/CompilerTest.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2009 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -18,6 +18,7 @@
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.dev.jjs.JsOutputOption;
 import com.google.gwt.dev.util.arg.SourceLevel;
+import com.google.gwt.util.tools.Utility;
 
 import java.io.File;
 
@@ -92,4 +93,34 @@
     assertProcessFailure(argProcessor, "-sourceLevel", "ssss");
     assertProcessFailure(argProcessor, "-sourceLevel", "1.5");
   }
+
+  /**
+   * Tests ordering for emum {@link SourceLevel}.
+   */
+  public void testSourceLevelOrdering() {
+    SourceLevel[] sourceLevels = SourceLevel.values();
+    SourceLevel previousSourceLevel = sourceLevels[0];
+    for (int i = 1; i < sourceLevels.length; i++) {
+      assertTrue(Utility.versionCompare(previousSourceLevel.getStringValue(),
+          sourceLevels[i].getStringValue()) < 0);
+      previousSourceLevel = sourceLevels[i];
+    }
+  }
+
+  public void testSourceLevelSelection() {
+    // We are not able to compile to less that Java 6 so, we might as well do Java7 on
+    // these cases.
+    assertEquals(SourceLevel.JAVA7, SourceLevel.getBestMatchingVersion("1.4"));
+    assertEquals(SourceLevel.JAVA7, SourceLevel.getBestMatchingVersion("1.5"));
+
+    assertEquals(SourceLevel.JAVA6, SourceLevel.getBestMatchingVersion("1.6"));
+    assertEquals(SourceLevel.JAVA6, SourceLevel.getBestMatchingVersion("1.6_26"));
+    assertEquals(SourceLevel.JAVA7, SourceLevel.getBestMatchingVersion("1.7"));
+    assertEquals(SourceLevel.JAVA7, SourceLevel.getBestMatchingVersion("1.8"));
+
+    // not proper version strings => default to JAVA7.
+    assertEquals(SourceLevel.JAVA7, SourceLevel.getBestMatchingVersion("1.6u3"));
+    assertEquals(SourceLevel.JAVA7, SourceLevel.getBestMatchingVersion("1.6b3"));
+    assertEquals(SourceLevel.JAVA7, SourceLevel.getBestMatchingVersion("1.7b3"));
+  }
 }
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index ffcfe98..c4c2bcd 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -57,7 +57,7 @@
 import com.google.gwt.dev.util.arg.ArgHandlerMaxPermsPerPrecompile;
 import com.google.gwt.dev.util.arg.ArgHandlerOptimize;
 import com.google.gwt.dev.util.arg.ArgHandlerScriptStyle;
-import com.google.gwt.dev.util.arg.ArgHandlerSource;
+import com.google.gwt.dev.util.arg.ArgHandlerSourceLevel;
 import com.google.gwt.dev.util.arg.ArgHandlerWarDir;
 import com.google.gwt.dev.util.arg.ArgHandlerWorkDirOptional;
 import com.google.gwt.junit.JUnitMessageQueue.ClientStatus;
@@ -291,7 +291,7 @@
       registerHandler(new ArgHandlerDeployDir(options));
       registerHandler(new ArgHandlerExtraDir(options));
       registerHandler(new ArgHandlerWorkDirOptional(options));
-      registerHandler(new ArgHandlerSource(options));
+      registerHandler(new ArgHandlerSourceLevel(options));
 
       // DISABLE: ArgHandlerModuleName