private ResolvedPath mergeWithCore(ResolvedPath path) {
    // Will throw a detailed exception on conflict
    pathResolver.merge(Arrays.asList(new ResolvedPath[] {corePath, path}));

    // Now strip any artifacts that are found in the core
    List artifacts = new ArrayList();

    for (Iterator i = path.getArtifacts().iterator(); i.hasNext(); ) {
      RepoArtifact artifact = (RepoArtifact) i.next();

      if (!corePath.contains(artifact.getId())) {
        artifacts.add(artifact);
      }
    }

    return new ResolvedPath(path.getId(), artifacts);
  }
  public ResolvedPath _getResolvedPluginPath(
      Plugin plugin, String pathId, boolean mergeWithCore, boolean overrideCore, boolean flatten) {
    // Create a mock artifact for the resolver as a way to add user specified path specs and
    // overrides
    RepoArtifact artifact = new RepoArtifact();
    RepoDependency dependency = new RepoDependency();
    RepoArtifactId pluginId = plugin.getArtifact().getId();
    dependency.setId(pluginId);
    artifact.addDependency(dependency);

    String id = "plugin";
    artifact.addPath(new RepoPath(id, "Plugin path", true, true));

    // Add dependencies
    if (plugin.getDependency() != null) {
      for (Iterator j = plugin.getDependency().getPathSpecs().iterator(); j.hasNext(); ) {
        RepoPathSpec pluginPathSpec = (RepoPathSpec) j.next();

        if (pluginPathSpec.getFrom().equals(pathId)) {
          // Add user specifications. Ignore the mandatory flag and to paths as they
          // are not relevant. However, allow descend to be false in case the writer of the
          // plugin added bogus dependencies.
          dependency.addPathSpec(
              new RepoPathSpec(
                  pathId,
                  id,
                  pluginPathSpec.getOptions(),
                  (pluginPathSpec.isDescend() == null) ? Boolean.TRUE : pluginPathSpec.isDescend(),
                  Boolean.TRUE));
        }
      }
    }

    if (dependency.getPathSpecs().size() == 0) {
      // Add default ... user hasn't specified anything
      dependency.addPathSpec(new RepoPathSpec(pathId, id, null, Boolean.TRUE, Boolean.TRUE));
    }

    // Add core overrides if applicable
    if (overrideCore) {
      for (Iterator j = coreOverrides.iterator(); j.hasNext(); ) {
        RepoOverride override = (RepoOverride) j.next();
        artifact.addOverride(override);
      }
    }

    // Add overrides
    for (Iterator i = overrides.iterator(); i.hasNext(); ) {
      ws.quokka.core.model.Override override = (ws.quokka.core.model.Override) i.next();
      Set paths = override.matchingPluginPaths(plugin.getArtifact().getId());

      if (paths.contains(pathId) || ((paths.size() == 1) && paths.contains("*"))) {
        // Create a copy of the override, moving matching plugin paths to be standard paths
        RepoOverride copy =
            new RepoOverride(
                Collections.singleton("*"),
                override.getGroup(),
                override.getName(),
                override.getType(),
                override.getVersion(),
                override.getWithVersion(),
                override.getWithPathSpecs());
        artifact.addOverride(copy);
      }
    }

    // Remove the plugin itself from the path
    // TODO: Look into a better way of doing this, perhaps modifying Resolver so it has the option
    // of not adding the root in first place.
    ResolvedPath path = pathResolver.resolvePath(id, artifact);
    path.setId("Plugin path '" + pathId + "' from " + pluginId.toShortString());

    List artifacts = new ArrayList();

    for (Iterator i = path.getArtifacts().iterator(); i.hasNext(); ) {
      artifact = (RepoArtifact) i.next();

      if (!artifact.getId().equals(pluginId)) {
        artifacts.add(artifact);
      }

      if (pluginId.equals(artifact.getId().getAnnotations().get("declaredBy"))) {
        artifact.getId().getAnnotations().remove("declaredBy");
      }
    }

    path = new ResolvedPath(path.getId(), artifacts);
    path = handleMergeAndFlatten(mergeWithCore, flatten, path);

    return path;
  }