}
/**
+ * \brief Replaces new step to installer by specified type
+ * Type of template parameter is used to create requested step
+ * class instance.
+ * Context of installer is passed to step in this method
+ * and is not being exposed outside installer.
+ * Step arguments are deduced and forwarded to constructor.
+ * \tparam StepT Step object to be added to the step list
+ * \tparam Args constructor arguments for StepT object
+ * \param step_name step name to replace
+ * \param args argument list
+ */
+ template<class StepT, class... Args>
+ void ReplaceStep(std::string step_name, Args&&... args) {
+ auto it = std::find_if(std::begin(steps_), std::end(steps_),
+ [&](const std::unique_ptr<Step>& s) {
+ return step_name == s->name();
+ });
+
+ if (steps_.end() == it) {
+ HandleStepError(Step::Status::INVALID_VALUE,
+ "Can't find the step : " + step_name);
+ return;
+ }
+
+ std::unique_ptr<Step> step(
+ new StepT(context_.get(), std::forward<Args>(args)...));
+ step->on_error.connect(
+ boost::bind(&AppInstaller::HandleStepError, this, _1, _2));
+ *it = std::move(step);
+ }
+
+ /**
+ * \brief Adds new step before specified step
+ * Type of template parameter is used to create requested step
+ * class instance.
+ * Context of installer is passed to step in this method
+ * and is not being exposed outside installer.
+ * Step arguments are deduced and forwarded to constructor.
+ * \tparam StepT Step object to be added to the step list
+ * \tparam Args constructor arguments for StepT object
+ * \param step_name step name to find and add
+ * \param args argument list
+ */
+ template<class StepT, class... Args>
+ void AddStepBefore(std::string step_name, Args&&... args) {
+ auto it = std::find_if(std::begin(steps_), std::end(steps_),
+ [&](const std::unique_ptr<Step>& s) {
+ return step_name == s->name();
+ });
+
+ if (steps_.end() == it) {
+ HandleStepError(Step::Status::INVALID_VALUE,
+ "Can't find the step : " + step_name);
+ return;
+ }
+
+ std::unique_ptr<Step> step(
+ new StepT(context_.get(), std::forward<Args>(args)...));
+ step->on_error.connect(
+ boost::bind(&AppInstaller::HandleStepError, this, _1, _2));
+ steps_.insert(it, std::move(step));
+ }
+
+ /**
+ * \brief Adds new step after specified step
+ * Type of template parameter is used to create requested step
+ * class instance.
+ * Context of installer is passed to step in this method
+ * and is not being exposed outside installer.
+ * Step arguments are deduced and forwarded to constructor.
+ * \tparam StepT Step object to be added to the step list
+ * \tparam Args constructor arguments for StepT object
+ * \param step_name step name to find and add
+ * \param args argument list
+ */
+ template<class StepT, class... Args>
+ void AddStepAfter(std::string step_name, Args&&... args) {
+ auto it = std::find_if(std::begin(steps_), std::end(steps_),
+ [&](const std::unique_ptr<Step>& s) {
+ return step_name == s->name();
+ });
+
+ if (steps_.end() == it) {
+ HandleStepError(Step::Status::INVALID_VALUE,
+ "Can't find the step : " + step_name);
+ return;
+ }
+
+ std::unique_ptr<Step> step(
+ new StepT(context_.get(), std::forward<Args>(args)...));
+ step->on_error.connect(
+ boost::bind(&AppInstaller::HandleStepError, this, _1, _2));
+ steps_.insert(++it, std::move(step));
+ }
+
+ /**
* \brief runs the steps in the specific sequence
*
* \return Result of the run (eg Result:OK)