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;
  }