bool NOX::LineSearch::SafeguardedStep::compute(Abstract::Group& newGrp,
                           double& step,
                           const Abstract::Vector& dir,
                           const Solver::Generic& s)
{
  printOpeningRemarks();

  if (useCounter_) {
    counter_.incrementNumLineSearches();
    counter_.incrementNumNonTrivialLineSearches();
  }

  invLimits_->reciprocal(*userLimits_);
  *scaledUpdate_ = dir;
  scaledUpdate_->scale(*invLimits_);
  double infNorm = scaledUpdate_->norm(NOX::Abstract::Vector::MaxNorm);

  if (infNorm > 1.0)
    step = 1.0 / infNorm;
  else
    step = 1.0;

  if (print_.isPrintType(NOX::Utils::Details)) {
    print_.out () << "userLimits_:" << std::endl;
    userLimits_->print(print_.out());
    print_.out () << "scaledUpdate_:" << std::endl;
    scaledUpdate_->print(print_.out());
    print_.out () << "dir:" << std::endl;
    dir.print(print_.out());
    print_.out () << "Old Solution:" << std::endl;
    newGrp.getX().print(print_.out());
  }

  if (print_.isPrintType(NOX::Utils::InnerIteration)) {
    print_.out () << "    computed step = " << step << std::endl;
  }

  step = std::max(step,lowerStepBound_);
  step = std::min(step,upperStepBound_);

  if (print_.isPrintType(NOX::Utils::InnerIteration))
    print_.out () << "    bounded step = " << step << std::endl;

  newGrp.computeX(newGrp,dir,step);

  if (print_.isPrintType(NOX::Utils::Details)) {
    // reuse invLimits_, will be reset above
    invLimits_->update(step,dir,0.0);
    print_.out () << "Final Step Scaled Update:" << std::endl;
    invLimits_->print(print_.out());
    print_.out () << "New Solution:" << std::endl;
    newGrp.getX().print(print_.out());
  }

  if (useCounter_)
    counter_.setValues(*paramsPtr_);

  return true;
}