@Override
  public @NotNull Result charTyped(final char c, final @NotNull Project project, final @NotNull Editor editor, final @NotNull PsiFile editedFile) {
    if (!WebEditorOptions.getInstance().isAutoCloseTag()) return Result.CONTINUE;
    if (c == '/' && XmlGtTypedHandler.fileContainsXmlLanguage(editedFile)) {
      PsiDocumentManager.getInstance(project).commitAllDocuments();

      PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
      if (file == null) return Result.CONTINUE;
      FileViewProvider provider = file.getViewProvider();
      final int offset = editor.getCaretModel().getOffset();
      PsiElement element = provider.findElementAt(offset - 1, XMLLanguage.class);
      if (element == null) return Result.CONTINUE;
      if (!(element.getLanguage() instanceof XMLLanguage)) return Result.CONTINUE;

      ASTNode prevLeaf = element.getNode();
      if (prevLeaf == null) return Result.CONTINUE;
      final String prevLeafText = prevLeaf.getText();
      if ("</".equals(prevLeafText) && prevLeaf.getElementType() == XmlTokenType.XML_END_TAG_START) {
        XmlTag tag = PsiTreeUtil.getParentOfType(element, XmlTag.class);
        if (tag != null && StringUtil.isNotEmpty(tag.getName()) &&
            TreeUtil.findSibling(prevLeaf, XmlTokenType.XML_NAME) == null &&
            TreeUtil.findSibling(prevLeaf, XmlTokenType.XML_TAG_NAME) == null) {
          // check for template language like JSP
          if (provider instanceof MultiplePsiFilesPerDocumentFileViewProvider) {
            PsiElement element1 = AbstractFileViewProvider.findElementAt(file, offset - 1);
            if (element1 != null) {
              // case of top-level jsp tag
              XmlTag tag1 = PsiTreeUtil.getParentOfType(element1, XmlTag.class);
              if (shouldReplace(tag, tag1, offset)) {
                tag = tag1;
              }
              else {
                // if we have enclosing jsp tag, actual tag to be completed will be previous sibling
                tag1 = PsiTreeUtil.getPrevSiblingOfType(element1.getParent(), XmlTag.class);
                if (shouldReplace(tag, tag1, offset)) {
                  tag = tag1;
                }
              }
            }
          }
          EditorModificationUtil.insertStringAtCaret(editor, tag.getName() + ">", false);
          autoIndent(editor);
          return Result.STOP;
        }
      }
      if (!"/".equals(prevLeafText.trim())) return Result.CONTINUE;

      while ((prevLeaf = TreeUtil.prevLeaf(prevLeaf)) != null && prevLeaf.getElementType() == XmlTokenType.XML_WHITE_SPACE) ;
      if (prevLeaf instanceof OuterLanguageElement) {
        element = file.getViewProvider().findElementAt(offset - 1, file.getLanguage());
        prevLeaf = element != null ? element.getNode() : null;
        while ((prevLeaf = TreeUtil.prevLeaf(prevLeaf)) != null && prevLeaf.getElementType() == XmlTokenType.XML_WHITE_SPACE) ;
      }
      if (prevLeaf == null) return Result.CONTINUE;

      XmlTag tag = PsiTreeUtil.getParentOfType(prevLeaf.getPsi(), XmlTag.class);
      if (tag == null) { // prevLeaf maybe in one tree and element in another
        PsiElement element2 = provider.findElementAt(prevLeaf.getStartOffset(), XMLLanguage.class);
        tag = PsiTreeUtil.getParentOfType(element2, XmlTag.class);
        if (tag == null) return Result.CONTINUE;
      }

      final XmlToken startToken = XmlUtil.getTokenOfType(tag, XmlTokenType.XML_START_TAG_START);
      if (startToken == null || !startToken.getText().equals("<")) return Result.CONTINUE;
      if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_TAG_END) != null) return Result.CONTINUE;
      if (XmlUtil.getTokenOfType(tag, XmlTokenType.XML_EMPTY_ELEMENT_END) != null) return Result.CONTINUE;
      if (PsiTreeUtil.getParentOfType(element, XmlAttributeValue.class) != null) return Result.CONTINUE;

      EditorModificationUtil.insertStringAtCaret(editor, ">", false);
      return Result.STOP;
    }
    return Result.CONTINUE;
  }
@Override
  public @NotNull Result charTyped(final char c, final @NotNull Project project, final @NotNull Editor editor, final @NotNull PsiFile editedFile)