/**
   * Initializes this class with all {@link Parameters} as generated by the given {@link
   * ISimulationParametersInitializer}s.<br>
   * This method will adopt parameters if there are any already.<br>
   * If you don't want that, call {@link
   * SimulationParameters#init(ISimulationParametersInitializer...)} or destroy existing Parameters
   * first.<br>
   * Be aware that if this method is called several times (after first calling the destroy method),
   * the old {@link Parameters} are gone. All registered {@link IParameterChangeListener}s are then
   * informed that the {@link Parameters} are new ones.
   *
   * @param parameterInitializers the concrete {@link ISimulationParametersInitializer}s that
   *     initialize the {@link SimulationParametersProvider}
   */
  public static void initOrAdopt(ISimulationParametersInitializer... parameterInitializers) {

    // either create a new parameters object or use the old one instead
    Parameters parameters = null;
    if (SimulationParameters.myParamProvider != null) {
      parameters = SimulationParameters.myParamProvider.getParameters();
      SimulationParameters.LOG.info("Adopted existing simulation parameters.");
    } else {
      parameters = new Parameters();
    }

    // merge all parameters as returned by the given simulation parameter initializers into one
    // object
    for (ISimulationParametersInitializer parameterInitializer : parameterInitializers) {
      parameters.addAllParameters(parameterInitializer.initializeSimulationParameters());
    }

    // initialize the simulation parameters provider
    SimulationParameters.myParamProvider = new SimulationParametersProvider(parameters);
    SimulationParameters.myParamProvider.getParameters();

    // refresh parameters of all available parameter listeners
    synchronized (SimulationParameters.parameterChangeListeners) {
      for (IParameterChangeListener parameterChangeListener :
          SimulationParameters.parameterChangeListeners) {
        SimulationParameters.LOG.debug(
            "Refreshing parameter listener '"
                + parameterChangeListener.getClass().getSimpleName()
                + "'.");
        parameterChangeListener.refreshParameters();
      }
    }
  }
 /**
  * Checks whether the {@link SimulationParameters} are currently in the modify state and if so
  * throws an {@link IllegalStateException}.
  */
 private static void checkSimulationParametersState() {
   if (SimulationParameters.modifyingSimulationParametersState) {
     SimulationParameters.LOG.throwing(
         new IllegalStateException(
             "SimulationParameters are currently in the modify state. Retrieval of parameters is thus currently discouraged until this state is left (see SimulationParametersModifier)."));
   }
 }
  /**
   * Initializes this class with all {@link Parameters} as generated by the given {@link
   * ISimulationParametersInitializer}s. <br>
   * <br>
   * Be aware that if this method is called several times (after first calling the destroy method),
   * the old {@link Parameters} are gone. All registered {@link IParameterChangeListener}s are then
   * informed that the {@link Parameters} are new ones.
   *
   * @param parameterInitializers the concrete {@link ISimulationParametersInitializer}s that
   *     initialize the {@link SimulationParametersProvider}
   * @throwing {@link IllegalStateException} if there is already a {@link
   *     SimulationParametersProvider} which has not been destroyed
   */
  public static void init(ISimulationParametersInitializer... parameterInitializers) {

    // just for info: the old simulation parameters provider is now replaced by a new one
    if (SimulationParameters.myParamProvider != null) {
      throw SimulationParameters.LOG.throwing(
          new IllegalStateException(
              "There was already an old SimulationParametersProvider present. You cannot initialize a new SimulationParametersProvider without explicitly destroying the old one first!"));
    }

    // then we are going to initialize from a fresh base
    SimulationParameters.initOrAdopt(parameterInitializers);
  }
 /**
  * Logs a warn message if the parameter does not exist and the default value has to be used.
  *
  * @param parameterName the name of the parameter
  * @param defaultVal the default value of the parameter
  */
 private static void warnDefaultValueMessage(String parameterName, Object defaultVal) {
   String defaultValAsString;
   if (defaultVal == null) {
     defaultValAsString = "null";
   } else if (defaultVal.getClass().isArray()) {
     defaultValAsString = Arrays.toString((Object[]) defaultVal);
   } else {
     defaultValAsString = defaultVal.toString();
   }
   SimulationParameters.LOG.warn(
       "Parameter '"
           + parameterName
           + "' does not exist. Using default value '"
           + defaultValAsString
           + "'.");
 }
 /**
  * Logs an error message if the parameter does not exist and the given default value is not the
  * same as in a previous parameter request.
  *
  * @param parameterName the name of the parameter
  * @param givenDefaultValue the default value of the parameter
  * @param savedDefaultValue the saved default value of the parameter
  */
 private static void warnWrongDefaultValueMessage(
     String parameterName, Object givenDefaultValue, Object savedDefaultValue) {
   String givenDefaultValAsString = givenDefaultValue.toString();
   String savedDefaultValueAsString = savedDefaultValue.toString();
   if (givenDefaultValue.getClass().isArray()) {
     givenDefaultValAsString = Arrays.toString((Object[]) givenDefaultValue);
     savedDefaultValueAsString = Arrays.toString((Object[]) savedDefaultValue);
   }
   SimulationParameters.LOG.error(
       "Parameter '"
           + parameterName
           + "' does not exist. The given default value '"
           + givenDefaultValAsString
           + "' is, however, not the same as the default value that was used before and that will be further used ('"
           + savedDefaultValueAsString
           + "').");
 }
 /**
  * Adds a new {@link IParameterChangeListener} to the set of {@link IParameterChangeListener}s
  * that are informed if the {@link Parameters}s have changed.
  *
  * @param parameterChangeListener the {@link IParameterChangeListener} to add
  */
 public static void addParameterChangeListener(IParameterChangeListener parameterChangeListener) {
   SimulationParameters.LOG.debug(
       "Adding parameter listener '" + parameterChangeListener.getClass().getSimpleName() + "'.");
   SimulationParameters.parameterChangeListeners.add(parameterChangeListener);
 }