public String[] knownNamespaces() {
   final PsiElement parentElement = getParent();
   BidirectionalMap<String, String> map = initNamespaceMaps(parentElement);
   Set<String> known = Collections.emptySet();
   if (map != null) {
     known = new HashSet<String>(map.values());
   }
   if (parentElement instanceof XmlTag) {
     if (known.isEmpty()) return ((XmlTag) parentElement).knownNamespaces();
     ContainerUtil.addAll(known, ((XmlTag) parentElement).knownNamespaces());
   } else {
     XmlExtension xmlExtension = XmlExtension.getExtensionByElement(this);
     if (xmlExtension != null) {
       final XmlFile xmlFile = xmlExtension.getContainingFile(this);
       if (xmlFile != null) {
         final XmlTag rootTag = xmlFile.getRootTag();
         if (rootTag != null && rootTag != this) {
           if (known.isEmpty()) return rootTag.knownNamespaces();
           ContainerUtil.addAll(known, rootTag.knownNamespaces());
         }
       }
     }
   }
   return ArrayUtil.toStringArray(known);
 }
  @NotNull
  @Override
  public LookupElement[] getVariants() {
    final PsiElement element = getElement();
    if (!myStartTagFlag) {
      return super.getVariants();
    }
    final XmlTag xmlTag = (XmlTag) element;

    final List<XmlElementDescriptor> variants =
        TagNameReference.<XmlElementDescriptor>getTagNameVariants(
            xmlTag, Arrays.asList(xmlTag.knownNamespaces()), new ArrayList<String>(), Function.ID);
    final List<LookupElement> elements = new ArrayList<LookupElement>(variants.size());
    for (XmlElementDescriptor descriptor : variants) {
      final String descriptorName = descriptor.getName(element);
      if (descriptorName != null) {
        LookupElementBuilder lookupElement =
            LookupElementBuilder.create(descriptor, descriptorName);
        elements.add(lookupElement.withInsertHandler(JavaFxTagInsertHandler.INSTANCE));
      }
    }
    return elements.toArray(new LookupElement[elements.size()]);
  }