@Nullable
  public static MavenDomPlugin searchManagingPlugin(@NotNull final MavenDomPlugin plugin) {
    final String artifactId = plugin.getArtifactId().getStringValue();
    final String groupId = plugin.getGroupId().getStringValue();
    if (artifactId == null) return null;

    final MavenDomProjectModel model = plugin.getParentOfType(MavenDomProjectModel.class, false);
    if (model == null) return null;

    SearchProcessor<MavenDomPlugin, MavenDomPlugins> processor =
        new SearchProcessor<MavenDomPlugin, MavenDomPlugins>() {
          @Override
          protected MavenDomPlugin find(MavenDomPlugins mavenDomPlugins) {
            if (!model.equals(mavenDomPlugins.getParentOfType(MavenDomProjectModel.class, true))) {
              for (MavenDomPlugin domPlugin : mavenDomPlugins.getPlugins()) {
                if (MavenPluginDomUtil.isPlugin(domPlugin, groupId, artifactId)) {
                  return domPlugin;
                }
              }
            }

            return null;
          }
        };

    Function<MavenDomProjectModelBase, MavenDomPlugins> domProfileFunction =
        mavenDomProfile -> mavenDomProfile.getBuild().getPluginManagement().getPlugins();

    process(
        model, processor, model.getManager().getProject(), domProfileFunction, domProfileFunction);

    return processor.myResult;
  }
  private void exclude() {
    final MavenArtifact artifactToExclude = mavenArtifactNode.getArtifact();
    final MavenArtifactNode oldestParent = getOldestParentMavenArtifact();

    DomFileElement domFileElement = getDomFileElement(oldestParent);

    if (domFileElement != null) {
      final MavenDomProjectModel rootElement =
          (MavenDomProjectModel) domFileElement.getRootElement();
      final MavenDomDependencies dependencies = rootElement.getDependencies();
      boolean found = false;

      for (MavenDomDependency mavenDomDependency : dependencies.getDependencies()) {
        if (isSameDependency(oldestParent.getArtifact(), mavenDomDependency)) {
          found = true;
          final MavenDomExclusions exclusions = mavenDomDependency.getExclusions();
          for (MavenDomExclusion mavenDomExclusion : exclusions.getExclusions()) {
            if (isSameDependency(artifactToExclude, mavenDomExclusion)) {
              return;
            }
          }
          createExclusion(artifactToExclude, exclusions);
          dependencyExcluded();
        }
      }
      if (!found) {
        final Notification notification =
            new Notification(
                MAVEN_HELPER_DEPENDENCY_ANALYZER_NOTIFICATION,
                "",
                "Parent dependency not found, it is probably in parent pom",
                NotificationType.WARNING);
        ApplicationManager.getApplication()
            .invokeLater(
                new Runnable() {
                  @Override
                  public void run() {
                    Notifications.Bus.notify(notification, project);
                  }
                });
      }
    } else {
      final Notification notification =
          new Notification(
              MAVEN_HELPER_DEPENDENCY_ANALYZER_NOTIFICATION,
              "",
              "Pom file not found",
              NotificationType.WARNING);
      ApplicationManager.getApplication()
          .invokeLater(
              new Runnable() {
                @Override
                public void run() {
                  Notifications.Bus.notify(notification, project);
                }
              });
    }
  }
  public static boolean processDependenciesInDependencyManagement(
      @NotNull MavenDomProjectModel projectDom,
      @NotNull final Processor<MavenDomDependency> processor,
      @NotNull final Project project) {

    Processor<MavenDomDependencies> managedDependenciesListProcessor =
        dependencies -> {
          SmartList<MavenDomDependency> importDependencies = null;

          for (MavenDomDependency domDependency : dependencies.getDependencies()) {
            if ("import".equals(domDependency.getScope().getRawText())) {
              if (importDependencies == null) {
                importDependencies = new SmartList<MavenDomDependency>();
              }

              importDependencies.add(domDependency);
            } else {
              if (processor.process(domDependency)) return true;
            }
          }

          if (importDependencies != null) {
            for (MavenDomDependency domDependency : importDependencies) {
              GenericDomValue<String> version = domDependency.getVersion();
              if (version.getXmlElement() != null) {
                GenericDomValueReference reference = new GenericDomValueReference(version);
                PsiElement resolve = reference.resolve();

                if (resolve instanceof XmlFile) {
                  MavenDomProjectModel dependModel =
                      MavenDomUtil.getMavenDomModel((PsiFile) resolve, MavenDomProjectModel.class);
                  if (dependModel != null) {
                    for (MavenDomDependency dep :
                        dependModel.getDependencyManagement().getDependencies().getDependencies()) {
                      if (processor.process(dep)) return true;
                    }
                  }
                }
              }
            }
          }

          return false;
        };

    Function<MavenDomProjectModelBase, MavenDomDependencies> domFunction =
        mavenDomProfile -> mavenDomProfile.getDependencyManagement().getDependencies();

    return process(projectDom, managedDependenciesListProcessor, project, domFunction, domFunction);
  }
  @NotNull
  public static Collection<MavenDomPlugin> searchManagedPluginUsages(
      @NotNull final MavenDomProjectModel model,
      @Nullable final String groupId,
      @NotNull final String artifactId) {
    Project project = model.getManager().getProject();

    final Set<MavenDomPlugin> usages = new HashSet<MavenDomPlugin>();

    Processor<MavenDomProjectModel> collectProcessor =
        mavenDomProjectModel -> {
          for (MavenDomPlugin domPlugin :
              mavenDomProjectModel.getBuild().getPlugins().getPlugins()) {
            if (MavenPluginDomUtil.isPlugin(domPlugin, groupId, artifactId)) {
              usages.add(domPlugin);
            }
          }
          return false;
        };

    processChildrenRecursively(
        model, collectProcessor, project, new HashSet<MavenDomProjectModel>(), true);

    return usages;
  }
  @NotNull
  public static Set<MavenDomDependency> searchDependencyUsages(
      @NotNull final MavenDomProjectModel model,
      @NotNull final DependencyConflictId dependencyId,
      @NotNull final Set<MavenDomDependency> excludes) {
    Project project = model.getManager().getProject();
    final Set<MavenDomDependency> usages = new HashSet<MavenDomDependency>();
    Processor<MavenDomProjectModel> collectProcessor =
        mavenDomProjectModel -> {
          for (MavenDomDependency domDependency :
              mavenDomProjectModel.getDependencies().getDependencies()) {
            if (excludes.contains(domDependency)) continue;

            if (dependencyId.equals(DependencyConflictId.create(domDependency))) {
              usages.add(domDependency);
            }
          }
          return false;
        };

    processChildrenRecursively(
        model, collectProcessor, project, new HashSet<MavenDomProjectModel>(), true);

    return usages;
  }
  @Nullable
  public static MavenProject findProject(@NotNull MavenDomProjectModel projectDom) {
    XmlElement element = projectDom.getXmlElement();
    if (element == null) return null;

    VirtualFile file = getVirtualFile(element);
    if (file == null) return null;
    MavenProjectsManager manager = MavenProjectsManager.getInstance(element.getProject());
    return manager.findProject(file);
  }
  public static boolean processDependencies(
      @NotNull MavenDomProjectModel projectDom,
      @NotNull final Processor<MavenDomDependencies> processor) {

    Function<MavenDomProjectModelBase, MavenDomDependencies> domFunction =
        mavenDomProfile -> mavenDomProfile.getDependencies();

    return process(
        projectDom, processor, projectDom.getManager().getProject(), domFunction, domFunction);
  }
  public static MavenDomParent updateMavenParent(
      MavenDomProjectModel mavenModel, MavenProject parentProject) {
    MavenDomParent result = mavenModel.getMavenParent();

    VirtualFile pomFile = DomUtil.getFile(mavenModel).getVirtualFile();
    Project project = mavenModel.getXmlElement().getProject();

    MavenId parentId = parentProject.getMavenId();
    result.getGroupId().setStringValue(parentId.getGroupId());
    result.getArtifactId().setStringValue(parentId.getArtifactId());
    result.getVersion().setStringValue(parentId.getVersion());

    if (!Comparing.equal(pomFile.getParent().getParent(), parentProject.getDirectoryFile())) {
      result
          .getRelativePath()
          .setValue(PsiManager.getInstance(project).findFile(parentProject.getFile()));
    }

    return result;
  }
 public static void processChildrenRecursively(
     @Nullable MavenDomProjectModel model,
     @NotNull Processor<MavenDomProjectModel> processor,
     boolean processCurrentModel) {
   if (model != null) {
     processChildrenRecursively(
         model,
         processor,
         model.getManager().getProject(),
         new HashSet<MavenDomProjectModel>(),
         processCurrentModel);
   }
 }
  public static void processParentProjects(
      @NotNull final MavenDomProjectModel projectDom,
      @NotNull final Processor<MavenDomProjectModel> processor) {
    Set<MavenDomProjectModel> processed = new HashSet<MavenDomProjectModel>();
    Project project = projectDom.getManager().getProject();
    MavenDomProjectModel parent = findParent(projectDom, project);
    while (parent != null) {
      if (processed.contains(parent)) break;
      processed.add(parent);
      if (processor.process(parent)) break;

      parent = findParent(parent, project);
    }
  }
 private static void collectChildrenProjects(
     @NotNull final MavenDomProjectModel model, @NotNull Set<MavenDomProjectModel> models) {
   MavenProject mavenProject = MavenDomUtil.findProject(model);
   if (mavenProject != null) {
     final Project project = model.getManager().getProject();
     for (MavenProject inheritor :
         MavenProjectsManager.getInstance(project).findInheritors(mavenProject)) {
       MavenDomProjectModel inheritorProjectModel =
           MavenDomUtil.getMavenDomProjectModel(project, inheritor.getFile());
       if (inheritorProjectModel != null && !models.contains(inheritorProjectModel)) {
         models.add(inheritorProjectModel);
         collectChildrenProjects(inheritorProjectModel, models);
       }
     }
   }
 }
    @Nullable
    public T process(@NotNull MavenDomProjectModel projectDom) {
      MavenDomParent parent = projectDom.getMavenParent();
      MavenParentDesc parentDesc = null;
      if (DomUtil.hasXml(parent)) {
        String parentGroupId = parent.getGroupId().getStringValue();
        String parentArtifactId = parent.getArtifactId().getStringValue();
        String parentVersion = parent.getVersion().getStringValue();
        String parentRelativePath = parent.getRelativePath().getStringValue();
        if (StringUtil.isEmptyOrSpaces(parentRelativePath)) parentRelativePath = "../pom.xml";
        MavenId parentId = new MavenId(parentGroupId, parentArtifactId, parentVersion);
        parentDesc = new MavenParentDesc(parentId, parentRelativePath);
      }

      return process(
          myManager.getGeneralSettings(), MavenDomUtil.getVirtualFile(projectDom), parentDesc);
    }
  public static MavenId describe(PsiFile psiFile) {
    MavenDomProjectModel model = getMavenDomModel(psiFile, MavenDomProjectModel.class);

    String groupId = model.getGroupId().getStringValue();
    String artifactId = model.getArtifactId().getStringValue();
    String version = model.getVersion().getStringValue();

    if (groupId == null) {
      groupId = model.getMavenParent().getGroupId().getStringValue();
    }

    if (version == null) {
      version = model.getMavenParent().getVersion().getStringValue();
    }

    return new MavenId(groupId, artifactId, version);
  }
  private static <T> boolean processProject(
      MavenDomProjectModel projectDom,
      MavenProject mavenProjectOrNull,
      Processor<T> processor,
      Project project,
      Function<? super MavenDomProfile, T> domProfileFunction,
      Function<? super MavenDomProjectModel, T> projectDomFunction) {

    if (processProfilesXml(
        MavenDomUtil.getVirtualFile(projectDom),
        mavenProjectOrNull,
        processor,
        project,
        domProfileFunction)) {
      return true;
    }

    if (processProfiles(
        projectDom.getProfiles(), mavenProjectOrNull, processor, domProfileFunction)) return true;

    T t = projectDomFunction.fun(projectDom);
    return t == null ? false : processor.process(t);
  }
 @NotNull
 public static MavenDomDependency createDomDependency(
     @NotNull MavenDomProjectModel model, @Nullable Editor editor) {
   return createDomDependency(model.getDependencies(), editor);
 }
 @Nullable
 public static MavenDomProjectModel findParent(
     @NotNull MavenDomProjectModel model, Project project) {
   return findParent(model.getMavenParent(), project);
 }