docs: public TitanManagement.IndexJobFuture updateIndex(TitanIndex index, SchemaAction updateAction)
              throws BackendException {
  
          Preconditions.checkNotNull(index, "Index parameter must not be null", index);
          Preconditions.checkNotNull(updateAction, "%s parameter must not be null", SchemaAction.class.getSimpleName());
          Preconditions.checkArgument(SUPPORTED_ACTIONS.contains(updateAction),
                  "Only these %s parameters are supported: %s (was given %s)",
                  SchemaAction.class.getSimpleName(), SUPPORTED_ACTIONS_STRING, updateAction);
          Preconditions.checkArgument(
                  RelationTypeIndex.class.isAssignableFrom(index.getClass()) ||
                          TitanGraphIndex.class.isAssignableFrom(index.getClass()),
                  "Index %s has class %s: must be a %s or %s (or subtype)",
                  index.getClass(), RelationTypeIndex.class.getSimpleName(), TitanGraphIndex.class.getSimpleName());
  
          org.apache.hadoop.conf.Configuration hadoopConf = new org.apache.hadoop.conf.Configuration();
          ModifiableHadoopConfiguration titanmrConf =
                  ModifiableHadoopConfiguration.of(TitanHadoopConfiguration.MAPRED_NS, hadoopConf);
  
          // The job we'll execute to either REINDEX or REMOVE_INDEX
          final Class<? extends IndexUpdateJob> indexJobClass;
          final Class<? extends Mapper> mapperClass;
  
          // The class of the IndexUpdateJob and the Mapper that will be used to run it (VertexScanJob vs ScanJob)
          if (updateAction.equals(SchemaAction.REINDEX)) {
              indexJobClass = IndexRepairJob.class;
              mapperClass = HadoopVertexScanMapper.class;
          } else if (updateAction.equals(SchemaAction.REMOVE_INDEX)) {
              indexJobClass = IndexRemoveJob.class;
              mapperClass = HadoopScanMapper.class;
          } else {
              // Shouldn't get here -- if this exception is ever thrown, update SUPPORTED_ACTIONS
              throw new IllegalStateException("Unrecognized " + SchemaAction.class.getSimpleName() + ": " + updateAction);
          }
  
          // The column family that serves as input to the IndexUpdateJob
          final String readCF;
          if (RelationTypeIndex.class.isAssignableFrom(index.getClass())) {
              readCF = Backend.EDGESTORE_NAME;
          } else {
              TitanGraphIndex gindex = (TitanGraphIndex)index;
              if (gindex.isMixedIndex() && !updateAction.equals(SchemaAction.REINDEX))
                  throw new UnsupportedOperationException("External mixed indexes must be removed in the indexing system directly.");
  
              Preconditions.checkState(TitanGraphIndex.class.isAssignableFrom(index.getClass()));
              if (updateAction.equals(SchemaAction.REMOVE_INDEX))
                  readCF = Backend.INDEXSTORE_NAME;
              else
                  readCF = Backend.EDGESTORE_NAME;
          }
          titanmrConf.set(TitanHadoopConfiguration.COLUMN_FAMILY_NAME, readCF);
  
          // The MapReduce InputFormat class based on the open graph's store manager
          final Class<? extends InputFormat> inputFormat;
          final Class<? extends KeyColumnValueStoreManager> storeManagerClass =
                  graph.getBackend().getStoreManagerClass();
          if (CASSANDRA_STORE_MANAGER_CLASSES.contains(storeManagerClass)) {
              inputFormat = CassandraBinaryInputFormat.class;
              // Set the partitioner
              IPartitioner part =
                      ((AbstractCassandraStoreManager)graph.getBackend().getStoreManager()).getCassandraPartitioner();
              hadoopConf.set("cassandra.input.partitioner.class", part.getClass().getName());
          } else if (HBASE_STORE_MANAGER_CLASSES.contains(storeManagerClass)) {
              inputFormat = HBaseBinaryInputFormat.class;
          } else {
              throw new IllegalArgumentException("Store manager class " + storeManagerClass + "is not supported");
          }
  
          // The index name and relation type name (if the latter is applicable)
          final String indexName = index.name();
          final String relationTypeName =
                  RelationTypeIndex.class.isAssignableFrom(index.getClass()) ?
                  ((RelationTypeIndex)index).getType().name() :
                  "";
          Preconditions.checkNotNull(indexName);
  
          // Set the class of the IndexUpdateJob
          titanmrConf.set(TitanHadoopConfiguration.SCAN_JOB_CLASS, indexJobClass.getName());
          // Set the configuration of the IndexUpdateJob
          copyIndexJobKeys(hadoopConf, indexName, relationTypeName);
          titanmrConf.set(TitanHadoopConfiguration.SCAN_JOB_CONFIG_ROOT,
                  GraphDatabaseConfiguration.class.getName() + "#JOB_NS");
          // Copy the StandardTitanGraph configuration under TitanHadoopConfiguration.GRAPH_CONFIG_KEYS
          org.apache.commons.configuration.Configuration localbc = graph.getConfiguration().getLocalConfiguration();
          localbc.clearProperty(Graph.GRAPH);
          copyInputKeys(hadoopConf, localbc);
  
          String jobName = HadoopScanMapper.class.getSimpleName() + "[" + indexJobClass.getSimpleName() + "]";
  
          try {
              return new CompletedJobFuture(HadoopScanRunner.runJob(hadoopConf, inputFormat, jobName, mapperClass));
          } catch (Exception e) {
              return new FailedJobFuture(e);
          }
      }