inline Teuchos::RCP<Secant<Real> > SecantFactory( Teuchos::ParameterList &parlist ) {
   ESecant esec = StringToESecant(
            parlist.sublist("General").sublist("Secant").get("Type","Limited-Memory BFGS") );
   int L  = parlist.sublist("General").sublist("Secant").get("Maximum Storage",10);
   int BB = parlist.sublist("General").sublist("Secant").get("Barzilai-Borwein",1);
   switch (esec) {
     case SECANT_LBFGS:           return Teuchos::rcp( new lBFGS<Real>(L) );
     case SECANT_LDFP:            return Teuchos::rcp( new lDFP<Real>(L) );
     case SECANT_LSR1:            return Teuchos::rcp( new lSR1<Real>(L) );
     case SECANT_BARZILAIBORWEIN: return Teuchos::rcp( new BarzilaiBorwein<Real>(BB) );
     default:                     return Teuchos::null;
   }
 }
  /** \brief Constructor.

      Standard constructor to build a LineSearchStep object.  Algorithmic 
      specifications are passed in through a Teuchos::ParameterList.

      @param[in]     parlist    is a parameter list containing algorithmic specifications
  */
  LineSearchStep( Teuchos::ParameterList &parlist )
    : Step<Real>(),
      secant_(Teuchos::null), krylov_(Teuchos::null),
      nlcg_(Teuchos::null), lineSearch_(Teuchos::null),
      hessian_(Teuchos::null), precond_(Teuchos::null),
      d_(Teuchos::null), gp_(Teuchos::null),
      iterKrylov_(0), flagKrylov_(0),
      els_(LINESEARCH_BACKTRACKING),
      enlcg_(NONLINEARCG_OREN_LUENBERGER),
      econd_(CURVATURECONDITION_WOLFE),
      edesc_(DESCENT_STEEPEST),
      esec_(SECANT_LBFGS),
      ekv_(KRYLOV_CG),
      ls_nfval_(0), ls_ngrad_(0),
      useSecantHessVec_(false), useSecantPrecond_(false),
      useProjectedGrad_(false) {
    Teuchos::ParameterList& Llist = parlist.sublist("Step").sublist("Line Search");
    Teuchos::ParameterList& Glist = parlist.sublist("General");
    // Initialize Linesearch Object
    edesc_ = StringToEDescent(Llist.sublist("Descent Method").get("Type","Quasi-Newton Method") );
    els_ = StringToELineSearch(Llist.sublist("Line-Search Method").get("Type","Cubic Interpolation") );
    econd_ = StringToECurvatureCondition(Llist.sublist("Curvature Condition").get("Type","Strong Wolfe Conditions") );
    useProjectedGrad_ = Glist.get("Projected Gradient Criticality Measure", false);
    acceptLastAlpha_ = Llist.get("Accept Last Alpha", false); 
    lineSearch_ = LineSearchFactory<Real>(parlist);
    // Inexactness Information
    useInexact_.clear();
    useInexact_.push_back(Glist.get("Inexact Objective Function", false));
    useInexact_.push_back(Glist.get("Inexact Gradient", false));
    useInexact_.push_back(Glist.get("Inexact Hessian-Times-A-Vector", false));
    // Initialize Krylov Object
    ekv_ = StringToEKrylov(Glist.sublist("Krylov").get("Type","Conjugate Gradients"));
    if ( edesc_ == DESCENT_NEWTONKRYLOV ) {
      krylov_ = KrylovFactory<Real>(parlist);
    }
    // Initialize Secant Object
    esec_ = StringToESecant(Glist.sublist("Secant").get("Type","Limited-Memory BFGS"));
    useSecantHessVec_ = Glist.sublist("Secant").get("Use as Hessian", false);
    useSecantHessVec_ = ((edesc_==DESCENT_SECANT) ? true : useSecantHessVec_);
    useSecantPrecond_ = Glist.sublist("Secant").get("Use as Preconditioner", false);
    if ( edesc_ == DESCENT_SECANT || (edesc_ == DESCENT_NEWTONKRYLOV && useSecantPrecond_) ) {
      secant_ = SecantFactory<Real>(parlist);
    }
    // Initialize Nonlinear CG Object
    enlcg_ = StringToENonlinearCG(Llist.sublist("Descent Method").get("Nonlinear CG Type","Oren-Luenberger"));
    if ( edesc_ == DESCENT_NONLINEARCG ) {
      nlcg_ = Teuchos::rcp( new NonlinearCG<Real>(enlcg_) );
    }
  }
 /** \brief Constructor.
    
            @param[in]     parlist   is a parameter list containing relevent algorithmic information
            @param[in]     useSecant is a bool which determines whether or not the algorithm uses 
                                     a secant approximation of the Hessian
 */
 PrimalDualActiveSetStep( Teuchos::ParameterList &parlist ) 
   : Step<Real>::Step(), iterCR_(0), flagCR_(0), iter_(0), flag_(0), neps_(-ROL_EPSILON), feasible_(false) {
   esec_    = StringToESecant(parlist.get("Secant Type","Limited-Memory BFGS"));
   maxit_   = parlist.get("PDAS Maximum Number of Iterations",10);
   stol_    = parlist.get("PDAS Relative Step Tolerance",1.e-8);
   gtol_    = parlist.get("PDAS Relative Gradient Tolerance",1.e-6);
   scale_   = parlist.get("PDAS Dual Scaling", 1.0);
 
   useSecantHessVec_ = parlist.get("Use Secant Hessian-Times-A-Vector", false); 
   useSecantPrecond_ = parlist.get("Use Secant Preconditioning", false);
   secant_  = Teuchos::null;
   if ( useSecantHessVec_ || useSecantPrecond_ ) {
     int L   = parlist.get("Maximum Secant Storage",10);
     int BB  = parlist.get("Barzilai-Borwein",1);
     secant_ = getSecant<Real>(esec_,L,BB); 
   }
   KrylovFactory(parlist);
 }