@Override
  public @NotNull Result beforeCharTyped(final char c,
                                         final @NotNull Project project,
                                         final @NotNull Editor editor,
                                         final @NotNull PsiFile editedFile,
                                         final @NotNull FileType fileType) {
    if (c == '/' && XmlGtTypedHandler.fileContainsXmlLanguage(editedFile)) {
      PsiDocumentManager.getInstance(project).commitAllDocuments();

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

      if (element instanceof XmlToken) {
        final IElementType tokenType = ((XmlToken)element).getTokenType();

        if (tokenType == XmlTokenType.XML_EMPTY_ELEMENT_END &&
            offset == element.getTextOffset()
        ) {
          editor.getCaretModel().moveToOffset(offset + 1);
          editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
          return Result.STOP;
        }
        else if (tokenType == XmlTokenType.XML_TAG_END &&
                 offset == element.getTextOffset()
        ) {
          final ASTNode parentNode = element.getParent().getNode();
          final ASTNode child = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(parentNode);

          if (child != null && offset + 1 == child.getTextRange().getStartOffset()) {
            editor.getDocument().replaceString(offset + 1, parentNode.getTextRange().getEndOffset(), "");
          }
        }
      }
      CharSequence contents = provider.getContents();
      XmlTag parentTag;
      if (offset > 0 && contents.charAt(offset - 1) == '<'
          // We need to correct only HTML behaviour
          && (parentTag = PsiTreeUtil.getParentOfType(element, XmlTag.class)) instanceof HtmlTag
          && element == provider.findElementAt(offset, provider.getBaseLanguage())) {
        // Ensure we're not closing within a closed tag
        ASTNode closingTagName = XmlChildRole.CLOSING_TAG_NAME_FINDER.findChild(parentTag.getNode());
        ASTNode startingTagName = XmlChildRole.START_TAG_NAME_FINDER.findChild(parentTag.getNode());
        if (closingTagName != null
            && startingTagName != null
            && startingTagName.getStartOffset() < offset) {
          if (closingTagName.getStartOffset() - 1 != offset) {
            int nextCharPos = StringUtil.skipWhitespaceForward(contents, offset);
            if (nextCharPos > 0 && contents.charAt(nextCharPos) == '>') {
              editor.getDocument().insertString(offset, "/");
            }
            else {
              editor.getDocument().insertString(offset, "/>");
            }
          }
          editor.getCaretModel().moveCaretRelatively(1, 0, false, false, false);
          return Result.STOP;
        }
      }
    }
    return Result.CONTINUE;
  }
@Override
  public @NotNull Result beforeCharTyped(final char c,
                                         final @NotNull Project project,
                                         final @NotNull Editor editor,
                                         final @NotNull PsiFile editedFile,
                                         final @NotNull FileType fileType)