public static XmlTag findVariableInsertionPoint(final XmlTag currentUsageTag, PsiElement usageBlock, final String referenceName, XmlTag... moreUsages) {
      // sort tags by document order
      final Set<XmlTag> usages = new TreeSet<>(POSITION_COMPARATOR);
      usages.add(currentUsageTag);
      ContainerUtil.addAll(usages, moreUsages);

      // collect all other possible unresolved references with the same name in the current template
      usageBlock.accept(new PsiRecursiveElementVisitor() {
        @Override
        public void visitElement(@NotNull PsiElement element) {
          if (element instanceof XPathVariableReference) {
            visitXPathVariableReference(((XPathVariableReference)element));
          }
          else {
            super.visitElement(element);
          }
        }

        private void visitXPathVariableReference(XPathVariableReference reference) {
          if (referenceName.equals(reference.getReferencedName())) {
            if (reference.resolve() == null) {
              usages.add(PsiTreeUtil.getContextOfType(reference, XmlTag.class, true));
            }
          }
        }

        public void visitXmlAttribute(XmlAttribute attribute) {
          if (XsltSupport.isXPathAttribute(attribute)) {
            final PsiFile[] xpathFiles = XsltSupport.getFiles(attribute);
            for (PsiFile xpathFile : xpathFiles) {
              xpathFile.accept(this);
            }
          }
        }
      });

      final Iterator<XmlTag> it = usages.iterator();
      final XmlTag firstUsage = it.next();

      // find broadest scope to create the variable in
      XmlTag tag = firstUsage;
      while (it.hasNext()) {
        XmlTag xmlTag = it.next();
        final PsiElement t = PsiTreeUtil.findCommonParent(tag, xmlTag);
        if (t instanceof XmlTag) {
          tag = (XmlTag)t;
        }
        else {
          break;
        }
      }

      // find the actual tag to create the variable before
      final XmlTag[] subTags = tag.getSubTags();
      for (XmlTag xmlTag : subTags) {
        if (xmlTag.getTextOffset() > firstUsage.getTextOffset()) break;
        tag = xmlTag;
      }

      final XmlTag parentTag = tag.getParentTag();
      if (parentTag == null) return tag;

      final String parentName = parentTag.getLocalName();
      if ("apply-templates".equals(parentName) || "call-template".equals(parentName)
          || "when".equals(parentName) || "choose".equals(parentName)) {
        if ("when".equals(parentName)) tag = tag.getParentTag();
        assert tag != null;
        tag = tag.getParentTag();
      }
      assert tag != null;
      return tag;
    }
public static XmlTag findVariableInsertionPoint(final XmlTag currentUsageTag, PsiElement usageBlock, final String referenceName, XmlTag... moreUsages)