@Override
 public void flush() throws StorageException {
   final StubIndexImpl stubIndex = getStubIndex();
   try {
     for (StubIndexKey key : stubIndex.getAllStubIndexKeys()) {
       stubIndex.flush(key);
     }
   } finally {
     super.flush();
   }
 }
  private static void updateStubIndices(
      @NotNull final Collection<StubIndexKey> indexKeys,
      final int inputId,
      @NotNull final Map<StubIndexKey, Map<Object, int[]>> oldStubTree,
      @NotNull final Map<StubIndexKey, Map<Object, int[]>> newStubTree) {
    final StubIndexImpl stubIndex = (StubIndexImpl) StubIndex.getInstance();
    for (StubIndexKey key : indexKeys) {
      final Map<Object, int[]> oldMap = oldStubTree.get(key);
      final Map<Object, int[]> newMap = newStubTree.get(key);

      final Map<Object, int[]> _oldMap =
          oldMap != null ? oldMap : Collections.<Object, int[]>emptyMap();
      final Map<Object, int[]> _newMap =
          newMap != null ? newMap : Collections.<Object, int[]>emptyMap();

      stubIndex.updateIndex(key, inputId, _oldMap, _newMap);
    }
  }
 @Override
 public void clear() throws StorageException {
   final StubIndexImpl stubIndex = StubIndexImpl.getInstanceOrInvalidate();
   final Collection<StubIndexKey> allStubIndexKeys =
       stubIndex != null
           ? stubIndex.getAllStubIndexKeys()
           : Collections.<StubIndexKey>emptyList();
   try {
     for (StubIndexKey key : allStubIndexKeys) {
       //noinspection ConstantConditions
       stubIndex.getWriteLock(key).lock();
     }
     getWriteLock().lock();
     if (stubIndex != null) {
       stubIndex.clearAllIndices();
     }
     super.clear();
   } finally {
     getWriteLock().unlock();
     for (StubIndexKey key : allStubIndexKeys) {
       //noinspection ConstantConditions
       stubIndex.getWriteLock(key).unlock();
     }
   }
 }
    @Override
    protected void updateWithMap(
        final int inputId,
        @NotNull final Map<Integer, SerializedStubTree> newData,
        @NotNull Callable<Collection<Integer>> oldKeysGetter)
        throws StorageException {

      checkNameStorage();
      final Map<StubIndexKey, Map<Object, int[]>> newStubTree = getStubTree(newData);

      final StubIndexImpl stubIndex = getStubIndex();
      final Collection<StubIndexKey> allStubIndices = stubIndex.getAllStubIndexKeys();
      try {
        // first write-lock affected stub indices to avoid deadlocks
        for (StubIndexKey key : allStubIndices) {
          stubIndex.getWriteLock(key).lock();
        }

        try {
          getWriteLock().lock();

          final Map<Integer, SerializedStubTree> oldData = readOldData(inputId);
          final Map<StubIndexKey, Map<Object, int[]>> oldStubTree = getStubTree(oldData);

          super.updateWithMap(inputId, newData, oldKeysGetter);

          updateStubIndices(
              getAffectedIndices(oldStubTree, newStubTree), inputId, oldStubTree, newStubTree);
        } finally {
          getWriteLock().unlock();
        }
      } finally {
        for (StubIndexKey key : allStubIndices) {
          stubIndex.getWriteLock(key).unlock();
        }
      }
    }