@Override
  public @Nullable TreeElement generateTreeFor(@NotNull PsiElement original, final @NotNull CharTable table, final @NotNull PsiManager manager) {
    if (original instanceof PsiJavaToken) {
      final String text = original.getText();
      return createLeafFromText(text, table, manager, original, ((PsiJavaToken)original).getTokenType());
    }

    if (original instanceof PsiModifierList) {
      final String text = original.getText();
      assert text != null : "Text is null for " + original + "; " + original.getClass();
      final LanguageLevel level = PsiUtil.getLanguageLevel(original);
      final DummyHolder holder = DummyHolderFactory.createHolder(original.getManager(), new JavaDummyElement(text, MOD_LIST, level), null);
      final TreeElement modifierListElement = holder.getTreeElement().getFirstChildNode();
      if (modifierListElement == null) {
        throw new AssertionError("No modifier list for \"" + text + '\"');
      }
      return markGeneratedIfNeeded(original, modifierListElement);
    }

    if (original instanceof PsiReferenceExpression) {
      TreeElement element = createReferenceExpression(original.getProject(), original.getText(), original);
      PsiElement refElement = ((PsiJavaCodeReferenceElement)original).resolve();
      if (refElement instanceof PsiClass) {
        element.putCopyableUserData(REFERENCED_CLASS_KEY, (PsiClass)refElement);
      }
      return element;
    }

    if (original instanceof PsiJavaCodeReferenceElement) {
      PsiElement refElement = ((PsiJavaCodeReferenceElement)original).resolve();
      final boolean generated = refElement != null && CodeEditUtil.isNodeGenerated(refElement.getNode());
      if (refElement instanceof PsiClass) {
        if (refElement instanceof PsiAnonymousClass) {
          PsiJavaCodeReferenceElement ref = ((PsiAnonymousClass)refElement).getBaseClassReference();
          original = ref;
          refElement = ref.resolve();
        }

        boolean isFQ = false;
        if (original instanceof PsiJavaCodeReferenceElementImpl) {
          PsiJavaCodeReferenceElementImpl.Kind kind = ((PsiJavaCodeReferenceElementImpl)original).getKindEnum(original.getContainingFile());
          switch (kind) {
            case CLASS_OR_PACKAGE_NAME_KIND:
            case CLASS_NAME_KIND:
            case CLASS_IN_QUALIFIED_NEW_KIND:
              isFQ = false;
              break;

            case CLASS_FQ_NAME_KIND:
            case CLASS_FQ_OR_PACKAGE_NAME_KIND:
              isFQ = true;
              break;

            default:
              LOG.assertTrue(false);
          }
        }

        final String text = isFQ ? ((PsiClass)refElement).getQualifiedName() : original.getText();
        final TreeElement element = createReference(original.getProject(), text, generated);
        element.putCopyableUserData(REFERENCED_CLASS_KEY, (PsiClass)refElement);
        return element;
      }
      return createReference(original.getProject(), original.getText(), generated);
    }

    if (original instanceof PsiCompiledElement) {
      PsiElement sourceVersion = original.getNavigationElement();
      if (sourceVersion != original) {
        return ChangeUtil.generateTreeElement(sourceVersion, table, manager);
      }
      PsiElement mirror = ((PsiCompiledElement)original).getMirror();
      return ChangeUtil.generateTreeElement(mirror, table, manager);
    }

    if (original instanceof PsiTypeElement) {
      PsiTypeElement typeElement = (PsiTypeElement)original;
      PsiType type = typeElement.getType();

      if (type instanceof PsiIntersectionType) {
        type = ((PsiIntersectionType)type).getRepresentative();
      }
      else if (type instanceof PsiMethodReferenceType || type instanceof PsiLambdaExpressionType) {
        type = PsiType.getJavaLangObject(manager, GlobalSearchScope.projectScope(manager.getProject()));
      }

      String text = type.getCanonicalText(true);
      PsiJavaParserFacade parserFacade = JavaPsiFacade.getInstance(original.getProject()).getParserFacade();
      PsiTypeElement element = parserFacade.createTypeElementFromText(text, original);

      TreeElement result = (TreeElement)element.getNode();
      markGeneratedIfNeeded(original, result);
      encodeInfoInTypeElement(result, type);
      return result;
    }

    return null;
  }
@Override
  public @Nullable TreeElement generateTreeFor(@NotNull PsiElement original, final @NotNull CharTable table, final @NotNull PsiManager manager)