@Override
  public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
    final XmlAttribute xmlns = getXmlnsDeclaration(element);
    if (xmlns == null) return;
    final String namespace = xmlns.getValue();
    final XmlTag tag = xmlns.getParent();

    if (tag != null) {
      final Set<String> ns = tag.getLocalNamespaceDeclarations().keySet();
      final String nsPrefix =
        Messages.showInputDialog(project, XmlBundle.message("namespace.prefix"),
                                 XmlBundle.message("xml.intention.insert.namespace.prefix.command"),
                                 Messages.getInformationIcon(), "",
                                 new InputValidator() {
                                   @Override
                                   public boolean checkInput(String inputString) {
                                     return !ns.contains(inputString) && isValidPrefix(inputString, project);
                                   }

                                   @Override
                                   public boolean canClose(String inputString) {
                                     return checkInput(inputString);
                                   }
                                 });
      if (nsPrefix == null) return;
      final List<XmlTag> tags = new ArrayList<>();
      final List<XmlAttributeValue> values = new ArrayList<>();
      WriteCommandAction.writeCommandAction(project, tag.getContainingFile())
        .withName(XmlBundle.message("xml.intention.insert.namespace.prefix.command")).run(() -> {
        tag.accept(new XmlRecursiveElementVisitor() {
          @Override
          public void visitXmlTag(@NotNull XmlTag tag) {
            if (tag.getNamespace().equals(namespace) && tag.getNamespacePrefix().isEmpty()) {
              tags.add(tag);
            }
            super.visitXmlTag(tag);
          }

          @Override
          public void visitXmlAttributeValue(@NotNull XmlAttributeValue value) {
            PsiReference ref = null;
            boolean skip = false;
            for (PsiReference reference : value.getReferences()) {
              if (reference instanceof TypeOrElementOrAttributeReference) {
                ref = reference;
              }
              else if (reference instanceof SchemaPrefixReference) {
                skip = true;
                break;
              }
            }
            if (!skip && ref != null) {
              final PsiElement xmlElement = ref.resolve();
              if (xmlElement instanceof XmlElement) {
                final XmlTag tag = PsiTreeUtil.getParentOfType(xmlElement, XmlTag.class, false);
                if (tag != null) {
                  if (tag.getNamespace().equals(namespace)) {
                    if (ref.getRangeInElement().getLength() == value.getValue().length()) { //no ns prefix
                      values.add(value);
                    }
                  }
                }
              }
            }
          }
        });
        for (XmlAttributeValue value : values) {
          ((XmlAttribute)value.getParent()).setValue(nsPrefix + ":" + value.getValue());
        }
        for (XmlTag xmlTag : tags) {
          xmlTag.setName(nsPrefix + ":" + xmlTag.getLocalName());
        }
        xmlns.setName("xmlns:" + nsPrefix);
      });
    }
  }
@Override
  public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element)