/**
   * Generates the classpath to be used by the launcher to execute the requested Grails script.
   *
   * @return An array of {@code URL} objects representing the dependencies required on the classpath
   *     to execute the selected Grails script.
   * @throws MojoExecutionException if an error occurs while attempting to resolve the dependencies
   *     and generate the classpath array.
   */
  @SuppressWarnings("unchecked")
  private URL[] generateGrailsExecutionClasspath(Set<Artifact> resolvedArtifacts)
      throws MojoExecutionException {
    try {

      final List<URL> classpath = generateExecutionClasspath(resolvedArtifacts);

      // check to see if someone is adding build listeners on the classpath, and if so, bring in the
      // system classpath and add it to our urls
      // IDEA for example does this
      if (System.getProperty("grails.build.listeners") != null) {
        String cp = System.getProperty("java.class.path");
        for (String c : cp.split(":")) {
          File f = new File(c);
          if (f.exists()) classpath.add(f.toURI().toURL());
        }
      }

      if (System.getProperty("grails.debug.classpath") != null) {
        for (URL url : classpath) {
          getLog().info("classpath " + url.toString());
        }
      }

      /*
       * Add the "tools.jar" to the classpath so that the Grails scripts can run native2ascii.
       * First assume that "java.home" points to a JRE within a JDK.  NOTE that this will not
       * provide a valid path on Mac OSX.  This is not a big deal, as the JDK on Mac OSX already
       * adds the required JAR's to the classpath.  This logic is really only for Windows/*Unix.
       */
      final String javaHome = System.getProperty("java.home");
      File toolsJar = new File(javaHome, "../lib/tools.jar");
      if (!toolsJar.exists()) {
        // The "tools.jar" cannot be found with that path, so
        // now try with the assumption that "java.home" points
        // to a JDK.
        toolsJar = new File(javaHome, "tools.jar");
      }

      if (toolsJar.exists()) {
        java.net.URL url = toolsJar.toURI().toURL();
        if (url != null) {
          classpath.add(url);
        }
      }

      return classpath.toArray(new URL[classpath.size()]);
    } catch (final Exception e) {
      throw new MojoExecutionException("Failed to create classpath for Grails execution.", e);
    }
  }
  /**
   * Gets around an issue where a binary plugin's resource refers to a source plugins's resource and
   * the binary plugin is subsequently requested in a binary or source artifact.
   *
   * @param existing - the existing decoded classpath
   * @return - the new classpath with the extra directories in it where source plugins will be
   *     stored
   * @throws MalformedURLException
   */
  protected URL[] addBinaryPluginWorkaround(URL[] existing) throws MalformedURLException {

    List<URL> classpath = new ArrayList<URL>();

    classpath.add(new File(basedir, "target/plugin-build-classes").toURI().toURL());
    classpath.add(new File(basedir, "target/plugin-provided-classes").toURI().toURL());
    classpath.add(new File(basedir, "target/plugin-classes").toURI().toURL());
    classpath.add(new File(basedir, "target/resources").toURI().toURL());

    classpath.addAll(Arrays.asList(existing));

    URL[] workaround = new URL[classpath.size()];

    return classpath.toArray(workaround);
  }