protected boolean isValid() {
    if (!super.isValid()) return false;

    try {
      Replacer.checkSupportedReplacementPattern(
          searchContext.getProject(), ((ReplaceConfiguration) model.getConfig()).getOptions());
    } catch (UnsupportedPatternException ex) {
      reportMessage(
          "unsupported.replacement.pattern.message", replaceCriteriaEdit, ex.getMessage());
      return false;
    } catch (MalformedPatternException ex) {
      reportMessage("malformed.replacement.pattern.message", replaceCriteriaEdit, ex.getMessage());
      return false;
    }

    return true;
  }
  @SuppressWarnings({"unchecked", "ConstantConditions"})
  private void handleModifierList(final PsiElement el, final PsiElement replacement)
      throws IncorrectOperationException {
    // We want to copy all comments, including doc comments and modifier lists
    // that are present in matched nodes but not present in search/replace

    Map<String, String> newNameToSearchPatternNameMap = myContext.getNewName2PatternNameMap();

    ModifierListOwnerCollector collector = new ModifierListOwnerCollector();
    el.accept(collector);
    Map<String, PsiNamedElement> originalNamedElements =
        (Map<String, PsiNamedElement>) collector.namedElements.clone();
    collector.namedElements.clear();

    replacement.accept(collector);
    Map<String, PsiNamedElement> replacedNamedElements =
        (Map<String, PsiNamedElement>) collector.namedElements.clone();
    collector.namedElements.clear();

    if (originalNamedElements.size() == 0 && replacedNamedElements.size() == 0) {
      Replacer.handleComments(el, replacement, myContext);
      return;
    }

    final PsiStatement[] statements = getCodeBlock().getStatements();
    if (statements.length > 0) {
      statements[0].getParent().accept(collector);
    }

    Map<String, PsiNamedElement> searchedNamedElements =
        (Map<String, PsiNamedElement>) collector.namedElements.clone();
    collector.namedElements.clear();

    for (String name : originalNamedElements.keySet()) {
      PsiNamedElement originalNamedElement = originalNamedElements.get(name);
      PsiNamedElement replacementNamedElement = replacedNamedElements.get(name);
      String key = newNameToSearchPatternNameMap.get(name);
      if (key == null) key = name;
      PsiNamedElement searchNamedElement = searchedNamedElements.get(key);

      if (replacementNamedElement == null
          && originalNamedElements.size() == 1
          && replacedNamedElements.size() == 1) {
        replacementNamedElement = replacedNamedElements.entrySet().iterator().next().getValue();
      }

      PsiElement comment = null;

      if (originalNamedElement instanceof PsiDocCommentOwner) {
        comment = ((PsiDocCommentOwner) originalNamedElement).getDocComment();
        if (comment == null) {
          PsiElement prevElement = originalNamedElement.getPrevSibling();
          if (prevElement instanceof PsiWhiteSpace) {
            prevElement = prevElement.getPrevSibling();
          }
          if (prevElement instanceof PsiComment) {
            comment = prevElement;
          }
        }
      }

      if (replacementNamedElement != null && searchNamedElement != null) {
        Replacer.handleComments(originalNamedElement, replacementNamedElement, myContext);
      }

      if (comment != null
          && replacementNamedElement instanceof PsiDocCommentOwner
          && !(replacementNamedElement.getFirstChild() instanceof PsiDocComment)) {
        final PsiElement nextSibling = comment.getNextSibling();
        PsiElement prevSibling = comment.getPrevSibling();
        replacementNamedElement.addRangeBefore(
            prevSibling instanceof PsiWhiteSpace ? prevSibling : comment,
            nextSibling instanceof PsiWhiteSpace ? nextSibling : comment,
            replacementNamedElement.getFirstChild());
      }

      if (originalNamedElement instanceof PsiModifierListOwner
          && replacementNamedElement instanceof PsiModifierListOwner) {
        PsiModifierList modifierList =
            ((PsiModifierListOwner) originalNamedElements.get(name)).getModifierList();

        if (searchNamedElement instanceof PsiModifierListOwner) {
          PsiModifierList modifierListOfSearchedElement =
              ((PsiModifierListOwner) searchNamedElement).getModifierList();
          final PsiModifierListOwner modifierListOwner =
              ((PsiModifierListOwner) replacementNamedElement);
          PsiModifierList modifierListOfReplacement = modifierListOwner.getModifierList();

          if (modifierListOfSearchedElement.getTextLength() == 0
              && modifierListOfReplacement.getTextLength() == 0
              && modifierList.getTextLength() > 0) {
            PsiElement space = modifierList.getNextSibling();
            if (!(space instanceof PsiWhiteSpace)) {
              space = createWhiteSpace(space);
            }

            modifierListOfReplacement.replace(modifierList);
            // copy space after modifier list
            if (space instanceof PsiWhiteSpace) {
              modifierListOwner.addRangeAfter(space, space, modifierListOwner.getModifierList());
            }
          } else if (modifierListOfSearchedElement.getTextLength() == 0
              && modifierList.getTextLength() > 0) {
            modifierListOfReplacement.addRange(
                modifierList.getFirstChild(), modifierList.getLastChild());
          }
        }
      }
    }
  }