private static <K, V> IntSet initIndexStorage(@NotNull FileBasedIndexExtension<K, V> extension,
                                                int version,
                                                @NotNull IndexConfiguration state,
                                                @NotNull IndexVersionRegistrationSink registrationStatusSink,
                                                @NotNull IntSet dirtyFiles) throws Exception {
    ID<K, V> name = extension.getName();
    InputFilter inputFilter = extension.getInputFilter();

    UpdatableIndex<K, V, FileContent, ?> index = null;

    int attemptCount = 2;
    for (int attempt = 0; attempt < attemptCount; attempt++) {
      try {
        VfsAwareIndexStorageLayout<K, V> layout = IndexStorageLayoutLocator.getLayout(extension);
        index = createIndex(extension, layout);

        for (FileBasedIndexInfrastructureExtension infrastructureExtension : FileBasedIndexInfrastructureExtension.EP_NAME.getExtensionList()) {
          UpdatableIndex<K, V, FileContent, ?> intermediateIndex = infrastructureExtension.combineIndex(extension, index);
          if (intermediateIndex != null) {
            index = intermediateIndex;
          }
        }

        state.registerIndex(name,
                            index,
                            inputFilter,
                            version + GlobalIndexFilter.getFiltersVersion(name));
        break;
      }
      catch (Exception e) {
        boolean lastAttempt = attempt == attemptCount - 1;

        try {
          VfsAwareIndexStorageLayout<K, V> layout = IndexStorageLayoutLocator.getLayout(extension);
          layout.clearIndexData();
        }
        catch (Exception layoutEx) {
          LOG.error(layoutEx);
        }

        for (FileBasedIndexInfrastructureExtension ext : FileBasedIndexInfrastructureExtension.EP_NAME.getExtensionList()) {
          try {
            ext.resetPersistentState(name);
          }
          catch (Exception extEx) {
            LOG.error(extEx);
          }
        }

        registrationStatusSink.setIndexVersionDiff(name, new IndexVersion.IndexVersionDiff.CorruptedRebuild(version));
        IndexVersion.rewriteVersion(name, version);
        IndexStatisticGroup.reportIndexRebuild(name, e, true);

        if (lastAttempt) {
          state.registerIndexInitializationProblem(name, e);
          if (extension instanceof CustomImplementationFileBasedIndexExtension) {
            ((CustomImplementationFileBasedIndexExtension<?, ?>)extension).handleInitializationError(e);
          }
          throw e;
        }
        else if (ApplicationManager.getApplication().isUnitTestMode()) {
          LOG.error(e);
        }
        else {
          String message = "Attempt #" + attemptCount + " to initialize index has failed for " + extension.getName();
          //noinspection InstanceofCatchParameter
          if (e instanceof CorruptedException) {
            LOG.warn(message + " because storage corrupted");
          }
          else {
            LOG.warn(message, e);
          }
        }
      }
    }

    try {
      if (shouldCheckStaleIndexesOnStartup() && StubUpdatingIndex.INDEX_ID.equals(extension.getName()) && index != null) {
        return StaleIndexesChecker.checkIndexForStaleRecords(index, dirtyFiles, true);
      }
    }
    catch (Exception e) {
      LOG.error("Exception while checking for stale records", e);
    }
    return new IntOpenHashSet();
  }
private static <K, V> IntSet initIndexStorage(@NotNull FileBasedIndexExtension<K, V> extension,
                                                int version,
                                                @NotNull IndexConfiguration state,
                                                @NotNull IndexVersionRegistrationSink registrationStatusSink,
                                                @NotNull IntSet dirtyFiles)