public XmlCompletionData() {
    declareFinalScope(XmlTag.class);
    declareFinalScope(XmlAttribute.class);
    declareFinalScope(XmlAttributeValue.class);

    {
      final CompletionVariant variant = new CompletionVariant(createTagCompletionFilter());
      variant.includeScopeClass(XmlTag.class);
      variant.addCompletionFilter(TrueFilter.INSTANCE);
      registerVariant(variant);
    }

    {
      final CompletionVariant variant = new CompletionVariant(createAttributeCompletionFilter());
      variant.includeScopeClass(XmlAttribute.class);
      variant.addCompletionFilter(TrueFilter.INSTANCE);
      registerVariant(variant);
    }

    {
      final CompletionVariant variant =
          new CompletionVariant(createAttributeValueCompletionFilter());
      variant.includeScopeClass(XmlAttributeValue.class);
      variant.addCompletion(getAttributeValueGetter(), TailType.NONE);
      variant.addCompletionFilter(TrueFilter.INSTANCE, TailType.NONE);
      registerVariant(variant);
    }

    final ElementFilter entityCompletionFilter = createXmlEntityCompletionFilter();

    {
      final CompletionVariant variant =
          new CompletionVariant(
              new AndFilter(
                  new XmlTokenTypeFilter(XmlTokenType.XML_DATA_CHARACTERS),
                  new NotFilter(entityCompletionFilter),
                  new ElementFilter() {
                    public boolean isAcceptable(Object element, PsiElement context) {
                      XmlTag tag = PsiTreeUtil.getParentOfType(context, XmlTag.class, false);
                      if (tag != null) {
                        return XmlUtil.getSchemaSimpleContent(tag) != null;
                      }
                      return false;
                    }

                    public boolean isClassAcceptable(Class hintClass) {
                      return true;
                    }
                  }));
      variant.includeScopeClass(XmlToken.class, true);
      variant.addCompletion(new SimpleTagContentEnumerationValuesGetter(), TailType.NONE);

      registerVariant(variant);
    }

    {
      final CompletionVariant variant =
          new CompletionVariant(
              new AndFilter(
                  new XmlTokenTypeFilter(XmlTokenType.XML_DATA_CHARACTERS),
                  new NotFilter(entityCompletionFilter)));
      variant.includeScopeClass(XmlToken.class, true);
      registerVariant(variant);
    }

    {
      final CompletionVariant variant = new CompletionVariant(entityCompletionFilter);
      variant.includeScopeClass(XmlToken.class, true);
      variant.addCompletion(new EntityRefGetter());
      variant.setInsertHandler(new EntityRefInsertHandler());
      registerVariant(variant);
    }
  }