class OriginalListChangeIterator<Solution_> extends UpcomingSelectionIterator<Move<Solution_>> {

    private final SingletonInverseVariableSupply inverseVariableSupply;
    private final IndexVariableSupply indexVariableSupply;
    private final ListVariableDescriptor<Solution_> listVariableDescriptor;
    private final Iterator<Object> valueIterator;
    private final DestinationSelector<Solution_> destinationSelector;
    private Iterator<ElementRef> destinationIterator;

    private Object upcomingSourceEntity;
    private Integer upcomingSourceIndex;
    private Object upcomingValue;

    public OriginalListChangeIterator(
            SingletonInverseVariableSupply inverseVariableSupply,
            IndexVariableSupply indexVariableSupply,
            EntityIndependentValueSelector<Solution_> valueSelector,
            DestinationSelector<Solution_> destinationSelector) {
        this.inverseVariableSupply = inverseVariableSupply;
        this.indexVariableSupply = indexVariableSupply;
        this.listVariableDescriptor = (ListVariableDescriptor<Solution_>) valueSelector.getVariableDescriptor();
        this.valueIterator = valueSelector.iterator();
        this.destinationSelector = destinationSelector;
        this.destinationIterator = Collections.emptyIterator();
    }

    @Override
    protected Move<Solution_> createUpcomingSelection() {<FILL_FUNCTION_BODY>}
}

        while (!destinationIterator.hasNext()) {
            if (!valueIterator.hasNext()) {
                return noUpcomingSelection();
            }
            upcomingValue = valueIterator.next();
            upcomingSourceEntity = inverseVariableSupply.getInverseSingleton(upcomingValue);
            upcomingSourceIndex = indexVariableSupply.getIndex(upcomingValue);

            destinationIterator = destinationSelector.iterator();
        }

        ElementRef destination = destinationIterator.next();

        if (upcomingSourceEntity == null && upcomingSourceIndex == null) {
            return new ListAssignMove<>(
                    listVariableDescriptor,
                    upcomingValue,
                    destination.getEntity(),
                    destination.getIndex());
        }

        // No need to generate ListUnassignMove because they are only used as undo moves.

        return new ListChangeMove<>(
                listVariableDescriptor,
                upcomingSourceEntity,
                upcomingSourceIndex,
                destination.getEntity(),
                destination.getIndex());
    
<methods>public non-sealed void <init>() ,public boolean hasNext() ,public Move<Solution_> next() ,public java.lang.String toString() <variables>protected boolean hasUpcomingSelection,protected boolean upcomingCreated,protected Move<Solution_> upcomingSelection