/**
  * Resolve the latest value for the {@link ValueDefinition} from the {@link ConfigurationSource}
  * and encapsulate it in a {@link ValueChangeAction} to be enacted in a subsequent operation.
  *
  * @param valueDefinition the value definition to prepare an update for
  * @param configurationSource the source from which to resolve the value.
  * @return the change action
  * @throws ConfigurationException if any problem occurs retrieving the value.
  */
 public ValueChangeAction prepareValueChange(
     ValueDefinition<?, ?> valueDefinition, ConfigurationSource configurationSource) {
   String expression = valueDefinition.getExpression();
   Class<?> type = valueDefinition.getType();
   Object result;
   boolean available;
   if (expression != null) {
     available = configurationSource.isAvailable(expression);
   } else {
     available = configurationSource.isAvailable(type);
   }
   if (available) {
     if (valueDefinition instanceof ValueListDefinition) {
       if (expression != null) {
         result = configurationSource.retrieveList(expression, type);
       } else {
         result = configurationSource.retrieveList(type);
       }
     } else {
       if (expression != null) {
         result = configurationSource.retrieve(expression, type);
       } else {
         result = configurationSource.retrieve(type);
       }
     }
   } else if (valueDefinition.isRequired()) {
     throw new ValueConfigurationException("No value could be found for", type, expression);
   } else {
     // Not required and not available, set to null. How this is handled is assignment specific.
     result = null;
   }
   return new ValueChangeAction(valueDefinition, result);
 }
 /**
  * Carry out the change to the value by invoking the {@link ValueChangeListener} with the value
  * resolved by {@link #prepareValueChange(ValueDefinition, ConfigurationSource)}.
  *
  * @param valueChangeAction the action to perform
  * @throws ValueConfigurationException if the listener throws a {@link RuntimeException}.
  */
 @SuppressWarnings({"rawtypes", "unchecked"})
 public void enactValueChange(ValueChangeAction valueChangeAction) {
   ValueDefinition<?, ?> valueDefinition = valueChangeAction.getValueDefinition();
   Object newValue = valueChangeAction.getNewValue();
   Object oldValue = valueChangeAction.getOldValue();
   ValueChangeListener listener = valueDefinition.getChangeListener();
   try {
     listener.onChange(newValue, oldValue);
   } catch (RuntimeException e) {
     throw new ValueConfigurationException(
         "value assignment", valueDefinition.getType(), valueDefinition.getExpression(), e);
   }
 }