@Override
    public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
        final int offset = editor.getCaretModel().getOffset();
        final PsiElement element = file.findElementAt(offset);
      final XmlAttribute attr = PsiTreeUtil.getParentOfType(element, XmlAttribute.class, false);
        assert attr != null;

        final XmlAttributeValue valueElement = attr.getValueElement();
        assert valueElement != null;
        final String s = attr.getValueTextRange().substring(valueElement.getText());

        final List<Pair<String, Boolean>> chunks = new ArrayList<>();
        final StringBuilder builder = new StringBuilder(s.length());

        final PsiFile[] files = XsltSupport.getFiles(attr);
        int i=0, j=0;
        while (i < s.length()) {
            final char c = s.charAt(i++);
            if (c == '{' && j < files.length) {
                if (i < s.length() - 1 && s.charAt(i) != '{') {
                    final PsiFile f = files[j++];
                    if (builder.length() > 0) {
                        chunks.add(Pair.create(builder.toString(), Boolean.FALSE));
                        builder.setLength(0);
                    }
                    chunks.add(Pair.create(f.getText(), Boolean.TRUE));
                    i += f.getTextLength();
                    if (s.charAt(i) == '}') i++;
                } else {
                    builder.append(c);
                    i++;
                }
            } else {
                builder.append(c);
            }
        }
        if (builder.length() > 0) {
            chunks.add(Pair.create(builder.toString(), Boolean.FALSE));
        }

        final XmlTag parent = attr.getParent();
      final XmlTag attrTag = parent.createChildTag("attribute", XsltSupport.XSLT_NS, null, false);
        attrTag.setAttribute("name", attr.getName()); // local name?

        final String value = attr.getNamespace();
        if (value.length() > 0) {
            attrTag.setAttribute("namespace", value);
        }
        for (Pair<String, Boolean> chunk : chunks) {
            final XmlTag child;
            if (chunk.second) {
              child = parent.createChildTag("value-of", XsltSupport.XSLT_NS, null, false);
                child.setAttribute("select", chunk.first);
//            } else if (chunks.size() == 1) {
                // TODO: really? or always create an xsl:text?
//                attrTag.add(attrTag.getManager().getElementFactory().createDisplayText(chunk.first));
//                continue;
            } else {
              child = parent.createChildTag("text", XsltSupport.XSLT_NS, null, false);
                child.add(XmlElementFactory.getInstance(child.getProject()).createDisplayText(chunk.first));
            }
            attrTag.add(child);
        }
        final PsiElement child = XsltCodeInsightUtil.findFirstRealTagChild(parent);
        if (child != null) {
            parent.addBefore(attrTag, child);
        } else {
            parent.add(attrTag);
        }
        attr.delete();
    }
@Override
    public void invoke(@NotNull Project project, Editor editor, PsiFile file)