private String[] getXjcArguments(final String classPath, final String episodeFileNameOrNull)
      throws MojoExecutionException, NoSchemasException {

    final ArgumentBuilder builder = new ArgumentBuilder();

    // Add all flags on the form '-flagName'
    builder.withFlag(true, sourceType.getXjcArgument());
    builder.withFlag(noPackageLevelAnnotations, "npa");
    builder.withFlag(laxSchemaValidation, "nv");
    builder.withFlag(verbose, "verbose");
    builder.withFlag(quiet, "quiet");
    builder.withFlag(enableIntrospection, "enableIntrospection");
    builder.withFlag(extension, "extension");
    builder.withFlag(readOnly, "readOnly");
    builder.withFlag(noGeneratedHeaderComments, "no-header");
    builder.withFlag(addGeneratedAnnotation, "mark-generated");

    // Add all arguments on the form '-argumentName argumentValue'
    // (i.e. in 2 separate elements of the returned String[])
    builder.withNamedArgument("httpproxy", getProxyString(settings.getActiveProxy()));
    builder.withNamedArgument("encoding", getEncoding(false));
    builder.withNamedArgument("p", packageName);
    builder.withNamedArgument("target", target);
    builder.withNamedArgument("d", getOutputDirectory().getAbsolutePath());
    builder.withNamedArgument("classpath", classPath);

    if (generateEpisode) {

      // We must use the -extension flag for the episode to work.
      if (!extension) {

        if (getLog().isInfoEnabled()) {
          getLog()
              .info(
                  "Adding 'extension' flag to XJC arguments, since the 'generateEpisode' argument is "
                      + "given. (XJCs 'episode' argument requires that the 'extension' argument is provided).");
        }
        builder.withFlag(true, "extension");
      }

      final File episodeFile = getEpisodeFile(episodeFileNameOrNull);
      builder.withNamedArgument("episode", FileSystemUtilities.getCanonicalPath(episodeFile));
    }
    if (catalog != null) {
      builder.withNamedArgument("catalog", FileSystemUtilities.getCanonicalPath(catalog));
    }

    if (arguments != null) {
      builder.withPreCompiledArguments(arguments);
    }

    for (File current : getSourceXJBs()) {

      // Shorten the argument?
      // final String strippedXjbPath = FileSystemUtilities.relativize(
      //         current.getAbsolutePath(), getProject().getBasedir());

      // Each XJB must be given as a separate argument.
      builder.withNamedArgument("-b", current.getAbsolutePath());
    }

    final List<URL> sourceXSDs = getSources();
    if (sourceXSDs.isEmpty()) {

      // If we have no XSDs, we are not going to be able to run XJC.
      getLog().warn("No XSD files found. Please check your plugin configuration.");
      throw new NoSchemasException();

    } else {

      final List<String> unwrappedSourceXSDs = new ArrayList<String>();
      for (URL current : sourceXSDs) {

        // Shorten the argument if possible.
        if ("file".equalsIgnoreCase(current.getProtocol())) {
          unwrappedSourceXSDs.add(
              FileSystemUtilities.relativize(
                  current.getPath(), new File(System.getProperty("user.dir"))));
        } else {
          unwrappedSourceXSDs.add(current.toString());
        }
      }

      builder.withPreCompiledArguments(unwrappedSourceXSDs);
    }

    // All done.
    return logAndReturnToolArguments(builder.build(), "XJC");
  }