Add support for converting to and from Intellij project views

With that change, we just need to add the necessary UI to call those
action to be able to solve #44.

This also add the necessary plumbing for #25 but it is also missing the
necessary UI.

Change-Id: I12adc3ef9036c559ebdcc5d16e3e6a450e543b5f
diff --git a/java/com/google/devtools/bazel/e4b/Activator.java b/java/com/google/devtools/bazel/e4b/Activator.java
index 5e8bc37..c47cd68 100644
--- a/java/com/google/devtools/bazel/e4b/Activator.java
+++ b/java/com/google/devtools/bazel/e4b/Activator.java
@@ -14,25 +14,13 @@
 
 package com.google.devtools.bazel.e4b;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.List;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.ProjectScope;
 import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.preferences.IScopeContext;
 import org.eclipse.jface.util.IPropertyChangeListener;
 import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
-import org.osgi.service.prefs.BackingStoreException;
-import org.osgi.service.prefs.Preferences;
 
-import com.google.common.collect.ImmutableList;
 import com.google.devtools.bazel.e4b.command.BazelCommand;
-import com.google.devtools.bazel.e4b.command.BazelCommand.BazelInstance;
-import com.google.devtools.bazel.e4b.command.BazelNotFoundException;
 
 /**
  * The activator class controls the plug-in life cycle
@@ -102,40 +90,6 @@
     return command;
   }
 
-
-  /**
-   * List targets configure for <code>project</code>. Each project configured for Bazel is
-   * configured to track certain targets and this function fetch this list from the project
-   * preferences.
-   */
-  public static List<String> getTargets(IProject project) throws BackingStoreException {
-    // Get the list of targets from the preferences
-    IScopeContext projectScope = new ProjectScope(project);
-    Preferences projectNode = projectScope.getNode(PLUGIN_ID);
-    ImmutableList.Builder<String> builder = ImmutableList.builder();
-    for (String s : projectNode.keys()) {
-      if (s.startsWith("target")) {
-        builder.add(projectNode.get(s, ""));
-      }
-    }
-    return builder.build();
-  }
-
-  /**
-   * Return the {@link BazelInstance} corresponding to the given <code>project</code>. It looks for
-   * the instance that runs for the workspace root configured for that project.
-   * 
-   * @throws BazelNotFoundException
-   */
-  public static BazelCommand.BazelInstance getBazelCommandInstance(IProject project)
-      throws BackingStoreException, IOException, InterruptedException, BazelNotFoundException {
-    IScopeContext projectScope = new ProjectScope(project.getProject());
-    Preferences projectNode = projectScope.getNode(Activator.PLUGIN_ID);
-    File workspaceRoot =
-        new File(projectNode.get("workspaceRoot", project.getLocation().toFile().toString()));
-    return getDefault().getCommand().getInstance(workspaceRoot);
-  }
-
   /**
    * Log an error to eclipse.
    */
diff --git a/java/com/google/devtools/bazel/e4b/BazelProjectSupport.java b/java/com/google/devtools/bazel/e4b/BazelProjectSupport.java
new file mode 100644
index 0000000..a855c8e
--- /dev/null
+++ b/java/com/google/devtools/bazel/e4b/BazelProjectSupport.java
@@ -0,0 +1,255 @@
+// Copyright 2016 The Bazel Authors. All rights reserved.
+//
+// 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 License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.bazel.e4b;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.eclipse.core.resources.ICommand;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IProjectDescription;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ProjectScope;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.preferences.IScopeContext;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.bazel.e4b.classpath.BazelClasspathContainer;
+import com.google.devtools.bazel.e4b.command.BazelCommand;
+import com.google.devtools.bazel.e4b.command.BazelCommand.BazelInstance;
+import com.google.devtools.bazel.e4b.command.BazelNotFoundException;
+import com.google.devtools.bazel.e4b.projectviews.ProjectView;
+
+/**
+ * A utility class to create e4b projects.
+ */
+public class BazelProjectSupport {
+
+  private static final String STANDARD_VM_CONTAINER_PREFIX =
+      "org.eclipse.jdt.launching.JRE_CONTAINER/"
+          + "org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.";
+
+  /**
+   * Create a e4b project. This method adds the natures to the project, saves the list of targets
+   * and the workspace root to the project settings, make Bazel the default builder instead of ECJ
+   * and create the classpath using ide build informations from Bazel.
+   */
+  public static IProject createProject(String projectName, URI location, String workspaceRoot,
+      List<String> paths, List<String> targets, int javaLanguageVersion) {
+
+    IProject project = createBaseProject(projectName, location);
+    try {
+      addNature(project, ProjectNature.NATURE_ID);
+      addNature(project, JavaCore.NATURE_ID);
+      addSettings(project, workspaceRoot, targets, ImmutableList.of());
+      setBuilders(project);
+      createClasspath(new Path(workspaceRoot), paths, JavaCore.create(project),
+          javaLanguageVersion);
+    } catch (CoreException e) {
+      e.printStackTrace();
+      project = null;
+    } catch (BackingStoreException e) {
+      e.printStackTrace();
+      project = null;
+    }
+
+    return project;
+  }
+
+  private static void addSettings(IProject project, String workspaceRoot, List<String> targets,
+      List<String> buildFlags) throws BackingStoreException {
+    IScopeContext projectScope = new ProjectScope(project);
+    Preferences projectNode = projectScope.getNode(Activator.PLUGIN_ID);
+    int i = 0;
+    for (String target : targets) {
+      projectNode.put("target" + i, target);
+      i++;
+    }
+    projectNode.put("workspaceRoot", workspaceRoot);
+    i = 0;
+    for (String flag : buildFlags) {
+      projectNode.put("buildFlag" + i, flag);
+      i++;
+    }
+    projectNode.flush();
+  }
+
+  private static void setBuilders(IProject project) throws CoreException {
+    IProjectDescription description = project.getDescription();
+    final ICommand buildCommand = description.newCommand();
+    buildCommand.setBuilderName("com.google.devtools.bazel.e4b.builder");
+    description.setBuildSpec(new ICommand[] {buildCommand});
+    project.setDescription(description, null);
+  }
+
+  private static void createClasspath(IPath root, List<String> paths, IJavaProject javaProject,
+      int javaLanguageLevel) throws CoreException {
+    String name = root.lastSegment();
+    IFolder base = javaProject.getProject().getFolder(name);
+    if (!base.isLinked()) {
+      base.createLink(root, IResource.NONE, null);
+    }
+    List<IClasspathEntry> list = new LinkedList<>();
+    for (String path : paths) {
+      IPath workspacePath = base.getFullPath().append(path);
+      list.add(JavaCore.newSourceEntry(workspacePath));
+    }
+    list.add(JavaCore.newContainerEntry(new Path(BazelClasspathContainer.CONTAINER_NAME)));
+
+    list.add(
+        JavaCore.newContainerEntry(new Path(STANDARD_VM_CONTAINER_PREFIX + javaLanguageLevel)));
+    IClasspathEntry[] newClasspath = list.toArray(new IClasspathEntry[0]);
+    javaProject.setRawClasspath(newClasspath, null);
+  }
+
+  private static IProject createBaseProject(String projectName, URI location) {
+    IProject newProject = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
+
+    if (!newProject.exists()) {
+      URI projectLocation = location;
+      IProjectDescription desc =
+          newProject.getWorkspace().newProjectDescription(newProject.getName());
+      if (location != null
+          && ResourcesPlugin.getWorkspace().getRoot().getLocationURI().equals(location)) {
+        projectLocation = null;
+      }
+
+      desc.setLocationURI(projectLocation);
+      try {
+        newProject.create(desc, null);
+        if (!newProject.isOpen()) {
+          newProject.open(null);
+        }
+      } catch (CoreException e) {
+        e.printStackTrace();
+      }
+    }
+
+    return newProject;
+  }
+
+  private static void addNature(IProject project, String nature) throws CoreException {
+    if (!project.hasNature(nature)) {
+      IProjectDescription description = project.getDescription();
+      String[] prevNatures = description.getNatureIds();
+      String[] newNatures = new String[prevNatures.length + 1];
+      System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
+      newNatures[prevNatures.length] = nature;
+      description.setNatureIds(newNatures);
+
+      project.setDescription(description, null);
+    }
+  }
+
+  /**
+   * List targets configure for <code>project</code>. Each project configured for Bazel is
+   * configured to track certain targets and this function fetch this list from the project
+   * preferences.
+   */
+  public static List<String> getTargets(IProject project) throws BackingStoreException {
+    // Get the list of targets from the preferences
+    IScopeContext projectScope = new ProjectScope(project);
+    Preferences projectNode = projectScope.getNode(Activator.PLUGIN_ID);
+    ImmutableList.Builder<String> builder = ImmutableList.builder();
+    for (String s : projectNode.keys()) {
+      if (s.startsWith("target")) {
+        builder.add(projectNode.get(s, ""));
+      }
+    }
+    return builder.build();
+  }
+
+  /**
+   * List of build flags for <code>project</code>, taken from the project configuration
+   */
+  public static List<String> getBuildFlags(IProject project) throws BackingStoreException {
+    // Get the list of targets from the preferences
+    IScopeContext projectScope = new ProjectScope(project);
+    Preferences projectNode = projectScope.getNode(Activator.PLUGIN_ID);
+    ImmutableList.Builder<String> builder = ImmutableList.builder();
+    for (String s : projectNode.keys()) {
+      if (s.startsWith("buildArgs")) {
+        builder.add(projectNode.get(s, ""));
+      }
+    }
+    return builder.build();
+  }
+
+  /**
+   * Return the {@link BazelInstance} corresponding to the given <code>project</code>. It looks for
+   * the instance that runs for the workspace root configured for that project.
+   *
+   * @throws BazelNotFoundException
+   */
+  public static BazelCommand.BazelInstance getBazelCommandInstance(IProject project)
+      throws BackingStoreException, IOException, InterruptedException, BazelNotFoundException {
+    IScopeContext projectScope = new ProjectScope(project.getProject());
+    Preferences projectNode = projectScope.getNode(Activator.PLUGIN_ID);
+    File workspaceRoot =
+        new File(projectNode.get("workspaceRoot", project.getLocation().toFile().toString()));
+    return Activator.getDefault().getCommand().getInstance(workspaceRoot);
+  }
+
+  /**
+   * Convert an Eclipse JDT project into an IntelliJ project view
+   */
+  public static ProjectView getProjectView(IProject project)
+      throws BackingStoreException, JavaModelException {
+    com.google.devtools.bazel.e4b.projectviews.Builder builder = ProjectView.builder();
+    IScopeContext projectScope = new ProjectScope(project);
+    Preferences projectNode = projectScope.getNode(Activator.PLUGIN_ID);
+    for (String s : projectNode.keys()) {
+      if (s.startsWith("buildArgs")) {
+        builder.addBuildFlag(projectNode.get(s, ""));
+      } else if (s.startsWith("target")) {
+        builder.addTarget(projectNode.get(s, ""));
+      }
+    }
+
+    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+    for (IClasspathEntry entry : ((IJavaProject) project).getRawClasspath()) {
+      switch (entry.getEntryKind()) {
+        case IClasspathEntry.CPE_SOURCE:
+          IResource res = root.findMember(entry.getPath());
+          if (res != null) {
+            builder.addDirectory(res.getProjectRelativePath().removeFirstSegments(1).toOSString());
+          }
+          break;
+        case IClasspathEntry.CPE_CONTAINER:
+          String path = entry.getPath().toOSString();
+          if (path.startsWith(STANDARD_VM_CONTAINER_PREFIX)) {
+            builder.setJavaLanguageLevel(
+                Integer.parseInt(path.substring(STANDARD_VM_CONTAINER_PREFIX.length())));
+          }
+          break;
+      }
+    }
+    return builder.build();
+  }
+}
diff --git a/java/com/google/devtools/bazel/e4b/builder/BazelBuilder.java b/java/com/google/devtools/bazel/e4b/builder/BazelBuilder.java
index 4c16fd4..84e853a 100644
--- a/java/com/google/devtools/bazel/e4b/builder/BazelBuilder.java
+++ b/java/com/google/devtools/bazel/e4b/builder/BazelBuilder.java
@@ -25,6 +25,7 @@
 import org.osgi.service.prefs.BackingStoreException;
 
 import com.google.devtools.bazel.e4b.Activator;
+import com.google.devtools.bazel.e4b.BazelProjectSupport;
 import com.google.devtools.bazel.e4b.command.BazelCommand.BazelInstance;
 import com.google.devtools.bazel.e4b.command.BazelNotFoundException;
 
@@ -35,7 +36,7 @@
       throws CoreException {
     IProject project = getProject();
     try {
-      BazelInstance instance = Activator.getBazelCommandInstance(project);
+      BazelInstance instance = BazelProjectSupport.getBazelCommandInstance(project);
       if (kind == INCREMENTAL_BUILD || kind == AUTO_BUILD) {
         IResourceDelta delta = getDelta(getProject());
         if (delta == null || delta.getAffectedChildren().length == 0) {
@@ -44,7 +45,8 @@
         }
       }
       instance.markAsDirty();
-      instance.build(Activator.getTargets(project));
+      instance.build(BazelProjectSupport.getTargets(project),
+          BazelProjectSupport.getBuildFlags(project));
     } catch (BackingStoreException | IOException | InterruptedException e) {
       Activator.error("Failed to build " + project.getName(), e);
     } catch (BazelNotFoundException e) {
diff --git a/java/com/google/devtools/bazel/e4b/classpath/BazelClasspathContainer.java b/java/com/google/devtools/bazel/e4b/classpath/BazelClasspathContainer.java
index bdd0082..7c82380 100644
--- a/java/com/google/devtools/bazel/e4b/classpath/BazelClasspathContainer.java
+++ b/java/com/google/devtools/bazel/e4b/classpath/BazelClasspathContainer.java
@@ -36,6 +36,7 @@
 import org.osgi.service.prefs.BackingStoreException;
 
 import com.google.devtools.bazel.e4b.Activator;
+import com.google.devtools.bazel.e4b.BazelProjectSupport;
 import com.google.devtools.bazel.e4b.command.BazelCommand.BazelInstance;
 import com.google.devtools.bazel.e4b.command.BazelNotFoundException;
 import com.google.devtools.bazel.e4b.command.IdeBuildInfo;
@@ -53,7 +54,7 @@
       BazelNotFoundException {
     this.path = path;
     this.project = project;
-    this.instance = Activator.getBazelCommandInstance(project.getProject());
+    this.instance = BazelProjectSupport.getBazelCommandInstance(project.getProject());
   }
 
   private boolean isSourcePath(String path) throws JavaModelException, BackingStoreException {
@@ -102,7 +103,7 @@
   @Override
   public IClasspathEntry[] getClasspathEntries() {
     try {
-      List<String> targets = Activator.getTargets(project.getProject());
+      List<String> targets = BazelProjectSupport.getTargets(project.getProject());
       Map<String, IdeBuildInfo> infos = instance.getIdeInfo(targets);
       Set<Jars> jars = new HashSet<>();
       for (IdeBuildInfo s : infos.values()) {
diff --git a/java/com/google/devtools/bazel/e4b/command/BazelCommand.java b/java/com/google/devtools/bazel/e4b/command/BazelCommand.java
index 85c9282..9dd1cd5 100644
--- a/java/com/google/devtools/bazel/e4b/command/BazelCommand.java
+++ b/java/com/google/devtools/bazel/e4b/command/BazelCommand.java
@@ -62,10 +62,9 @@
   public BazelCommand(BazelAspectLocation aspectLocation, CommandConsoleFactory consoleFactory) {
     this.aspectLocation = aspectLocation;
     this.consoleFactory = consoleFactory;
-    this.buildOptions =
-        ImmutableList.of("--watchfs",
-            "--override_repository=local_eclipse_aspect=" + aspectLocation.getWorkspaceDirectory(),
-            "--aspects=@local_eclipse_aspect" + aspectLocation.getAspectLabel());
+    this.buildOptions = ImmutableList.of("--watchfs",
+        "--override_repository=local_eclipse_aspect=" + aspectLocation.getWorkspaceDirectory(),
+        "--aspects=@local_eclipse_aspect" + aspectLocation.getAspectLabel());
     this.aspectOptions = ImmutableList.<String>builder().addAll(buildOptions).add("-k",
         "--output_groups=ide-info-text,ide-resolve,-_,-defaults", "--experimental_show_artifacts")
         .build();
@@ -135,7 +134,7 @@
   /**
    * Returns a {@link BazelInstance} for the given directory. It looks for the enclosing workspace
    * and returns the instance that correspond to it. If not in a workspace, returns null.
-   * 
+   *
    * @throws BazelNotFoundException
    */
   public BazelInstance getInstance(File directory)
@@ -168,7 +167,7 @@
 
     /**
      * Returns the list of targets present in the BUILD files for the given sub-directories.
-     * 
+     *
      * @throws BazelNotFoundException
      */
     public synchronized List<String> listTargets(File... directories)
@@ -193,7 +192,7 @@
     /**
      * Returns the IDE build information from running the aspect over the given list of targets. The
      * result is a list of of path to the output artifact created by the build.
-     * 
+     *
      * @throws BazelNotFoundException
      */
     private synchronized List<String> buildIdeInfo(Collection<String> targets)
@@ -213,7 +212,7 @@
      * <p>
      * This method cache it results and won't recompute a previously computed version unless
      * {@link #markAsDirty()} has been called in between.
-     * 
+     *
      * @throws BazelNotFoundException
      */
     public synchronized Map<String, IdeBuildInfo> getIdeInfo(Collection<String> targets)
@@ -239,26 +238,35 @@
 
     /**
      * Build a list of targets in the current workspace.
-     * 
+     *
      * @throws BazelNotFoundException
      */
     public synchronized int build(List<String> targets, String... extraArgs)
         throws IOException, InterruptedException, BazelNotFoundException {
-      return BazelCommand.this.runBazel(workspaceRoot,
-          ImmutableList.<String>builder().add("build")
-              .addAll(buildOptions).add(extraArgs).addAll(targets).build());
+      return BazelCommand.this.runBazel(workspaceRoot, ImmutableList.<String>builder().add("build")
+          .addAll(buildOptions).add(extraArgs).addAll(targets).build());
+    }
+
+    /**
+     * Build a list of targets in the current workspace.
+     *
+     * @throws BazelNotFoundException
+     */
+    public synchronized int build(List<String> targets, List<String> extraArgs)
+        throws IOException, InterruptedException, BazelNotFoundException {
+      return BazelCommand.this.runBazel(workspaceRoot, ImmutableList.<String>builder().add("build")
+          .addAll(buildOptions).addAll(extraArgs).addAll(targets).build());
     }
 
     /**
      * Run test on a list of targets in the current workspace.
-     * 
+     *
      * @throws BazelNotFoundException
      */
     public synchronized int tests(List<String> targets, String... extraArgs)
         throws IOException, InterruptedException, BazelNotFoundException {
-      return BazelCommand.this.runBazel(workspaceRoot,
-          ImmutableList.<String>builder().add("test")
-              .addAll(buildOptions).add(extraArgs).addAll(targets).build());
+      return BazelCommand.this.runBazel(workspaceRoot, ImmutableList.<String>builder().add("test")
+          .addAll(buildOptions).add(extraArgs).addAll(targets).build());
     }
 
     /**
@@ -278,7 +286,7 @@
     /**
      * Gives a list of target completions for the given beginning string. The result is the list of
      * possible completion for a target pattern starting with string.
-     * 
+     *
      * @throws BazelNotFoundException
      */
     public List<String> complete(String string)
diff --git a/java/com/google/devtools/bazel/e4b/wizard/BazelProjectSupport.java b/java/com/google/devtools/bazel/e4b/wizard/BazelProjectSupport.java
deleted file mode 100644
index 5bcd9b9..0000000
--- a/java/com/google/devtools/bazel/e4b/wizard/BazelProjectSupport.java
+++ /dev/null
@@ -1,153 +0,0 @@
-// Copyright 2016 The Bazel Authors. All rights reserved.
-//
-// 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 License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.bazel.e4b.wizard;
-
-import java.net.URI;
-import java.util.LinkedList;
-import java.util.List;
-
-import org.eclipse.core.resources.ICommand;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ProjectScope;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.core.runtime.preferences.IScopeContext;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.IJavaProject;
-import org.eclipse.jdt.core.JavaCore;
-import org.osgi.service.prefs.BackingStoreException;
-import org.osgi.service.prefs.Preferences;
-
-import com.google.devtools.bazel.e4b.Activator;
-import com.google.devtools.bazel.e4b.ProjectNature;
-import com.google.devtools.bazel.e4b.classpath.BazelClasspathContainer;
-
-/**
- * A utility class to create e4b projects.
- */
-public class BazelProjectSupport {
-
-  /**
-   * Create a e4b project. This method adds the natures to the project, saves the list of targets
-   * and the workspace root to the project settings, make Bazel the default builder instead of ECJ
-   * and create the classpath using ide build informations from Bazel.
-   */
-  public static IProject createProject(String projectName, URI location, String workspaceRoot,
-      List<String> paths, List<String> targets) {
-
-    IProject project = createBaseProject(projectName, location);
-    try {
-      addNature(project, ProjectNature.NATURE_ID);
-      addNature(project, JavaCore.NATURE_ID);
-      addSettings(project, workspaceRoot, targets);
-      setBuilders(project);
-      createClasspath(new Path(workspaceRoot), paths, JavaCore.create(project));
-    } catch (CoreException e) {
-      e.printStackTrace();
-      project = null;
-    } catch (BackingStoreException e) {
-      e.printStackTrace();
-      project = null;
-    }
-
-    return project;
-  }
-
-  private static void addSettings(IProject project, String workspaceRoot, List<String> targets)
-      throws BackingStoreException {
-    IScopeContext projectScope = new ProjectScope(project);
-    Preferences projectNode = projectScope.getNode(Activator.PLUGIN_ID);
-    int i = 0;
-    for (String target : targets) {
-      projectNode.put("target" + i, target);
-      i++;
-    }
-    projectNode.put("workspaceRoot", workspaceRoot);
-    projectNode.flush();
-  }
-
-  private static void setBuilders(IProject project) throws CoreException {
-    IProjectDescription description = project.getDescription();
-    final ICommand buildCommand = description.newCommand();
-    buildCommand.setBuilderName("com.google.devtools.bazel.e4b.builder");
-    description.setBuildSpec(new ICommand[] {buildCommand});
-    project.setDescription(description, null);
-  }
-
-  private static void createClasspath(IPath root, List<String> paths, IJavaProject javaProject)
-      throws CoreException {
-    String name = root.lastSegment();
-    IFolder base = javaProject.getProject().getFolder(name);
-    if (!base.isLinked()) {
-      base.createLink(root, IResource.NONE, null);
-    }
-    List<IClasspathEntry> list = new LinkedList<>();
-    for (String path : paths) {
-      IPath workspacePath = base.getFullPath().append(path);
-      list.add(JavaCore.newSourceEntry(workspacePath));
-    }
-    list.add(JavaCore.newContainerEntry(new Path(BazelClasspathContainer.CONTAINER_NAME)));
-    // TODO(dmarting): we should add otherwise. Best way is to get the bootclasspath from Bazel.
-    list.add(JavaCore.newContainerEntry(new Path("org.eclipse.jdt.launching.JRE_CONTAINER/"
-        + "org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8")));
-    IClasspathEntry[] newClasspath = (IClasspathEntry[]) list.toArray(new IClasspathEntry[0]);
-    javaProject.setRawClasspath(newClasspath, null);
-  }
-
-  private static IProject createBaseProject(String projectName, URI location) {
-    IProject newProject = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
-
-    if (!newProject.exists()) {
-      URI projectLocation = location;
-      IProjectDescription desc =
-          newProject.getWorkspace().newProjectDescription(newProject.getName());
-      if (location != null
-          && ResourcesPlugin.getWorkspace().getRoot().getLocationURI().equals(location)) {
-        projectLocation = null;
-      }
-
-      desc.setLocationURI(projectLocation);
-      try {
-        newProject.create(desc, null);
-        if (!newProject.isOpen()) {
-          newProject.open(null);
-        }
-      } catch (CoreException e) {
-        e.printStackTrace();
-      }
-    }
-
-    return newProject;
-  }
-
-  private static void addNature(IProject project, String nature) throws CoreException {
-    if (!project.hasNature(nature)) {
-      IProjectDescription description = project.getDescription();
-      String[] prevNatures = description.getNatureIds();
-      String[] newNatures = new String[prevNatures.length + 1];
-      System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
-      newNatures[prevNatures.length] = nature;
-      description.setNatureIds(newNatures);
-
-      project.setDescription(description, null);
-    }
-  }
-
-}
diff --git a/java/com/google/devtools/bazel/e4b/wizard/BazelWizard.java b/java/com/google/devtools/bazel/e4b/wizard/BazelWizard.java
index 32c338b..b017665 100644
--- a/java/com/google/devtools/bazel/e4b/wizard/BazelWizard.java
+++ b/java/com/google/devtools/bazel/e4b/wizard/BazelWizard.java
@@ -20,6 +20,8 @@
 import org.eclipse.ui.IWorkbenchWizard;
 import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
 
+import com.google.devtools.bazel.e4b.BazelProjectSupport;
+
 /**
  * A wizard to create a Bazel import project.
  */
@@ -44,7 +46,8 @@
   @Override
   public boolean performFinish() {
     BazelProjectSupport.createProject(page1.getProjectName(), page1.getLocationURI(),
-        page2.getWorkspaceRoot(), page2.getDirectories(), page2.getTargets());
+        page2.getWorkspaceRoot(), page2.getDirectories(), page2.getTargets(),
+        page2.getJavaLanguageVersion());
     return true;
   }
 
diff --git a/java/com/google/devtools/bazel/e4b/wizard/WorkspaceWizardPage.java b/java/com/google/devtools/bazel/e4b/wizard/WorkspaceWizardPage.java
index 5f70a67..fafdc8c 100644
--- a/java/com/google/devtools/bazel/e4b/wizard/WorkspaceWizardPage.java
+++ b/java/com/google/devtools/bazel/e4b/wizard/WorkspaceWizardPage.java
@@ -87,6 +87,13 @@
     return workspaceRoot.getText();
   }
 
+  /**
+   * Returns the language version for the new project.
+   */
+  int getJavaLanguageVersion() {
+    return 8;
+  }
+
 
   @Override
   public void createControl(Composite parent) {
@@ -226,6 +233,7 @@
     target = new Text(container, SWT.BORDER);
     setAutoCompletion();
     target.addKeyListener(new KeyAdapter() {
+      @Override
       public void keyReleased(KeyEvent ke) {
         if (ke.keyCode == '\r' && (ke.stateMask & SWT.SHIFT) != 0 && !target.getText().isEmpty()) {
           addTarget();