@Override
  public String getSignature(@NotNull PsiElement element) {
    TextRange range = element.getTextRange();
    if (range.isEmpty()) {
      return null;
    }
    StringBuilder buffer = new StringBuilder();
    buffer.append(TYPE_MARKER).append("#");
    buffer.append(range.getStartOffset());
    buffer.append(ELEMENT_TOKENS_SEPARATOR);
    buffer.append(range.getEndOffset());

    // There is a possible case that given PSI element has a parent or child that targets the same range. So, we remember
    // not only target range offsets but 'hierarchy index' as well.
    int index = getElementHierarchyIndex(element);

    buffer.append(ELEMENT_TOKENS_SEPARATOR).append(index);
    PsiFile containingFile = element.getContainingFile();
    if (containingFile != null && containingFile.getViewProvider().getLanguages().size() > 1) {
      buffer.append(ELEMENT_TOKENS_SEPARATOR).append(containingFile.getLanguage().getID());
    }
    return buffer.toString();
  }
@Override
  public String getSignature(@NotNull PsiElement element)