std::vector<std::list<Parameterization> > ParameterizedCommand::ExpandParameters(
    unsigned int startIndex, const std::vector<IParameter::Pointer>& parameters)
{
  typedef std::vector<std::list<Parameterization> > ReturnType;

  const unsigned int nextIndex = startIndex + 1;
  const bool noMoreParameters = (nextIndex >= parameters.size());

  const IParameter::Pointer parameter(parameters[startIndex]);
  ReturnType parameterizations;

  if (parameter->IsOptional())
  {
    parameterizations.push_back(std::list<Parameterization>());
  }

  IParameter::ParameterValues parameterValues(parameter->GetValues());
  for (IParameter::ParameterValues::iterator parameterValueItr =
      parameterValues.begin(); parameterValueItr != parameterValues.end(); ++parameterValueItr)
  {
    std::list<Parameterization> combination;
    combination.push_back(
        Parameterization(parameter, parameterValueItr->second));
    parameterizations.push_back(combination);
  }

  // Check if another iteration will produce any more names.
  if (noMoreParameters)
  {
    // This is it, so just return the current parameterizations.
    return parameterizations;
  }

  // Make recursive call
  ReturnType suffixes(ExpandParameters(nextIndex, parameters));
  if (suffixes.empty())
  {
    // This is it, so just return the current parameterizations.
    return parameterizations;
  }

  ReturnType returnValue;
  for (ReturnType::iterator suffixItr = suffixes.begin(); suffixItr
      != suffixes.end(); ++suffixItr)
  {
    for (ReturnType::iterator combinationItr = parameterizations.begin(); combinationItr
        != parameterizations.end(); ++combinationItr)
    {
      std::list<Parameterization> newCombination(*combinationItr);
      newCombination.insert(newCombination.end(), suffixItr->begin(),
          suffixItr->end());
      returnValue.push_back(newCombination);
    }
  }

  return returnValue;
}
QList<ParameterizedCommand::Pointer>
ParameterizedCommand::GenerateCombinations(const SmartPointer<Command> command)
{
  QList<IParameter::Pointer> parameters(command->GetParameters());

  typedef QList<QList<Parameterization> > ExpandedParamsType;
  const ExpandedParamsType expansion(ExpandParameters(0, parameters));
  QList<ParameterizedCommand::Pointer> combinations;

  for (ExpandedParamsType::const_iterator expansionItr = expansion.begin();
      expansionItr != expansion.end(); ++expansionItr)
  {
    QList<Parameterization> combination(*expansionItr);

    QList<Parameterization> parameterizations(combination);
    ParameterizedCommand::Pointer pCmd(new ParameterizedCommand(command,
            parameterizations));
    combinations.push_back(pCmd);
  }

  return combinations;
}
std::vector<ParameterizedCommand::Pointer>
ParameterizedCommand::GenerateCombinations(const SmartPointer<Command> command)
throw(NotDefinedException)
{
  std::vector<IParameter::Pointer> parameters(command->GetParameters());

  typedef std::vector<std::list<Parameterization> > ExpandedParamsType;
  const ExpandedParamsType expansion(ExpandParameters(0, parameters));
  std::vector<ParameterizedCommand::Pointer> combinations;

  for (ExpandedParamsType::const_iterator expansionItr = expansion.begin();
      expansionItr != expansion.end(); ++expansionItr)
  {
    std::list<Parameterization> combination(*expansionItr);

    std::vector<Parameterization> parameterizations(combination.begin(), combination.end());
    ParameterizedCommand::Pointer pCmd(new ParameterizedCommand(command,
            parameterizations));
    combinations.push_back(pCmd);
  }

  return combinations;
}
QList<QList<Parameterization> > ParameterizedCommand::ExpandParameters(
    unsigned int startIndex, const QList<IParameter::Pointer>& parameters)
{
  typedef QList<QList<Parameterization> > ReturnType;

  const int nextIndex = startIndex + 1;
  const bool noMoreParameters = (nextIndex >= parameters.size());

  const IParameter::Pointer parameter(parameters[startIndex]);
  ReturnType parameterizations;

  if (parameter->IsOptional())
  {
    parameterizations.push_back(QList<Parameterization>());
  }

  IParameterValues* values = NULL;
  try
  {
    values = parameter->GetValues();
  }
  catch (const ParameterValuesException& /*e*/)
  {
    if (noMoreParameters)
    {
      return parameterizations;
    }

    // Make recursive call
    return ExpandParameters(nextIndex, parameters);
  }

  const QHash<QString,QString> parameterValues = values->GetParameterValues();
  for (IParameter::ParameterValues::const_iterator parameterValueItr =
      parameterValues.begin(); parameterValueItr != parameterValues.end(); ++parameterValueItr)
  {
    QList<Parameterization> combination;
    combination.push_back(
        Parameterization(parameter, parameterValueItr.value()));
    parameterizations.push_back(combination);
  }

  // Check if another iteration will produce any more names.
  if (noMoreParameters)
  {
    // This is it, so just return the current parameterizations.
    return parameterizations;
  }

  // Make recursive call
  ReturnType suffixes(ExpandParameters(nextIndex, parameters));
  if (suffixes.empty())
  {
    // This is it, so just return the current parameterizations.
    return parameterizations;
  }

  ReturnType returnValue;
  for (ReturnType::iterator suffixItr = suffixes.begin(); suffixItr
      != suffixes.end(); ++suffixItr)
  {
    for (ReturnType::iterator combinationItr = parameterizations.begin(); combinationItr
        != parameterizations.end(); ++combinationItr)
    {
      QList<Parameterization> newCombination(*combinationItr);
      newCombination.append(*suffixItr);
      returnValue.push_back(newCombination);
    }
  }

  return returnValue;
}