public static <Solution_> PartitionChangeMove<Solution_> createMove(
      InnerScoreDirector<Solution_> scoreDirector) {
    SolutionDescriptor<Solution_> solutionDescriptor = scoreDirector.getSolutionDescriptor();
    Solution_ workingSolution = scoreDirector.getWorkingSolution();

    int entityCount = solutionDescriptor.getEntityCount(workingSolution);
    Map<GenuineVariableDescriptor<Solution_>, List<Pair<Object, Object>>> changeMap =
        new LinkedHashMap<>(solutionDescriptor.getEntityDescriptors().size() * 3);
    for (EntityDescriptor<Solution_> entityDescriptor : solutionDescriptor.getEntityDescriptors()) {
      for (GenuineVariableDescriptor<Solution_> variableDescriptor :
          entityDescriptor.getDeclaredGenuineVariableDescriptors()) {
        changeMap.put(variableDescriptor, new ArrayList<>(entityCount));
      }
    }
    for (Iterator<Object> it = solutionDescriptor.extractAllEntitiesIterator(workingSolution);
        it.hasNext(); ) {
      Object entity = it.next();
      EntityDescriptor<Solution_> entityDescriptor =
          solutionDescriptor.findEntityDescriptorOrFail(entity.getClass());
      if (entityDescriptor.isMovable(scoreDirector, entity)) {
        for (GenuineVariableDescriptor<Solution_> variableDescriptor :
            entityDescriptor.getGenuineVariableDescriptors()) {
          Object value = variableDescriptor.getValue(entity);
          changeMap.get(variableDescriptor).add(Pair.of(entity, value));
        }
      }
    }
    return new PartitionChangeMove<>(changeMap);
  }