private MavenPlugin addOrUpdatePlugin(
      DependencyFacet deps,
      MavenPluginFacet plugins,
      MavenPluginAdapter pluginToInstall,
      boolean managed) {

    Coordinate pluginCoordinates =
        CoordinateBuilder.create()
            .setGroupId(pluginToInstall.getGroupId())
            .setArtifactId(pluginToInstall.getArtifactId());
    if (managed) {
      if (plugins.hasManagedPlugin(pluginCoordinates)) {
        plugins.updateManagedPlugin(pluginToInstall);
      } else {
        plugins.addManagedPlugin(pluginToInstall);
      }
    } else {
      if (plugins.hasPlugin(pluginCoordinates)) {
        plugins.updatePlugin(pluginToInstall);
      } else {
        plugins.addPlugin(pluginToInstall);
      }
    }

    return pluginToInstall;
  }
  private MavenPlugin install(Project project, final MavenPlugin plugin, boolean managed) {
    MavenPluginFacet plugins = project.getFacet(MavenPluginFacet.class);
    DependencyFacet deps = project.getFacet(DependencyFacet.class);
    Coordinate pluginCoordinates =
        CoordinateBuilder.create()
            .setGroupId(plugin.getCoordinate().getGroupId())
            .setArtifactId(plugin.getCoordinate().getArtifactId());
    MavenPlugin managedPlugin = null;
    if (plugins.hasManagedPlugin(pluginCoordinates)) {
      managedPlugin = plugins.getManagedPlugin(pluginCoordinates);
    }

    MavenPlugin existing = null;
    // existing represents the plugin(management) as it exists currently throughout the entire
    // hierarchy
    if (managed && plugins.hasEffectiveManagedPlugin(pluginCoordinates)) {
      existing = plugins.getEffectiveManagedPlugin(pluginCoordinates);
    } else if (plugins.hasEffectivePlugin(pluginCoordinates)) {
      existing = plugins.getEffectivePlugin(pluginCoordinates);
    }

    MavenPlugin filteredPlugin = plugin;
    // The filtered plugin preserve the hierarchy, by preventing installing properties already
    // defined with the same
    // values
    if (existing != null && preserveHierarchyPrecedence) {
      filteredPlugin = diff(plugin, existing);
    }
    // Preserve direct plugin-management inheritance
    if (!managed && managedPlugin != null) {
      // The plugin section does not exists but a plugin management section in the direct pom does
      filteredPlugin = diff(filteredPlugin, managedPlugin);
    }

    MavenPlugin mergedPlugin = filteredPlugin;
    // merged plugin is a merge with the direct plugin(management)
    if (managed && managedPlugin != null) {
      mergedPlugin = plugins.merge(mergedPlugin, managedPlugin);
    } else if (!managed && plugins.hasPlugin(pluginCoordinates)) {
      mergedPlugin = plugins.merge(mergedPlugin, plugins.getPlugin(pluginCoordinates));
    }

    // Resolve version
    String versionToInstall = plugin.getCoordinate().getVersion();
    if (mergedPlugin.getCoordinate().getVersion() == null) {
      // null version means no version was specified or already defined in the hierarchy
      if (versionToInstall == null) {
        versionToInstall = promptVersion(deps, pluginCoordinates, null).getVersion();
      }
    }

    // Install the plugin
    MavenPluginAdapter pluginToInstall = new MavenPluginAdapter(mergedPlugin);
    pluginToInstall.setVersion(versionToInstall);
    if (!managed) {
      // In case of a direct plugin install
      // We want it's version being managed in the plugin management section
      MavenPluginAdapter mavenManagedPlugin = null;
      if (managedPlugin != null) {
        // A plugin managemement section already exists, update version
        mavenManagedPlugin = new MavenPluginAdapter(managedPlugin);
        mavenManagedPlugin.setVersion(pluginToInstall.getVersion());
      } else {
        // Create a new plugin management, that will handle the minimal configuration: groupId,
        // artifactId and
        // version
        Plugin newManagedPlugin = new Plugin();
        newManagedPlugin.setGroupId(pluginToInstall.getGroupId());
        newManagedPlugin.setArtifactId(pluginToInstall.getArtifactId());
        newManagedPlugin.setVersion(pluginToInstall.getVersion());
        mavenManagedPlugin = new MavenPluginAdapter(newManagedPlugin);
      }

      // Install the plugin management, if needed
      addOrUpdatePlugin(deps, plugins, mavenManagedPlugin, true);
      pluginToInstall.setVersion(null); // handled by the plugin management section
    } else {
      if (existing != null
          && Strings.compare(versionToInstall, existing.getCoordinate().getVersion())) {
        // Same version in the hierarchy, no need to specify the version
        pluginToInstall.setVersion(null);
      }
    }

    return addOrUpdatePlugin(deps, plugins, pluginToInstall, managed);
  }