private void saveMigratorSequence(
     SessionImpl session, DependencySequence migratorDependencySequence)
     throws AccessDeniedException, StorageClientException {
   Content runMigrators = session.getContentManager().get(SYSTEM_MIGRATION_CONTENT_ITEM);
   String ts = String.valueOf(System.currentTimeMillis());
   int i = 0;
   if (runMigrators == null) {
     Builder<String, Object> b = ImmutableMap.builder();
     for (PropertyMigrator pm : migratorDependencySequence) {
       b.put(pm.getName(), ts + ";" + i);
     }
     runMigrators = new Content(SYSTEM_MIGRATION_CONTENT_ITEM, b.build());
   } else {
     for (PropertyMigrator pm : migratorDependencySequence) {
       runMigrators.setProperty(pm.getName(), ts + ";" + i);
     }
   }
   session.getContentManager().update(runMigrators);
 }
 private DependencySequence getMigratorSequence(
     SessionImpl session, PropertyMigrator[] propertyMigrators)
     throws StorageClientException, AccessDeniedException {
   Content runMigrators = session.getContentManager().get(SYSTEM_MIGRATION_CONTENT_ITEM);
   Map<String, Object> runMigratorRecord = ImmutableMap.of();
   if (runMigrators != null) {
     runMigratorRecord = runMigrators.getProperties();
   }
   return new DependencySequence(propertyMigrators, runMigratorRecord);
 }
  public synchronized void migrate(boolean dryRun, int limit, boolean reindexAll, Feedback feedback)
      throws ClientPoolException, StorageClientException, AccessDeniedException, IOException,
          PropertyMigrationException {
    SessionImpl session = (SessionImpl) repository.loginAdministrative();
    StorageClient client = session.getClient();
    FileRedoLogger migrateRedoLog = new FileRedoLogger(redoLogLocation, maxLogFileSize, feedback);
    client.setStorageClientListener(migrateRedoLog);
    try {
      if (client instanceof JDBCStorageClient) {
        JDBCStorageClient jdbcClient = (JDBCStorageClient) client;
        String keySpace = configuration.getKeySpace();

        Indexer indexer = jdbcClient.getIndexer();

        PropertyMigrator[] propertyMigrators = propertyMigratorTracker.getPropertyMigrators();

        DependencySequence migratorDependencySequence =
            getMigratorSequence(session, propertyMigrators);

        for (PropertyMigrator p : migratorDependencySequence) {
          LOGGER.info("DryRun:{} Using Property Migrator {} ", dryRun, p);
          feedback.log("DryRun:{0} Using Property Migrator {1} ", dryRun, p);
        }
        for (PropertyMigrator p : migratorDependencySequence.getUnresolved()) {
          LOGGER.info("DryRun:{} Unresolved Property Migrator {} ", dryRun, p);
          feedback.log("DryRun:{0} Unresolved Property Migrator {1} ", dryRun, p);
        }
        for (Entry<String, Object> p : migratorDependencySequence.getAlreadyRun().entrySet()) {
          LOGGER.info("DryRun:{} Migrator Last Run {} ", dryRun, p);
          feedback.log("DryRun:{0} Migrator Last Run {1} ", dryRun, p);
        }
        if (migratorDependencySequence.hasUnresolved()) {
          throw new PropertyMigrationException(
              "There are unresolved dependencies " + migratorDependencySequence.getUnresolved());
        }
        CacheAwareMigrationManager cacheAwareMigrationManager =
            new CacheAwareMigrationManager(
                jdbcClient, session.getCache(configuration.getAuthorizableColumnFamily()));
        reindex(
            dryRun,
            jdbcClient,
            cacheAwareMigrationManager,
            keySpace,
            configuration.getAuthorizableColumnFamily(),
            indexer,
            migratorDependencySequence,
            new IdExtractor() {

              public String getKey(Map<String, Object> properties) {
                if (properties.containsKey(Authorizable.ID_FIELD)) {
                  return (String) properties.get(Authorizable.ID_FIELD);
                }
                return null;
              }
            },
            limit,
            feedback,
            reindexAll);

        cacheAwareMigrationManager =
            new CacheAwareMigrationManager(
                jdbcClient, session.getCache(configuration.getContentColumnFamily()));
        reindex(
            dryRun,
            jdbcClient,
            cacheAwareMigrationManager,
            keySpace,
            configuration.getContentColumnFamily(),
            indexer,
            migratorDependencySequence,
            new IdExtractor() {

              public String getKey(Map<String, Object> properties) {
                if (properties.containsKey(BlockSetContentHelper.CONTENT_BLOCK_ID)) {
                  // blocks of a bit stream
                  return (String) properties.get(BlockSetContentHelper.CONTENT_BLOCK_ID);
                } else if (properties.containsKey(Content.UUID_FIELD)) {
                  // a content item and content block item
                  return (String) properties.get(Content.UUID_FIELD);
                } else if (properties.containsKey(Content.STRUCTURE_UUID_FIELD)) {
                  // a structure item
                  return (String) properties.get(Content.PATH_FIELD);
                }
                return null;
              }
            },
            limit,
            feedback,
            reindexAll);

        cacheAwareMigrationManager =
            new CacheAwareMigrationManager(
                jdbcClient, session.getCache(configuration.getAclColumnFamily()));
        reindex(
            dryRun,
            jdbcClient,
            cacheAwareMigrationManager,
            keySpace,
            configuration.getAclColumnFamily(),
            indexer,
            migratorDependencySequence,
            new IdExtractor() {
              public String getKey(Map<String, Object> properties) {
                if (properties.containsKey(AccessControlManagerImpl._KEY)) {
                  return (String) properties.get(AccessControlManagerImpl._KEY);
                }
                return null;
              }
            },
            limit,
            feedback,
            reindexAll);

        saveMigratorSequence(session, migratorDependencySequence);

      } else {
        LOGGER.warn("This class will only re-index content for the JDBCStorageClients");
      }
    } finally {
      client.setStorageClientListener(null);
      migrateRedoLog.close();
      session.logout();
    }
  }