@Override
  protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
    final PsiFile containingFile = element.getContainingFile();

    @NonNls String prefixToInsert = "";
    @NonNls String suffixToInsert = "";

    final int UNDEFINED_OFFSET = -1;
    int anchorOffset = UNDEFINED_OFFSET;
    PsiElement anchor =
      PsiTreeUtil.getParentOfType(element, XmlElementDecl.class, XmlAttlistDecl.class, XmlEntityDecl.class, XmlConditionalSection.class);
    if (anchor != null) anchorOffset = anchor.getTextRange().getStartOffset();

    if (anchorOffset == UNDEFINED_OFFSET && containingFile.getLanguage() == XMLLanguage.INSTANCE) {
      XmlFile file = (XmlFile)containingFile;
      final XmlProlog prolog = file.getDocument().getProlog();
      assert prolog != null;

      final XmlDoctype doctype = prolog.getDoctype();
      final XmlMarkupDecl markupDecl;

      if (doctype != null) {
        markupDecl = doctype.getMarkupDecl();
      }
      else {
        markupDecl = null;
      }

      if (doctype == null) {
        final XmlTag rootTag = file.getDocument().getRootTag();
        prefixToInsert = "<!DOCTYPE " + ((rootTag != null) ? rootTag.getName() : "null");
        suffixToInsert = ">\n";
      }
      if (markupDecl == null) {
        prefixToInsert += " [\n";
        suffixToInsert = "]" + suffixToInsert;

        if (doctype != null) {
          anchorOffset = doctype.getTextRange().getEndOffset() - 1; // just before last '>'
        }
        else {
          anchorOffset = prolog.getTextRange().getEndOffset();
        }
      }
    }

    if (anchorOffset == UNDEFINED_OFFSET) anchorOffset = element.getTextRange().getStartOffset();

    Document document = containingFile.getFileDocument();
    StringBuilder declaration = new StringBuilder();
    if (!prefixToInsert.isEmpty()) declaration.append(prefixToInsert);
    CharSequence sequence = document.getImmutableCharSequence();
    int pos = anchorOffset - 1;
    while (pos > 0 && (sequence.charAt(pos) == ' ' || sequence.charAt(pos) == '\t')) {
      pos--;
    }
    declaration.append("<!").append(myElementDeclarationName).append(" ").append(myReference).append(" ");
    int finalOffset = declaration.length() + anchorOffset;
    declaration.append(">\n");
    if (pos > 0 && sequence.charAt(pos) == '\n') {
      declaration.append(sequence.subSequence(pos + 1, anchorOffset));
    }
    if (!suffixToInsert.isEmpty()) declaration.append(suffixToInsert);
    document.insertString(anchorOffset, declaration.toString());
    updater.moveCaretTo(finalOffset);
  }
@Override
  protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater)