@Override
  protected PsiElement restoreBySignatureTokens(@NotNull PsiFile file,
                                                @NotNull PsiElement parent,
                                                @NotNull final String type,
                                                @NotNull StringTokenizer tokenizer,
                                                @Nullable StringBuilder processingInfoStorage)
  {
    if (!TYPE_MARKER.equals(type)) {
      if (processingInfoStorage != null) {
        processingInfoStorage.append(String.format(
          "Stopping '%s' provider because given signature doesn't have expected type - can work with '%s' but got '%s'%n",
          getClass().getName(), TYPE_MARKER, type
        ));
      }
      return null;
    }
    String elementMarker = tokenizer.nextToken();
    if (TOP_LEVEL_CHILD_MARKER.equals(elementMarker)) {
      PsiElement result = null;
      for (PsiElement child = file.getFirstChild(); child != null; child = child.getNextSibling()) {
        if (child instanceof PsiWhiteSpace) {
          continue;
        }
        if (result == null) {
          result = child;
        }
        else {
          if (processingInfoStorage != null) {
            processingInfoStorage.append(String.format(
              "Stopping '%s' provider because it has top level marker but more than one non white-space child: %s%n",
              getClass().getName(), Arrays.toString(file.getChildren())
            ));
          }
          // More than one top-level non-white space children. Can't match.
          return null;
        }
      }
      if (processingInfoStorage != null) {
        processingInfoStorage.append(String.format(
          "Finished processing of '%s' provider because all of its top-level children have been processed: %s%n",
          getClass().getName(), Arrays.toString(file.getChildren())
        ));
      }
      return result;
    }
    if (DOC_COMMENT_MARKER.equals(elementMarker)) {
      PsiElement candidate = parent.getFirstChild();
      return candidate instanceof PsiComment ? candidate : null;
    }
    if (CODE_BLOCK_MARKER.equals(elementMarker)) {
      int index = 0;
      if (tokenizer.hasMoreTokens()) {
        String indexStr = tokenizer.nextToken();
        try {
          index = Integer.parseInt(indexStr);
        }
        catch (NumberFormatException e) {
          if (processingInfoStorage != null) {
            processingInfoStorage.append("Invalid block index: ").append(indexStr).append("\n");
          }
        }
      }
      for (PsiElement child = parent.getFirstChild(); child != null; child = child.getNextSibling()) {
        if (isBlockElement(child)) {
          if (--index < 0) {
            return child;
          }
        }
      }
      return null;
    }

    if (!tokenizer.hasMoreTokens()) {
      if (processingInfoStorage != null) {
        processingInfoStorage.append(String.format("Stopping '%s' provider because it has no more data to process%n", getClass().getName()));
      }
      return null;
    }
    try {
      int index = Integer.parseInt(tokenizer.nextToken());
      if (processingInfoStorage != null) {
        processingInfoStorage.append(String.format("Looking for the child with a name '%s' # %d at the element '%s'%n",
                                                   elementMarker, index, parent));
      }
      return restoreElementInternal(parent, unescape(elementMarker), index, PsiNamedElement.class);
    }
    catch (NumberFormatException e) {
      return null;
    }
  }
@Override
  protected PsiElement restoreBySignatureTokens(@NotNull PsiFile file,
                                                @NotNull PsiElement parent,
                                                @NotNull final String type,
                                                @NotNull StringTokenizer tokenizer,
                                                @Nullable StringBuilder processingInfoStorage)