docs: private <N, S extends State, SV> void migrateStateValues(
  		StateDescriptor<S, SV> stateDesc,
  		Tuple2<ColumnFamilyHandle, RegisteredKeyValueStateBackendMetaInfo<N, SV>> stateMetaInfo) throws Exception {
  
  		if (stateDesc.getType() == StateDescriptor.Type.MAP) {
  			throw new StateMigrationException("The new serializer for a MapState requires state migration in order for the job to proceed." +
  				" However, migration for MapState currently isn't supported.");
  		}
  
  		LOG.info(
  			"Performing state migration for state {} because the state serializer's schema, i.e. serialization format, has changed.",
  			stateDesc);
  
  		// we need to get an actual state instance because migration is different
  		// for different state types. For example, ListState needs to deal with
  		// individual elements
  		StateFactory stateFactory = STATE_FACTORIES.get(stateDesc.getClass());
  		if (stateFactory == null) {
  			String message = String.format("State %s is not supported by %s",
  				stateDesc.getClass(), this.getClass());
  			throw new FlinkRuntimeException(message);
  		}
  		State state = stateFactory.createState(
  			stateDesc,
  			stateMetaInfo,
  			RocksDBKeyedStateBackend.this);
  		if (!(state instanceof AbstractRocksDBState)) {
  			throw new FlinkRuntimeException(
  				"State should be an AbstractRocksDBState but is " + state);
  		}
  
  		@SuppressWarnings("unchecked")
  		AbstractRocksDBState<?, ?, SV> rocksDBState = (AbstractRocksDBState<?, ?, SV>) state;
  
  		Snapshot rocksDBSnapshot = db.getSnapshot();
  		try (
  			RocksIteratorWrapper iterator = RocksDBOperationUtils.getRocksIterator(db, stateMetaInfo.f0);
  			RocksDBWriteBatchWrapper batchWriter = new RocksDBWriteBatchWrapper(db, getWriteOptions())
  		) {
  			iterator.seekToFirst();
  
  			DataInputDeserializer serializedValueInput = new DataInputDeserializer();
  			DataOutputSerializer migratedSerializedValueOutput = new DataOutputSerializer(512);
  			while (iterator.isValid()) {
  				serializedValueInput.setBuffer(iterator.value());
  
  				rocksDBState.migrateSerializedValue(
  					serializedValueInput,
  					migratedSerializedValueOutput,
  					stateMetaInfo.f1.getPreviousStateSerializer(),
  					stateMetaInfo.f1.getStateSerializer());
  
  				batchWriter.put(stateMetaInfo.f0, iterator.key(), migratedSerializedValueOutput.getCopyOfBuffer());
  
  				migratedSerializedValueOutput.clear();
  				iterator.next();
  			}
  		} finally {
  			db.releaseSnapshot(rocksDBSnapshot);
  			rocksDBSnapshot.close();
  		}
  	}