private void initTimestampIndex(final boolean needReindex) {
    if (needReindex) {
      FileUtil.delete(IndexInfrastructure.getIndexRootDir(getFileTimestampsIndexId()));
    }
    for (int attempts = 0; attempts < 2; attempts++) {
      try {
        this.fileTimestampsIndex =
            new PersistentHashMap<Integer, Long>(
                IndexInfrastructure.getStorageFile(getFileTimestampsIndexId()),
                EnumeratorIntegerDescriptor.INSTANCE,
                new DataExternalizer<Long>() {
                  @Override
                  public void save(final DataOutput out, final Long value) throws IOException {
                    out.writeLong(value);
                  }

                  @Override
                  public Long read(final DataInput in) throws IOException {
                    return in.readLong();
                  }
                });
      } catch (IOException e) {
        FileUtil.delete(IndexInfrastructure.getIndexRootDir(getFileTimestampsIndexId()));
      }
      if (fileTimestampsIndex != null) {
        return;
      }
    }
    throw new RuntimeException("Timestamps index not initialized");
  }
  private void dropUnregisteredIndices() {
    final Set<String> indicesToDrop =
        new HashSet<String>(
            myPreviouslyRegistered != null
                ? myPreviouslyRegistered.registeredIndices
                : Collections.<String>emptyList());
    for (ID<?, ?> key : myIndices.keySet()) {
      indicesToDrop.remove(key.toString());
    }

    for (String s : indicesToDrop) {
      FileUtil.delete(IndexInfrastructure.getIndexRootDir(ID.create(s)));
    }
  }
  public static boolean canHaveStub(@NotNull VirtualFile file) {
    final FileType fileType = file.getFileType();
    if (fileType instanceof LanguageFileType) {
      Language l = ((LanguageFileType) fileType).getLanguage();
      ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(l);
      if (parserDefinition == null) return false;

      final IFileElementType elementType = parserDefinition.getFileNodeType();
      return elementType instanceof IStubFileElementType
          && (((IStubFileElementType) elementType).shouldBuildStubFor(file)
              || IndexingStamp.isFileIndexed(
                  file, INDEX_ID, IndexInfrastructure.getIndexCreationStamp(INDEX_ID)));
    }
    if (fileType.isBinary()) {
      final BinaryFileStubBuilder builder = BinaryFileStubBuilders.INSTANCE.forFileType(fileType);
      return builder != null && builder.acceptsFile(file);
    }

    return false;
  }
  private <K> boolean registerIndexer(
      final StubIndexExtension<K, ?> extension, final boolean forceClean) throws IOException {
    final StubIndexKey<K, ?> indexKey = extension.getKey();
    final int version = extension.getVersion();
    myIndexIdToVersionMap.put(indexKey, version);
    final File versionFile = IndexInfrastructure.getVersionFile(indexKey);
    final boolean versionFileExisted = versionFile.exists();
    final File indexRootDir = IndexInfrastructure.getIndexRootDir(indexKey);
    boolean needRebuild = false;
    if (forceClean || IndexInfrastructure.versionDiffers(versionFile, version)) {
      final String[] children = indexRootDir.list();
      // rebuild only if there exists what to rebuild
      needRebuild = !forceClean && (versionFileExisted || children != null && children.length > 0);
      if (needRebuild) {
        LOG.info(
            "Version has changed for stub index "
                + extension.getKey()
                + ". The index will be rebuilt.");
      }
      FileUtil.delete(indexRootDir);
      IndexInfrastructure.rewriteVersion(versionFile, version);
    }

    for (int attempt = 0; attempt < 2; attempt++) {
      try {
        final MapIndexStorage<K, TIntArrayList> storage =
            new MapIndexStorage<K, TIntArrayList>(
                IndexInfrastructure.getStorageFile(indexKey),
                extension.getKeyDescriptor(),
                new StubIdExternalizer(),
                2 * 1024);
        final MemoryIndexStorage<K, TIntArrayList> memStorage =
            new MemoryIndexStorage<K, TIntArrayList>(storage);
        myIndices.put(indexKey, new MyIndex<K>(memStorage));
        break;
      } catch (IOException e) {
        LOG.info(e);
        needRebuild = true;
        FileUtil.delete(indexRootDir);
        IndexInfrastructure.rewriteVersion(versionFile, version);
      }
    }
    return needRebuild;
  }