protected static boolean addTail(char completionChar,
                                   XmlElementDescriptor descriptor,
                                   boolean isHtmlCode,
                                   XmlTag tag,
                                   Template template,
                                   StringBuilder indirectRequiredAttrs) {
    if (completionChar == '>' || (completionChar == '/' && indirectRequiredAttrs != null)) {
      template.addTextSegment(">");

      if (indirectRequiredAttrs != null) template.addTextSegment(indirectRequiredAttrs.toString());
      template.addEndVariable();

      if ((!(tag instanceof HtmlTag) || !HtmlUtil.isSingleHtmlTag(tag, true)) && tag.getAttributes().length == 0) {
        if (WebEditorOptions.getInstance().isAutomaticallyInsertClosingTag()) {
          final String name = descriptor.getName(tag);
          if (name != null) {
            template.addTextSegment("</");
            template.addTextSegment(name);
            template.addTextSegment(">");
          }
        }
      }
    }
    else if (completionChar == '/') {
      template.addTextSegment(closeTag(tag));
    }
    else if (completionChar == ' ' && template.getSegmentsCount() == 0) {
      if (WebEditorOptions.getInstance().isAutomaticallyStartAttribute() &&
          (descriptor.getAttributesDescriptors(tag).length > 0 || isTagFromHtml(tag) && !HtmlUtil.isTagWithoutAttributes(tag.getName()))) {
        completeAttribute(tag.getContainingFile(), template);
        return true;
      }
    }
    else if (completionChar == Lookup.AUTO_INSERT_SELECT_CHAR || completionChar == Lookup.NORMAL_SELECT_CHAR || completionChar == Lookup.REPLACE_SELECT_CHAR) {
      if (WebEditorOptions.getInstance().isAutomaticallyInsertClosingTag() && isHtmlCode && HtmlUtil.isSingleHtmlTag(tag, true)) {
        if (hasOwnAttributes(descriptor, tag)) {
          template.addEndVariable();
        }
        template.addTextSegment(HtmlUtil.isHtmlTag(tag) ? ">" : closeTag(tag));
      }
      else {
        if (needAtLeastOneAttribute(tag) && WebEditorOptions.getInstance().isAutomaticallyStartAttribute() && tag.getAttributes().length == 0
            && template.getSegmentsCount() == 0) {
          completeAttribute(tag.getContainingFile(), template);
          return true;
        }
        else {
          completeTagTail(template, descriptor, tag.getContainingFile(), tag, true);
        }
      }
    }

    return false;
  }
protected static boolean addTail(char completionChar,
                                   XmlElementDescriptor descriptor,
                                   boolean isHtmlCode,
                                   XmlTag tag,
                                   Template template,
                                   StringBuilder indirectRequiredAttrs)