@Override
  public @Nullable String getSignature(final @NotNull PsiElement element) {
    PsiFile file = element.getContainingFile();
    if (!(file instanceof PsiJavaFile)) {
      return null;
    }
    if (element instanceof PsiImportList) {
      if (element.equals(((PsiJavaFile)file).getImportList())) {
        return "imports";
      }
      else {
        return null;
      }
    }
    if (element instanceof PsiMethod method) {
      PsiElement parent = method.getParent();

      StringBuilder buffer = new StringBuilder();
      buffer.append("method").append(ELEMENT_TOKENS_SEPARATOR);
      String name = method.getName();
      buffer.append(name);
      buffer.append(ELEMENT_TOKENS_SEPARATOR);
      int childIndex = getChildIndex(method, parent, name, PsiMethod.class);
      if (childIndex < 0) return null;
      buffer.append(childIndex);

      if (parent instanceof PsiClass) {
        String parentSignature = getSignature(parent);
        if (parentSignature == null) return null;
        buffer.append(";");
        buffer.append(parentSignature);
      }

      return buffer.toString();
    }
    if (element instanceof PsiClass aClass) {
      PsiElement parent = aClass.getParent();

      StringBuilder buffer = new StringBuilder();
      buffer.append("class").append(ELEMENT_TOKENS_SEPARATOR);
      if (parent instanceof PsiClass || parent instanceof PsiFile) {
        String name = aClass.getName();
        buffer.append(name);
        buffer.append(ELEMENT_TOKENS_SEPARATOR);
        int childIndex = getChildIndex(aClass, parent, name, PsiClass.class);
        if (childIndex < 0) return null;
        buffer.append(childIndex);

        if (parent instanceof PsiClass) {
          String parentSignature = getSignature(parent);
          if (parentSignature == null) return null;
          buffer.append(ELEMENTS_SEPARATOR);
          buffer.append(parentSignature);
        }
      }
      else {
        buffer.append(aClass.getTextRange().getStartOffset());
        buffer.append(":");
        buffer.append(aClass.getTextRange().getEndOffset());
      }

      return buffer.toString();
    }
    if (element instanceof PsiClassInitializer initializer) {
      PsiElement parent = initializer.getParent();

      StringBuilder buffer = new StringBuilder();
      buffer.append("initializer").append(ELEMENT_TOKENS_SEPARATOR);

      int index = 0;
      PsiElement[] children = parent.getChildren();
      for (PsiElement child : children) {
        if (child instanceof PsiClassInitializer) {
          if (child.equals(initializer)) break;
          index++;
        }
      }
      buffer.append(ELEMENT_TOKENS_SEPARATOR);
      buffer.append(index);

      if (parent instanceof PsiClass) {
        String parentSignature = getSignature(parent);
        if (parentSignature == null) return null;
        buffer.append(ELEMENTS_SEPARATOR);
        buffer.append(parentSignature);
      }

      return buffer.toString();
    }
    if (element instanceof PsiField field) { // needed for doc-comments only
      PsiElement parent = field.getParent();

      StringBuilder buffer = new StringBuilder();
      buffer.append("field").append(ELEMENT_TOKENS_SEPARATOR);
      String name = field.getName();
      buffer.append(name);

      buffer.append(ELEMENT_TOKENS_SEPARATOR);
      int childIndex = getChildIndex(field, parent, name, PsiField.class);
      if (childIndex < 0) return null;
      buffer.append(childIndex);

      if (parent instanceof PsiClass) {
        String parentSignature = getSignature(parent);
        if (parentSignature == null) return null;
        buffer.append(ELEMENTS_SEPARATOR);
        buffer.append(parentSignature);
      }

      return buffer.toString();
    }
    if (element instanceof PsiDocComment) {
      StringBuilder buffer = new StringBuilder();
      buffer.append("docComment").append(ELEMENTS_SEPARATOR);

      PsiElement parent = element.getParent();
      if (!(parent instanceof PsiClass) && !(parent instanceof PsiMethod) && !(parent instanceof PsiField)) {
        return null;
      }
      if (!element.equals(((PsiDocCommentOwner)parent).getDocComment())) {
        return null;
      }
      String parentSignature = getSignature(parent);
      if (parentSignature == null) return null;
      buffer.append(parentSignature);

      return buffer.toString();
    }
    return null;
  }
@Override
  public @Nullable String getSignature(final @NotNull PsiElement element)