#include "Teuchos_StandardParameterEntryValidators.hpp"
#include "Teuchos_Version.hpp"
#include "Teuchos_StandardCatchMacros.hpp"
int main(int argc, char* argv[])
{
  using Teuchos::tuple;
  bool success = false;
  bool verbose = true;
  try {
    std::cout << Teuchos::Teuchos_Version() << std::endl << std::endl;
    
    ParameterList myPL;
    
    myPL.set("Max Iters", 1550, "Determines the maximum number of iterations in the solver");
    myPL.set("Tolerance", 1e-10, "The tolerance used for the convergence check");
    
    
    RCP<Teuchos::StringToIntegralParameterEntryValidator<int> >
            Teuchos::tuple<std::string>( "GMRES", "CG", "TFQMR" )
            ,"Solver"
            )
          );
    myPL.set(
        "Solver"
        ,"GMRES" 
        ,"The type of solver to use"
        ,solverValidator
        );
    
    myPL.set("Tolerance", as<float>(1e-10), "The tolerance used for the convergence check");
    
    myPL.set<Array<double> >("Initial Guess", tuple<double>( 10, 0.0 ),
        "The initial guess as a RCP to an array object.");
    
    ParameterList& Prec_List = myPL.sublist("Preconditioner", false,
        "Sublist that defines the preconditioner.");
    
    Prec_List.set("Type", "ILU", "The tpye of preconditioner to use");
    Prec_List.set("Drop Tolerance", 1e-3,
        "The tolerance below which entries from the\n""factorization are left out of the factors.");
    
    
    bool solver_defined = false, prec_defined = false, dtol_double = false;
    solver_defined = myPL.isParameter("Solver");
    
    prec_defined = myPL.isSublist("Preconditioner");
    
    bool tol_double = false;
    tol_double = myPL.INVALID_TEMPLATE_QUALIFIER isType<double>("Tolerance");
    
    dtol_double = Teuchos::isParameterType<double>(Prec_List, "Drop Tolerance");
    
    
    int its = -1;
    its = myPL.get("Max Iters", 1200);
    
    float tol = -1.0;
    tol = myPL.get<float>("Tolerance");
    
    std::string
      solver = solverValidator->validateString(
          Teuchos::getParameter<std::string>(myPL,"Solver")
          );
    
    Array<double> init_guess = myPL.get<Array<double> >("Initial Guess");
    std::cout << "\n# Printing this parameter list using opeator<<(...) ...\n\n";
    std::cout << myPL << std::endl;
    std::cout << "\n# Printing the parameter list only showing documentation fields ...\n\n";
    myPL.print(std::cout,
        ParameterList::PrintOptions().showDoc(true).indent(2).showTypes(true));
    
    std::cout << "\n# Showing unused parameters ...\n\n";
    myPL.unused( std::cout );
    success = true;
  }
  return ( success ? EXIT_SUCCESS : EXIT_FAILURE );
}