bool NLPInterfacePack::test_basis_system(
   NLPFirstOrder                                 *nlp
  ,BasisSystem                                  *basis_sys
  ,OptionsFromStreamPack::OptionsFromStream     *options
  ,std::ostream                                 *out
  )
{
  namespace mmp = MemMngPack;

  const index_type
    n = nlp->n(),
    m = nlp->m();

  // Create the matrices Gc and Gh
  NLPFirstOrder::mat_fcty_ptr_t::element_type::obj_ptr_t
    Gc = ( m  ? nlp->factory_Gc()->create() : Teuchos::null );
  
  // Compute the matrices at xinit
  const Vector
    &xo = nlp->xinit();
  if(m)
    nlp->set_Gc(Gc.get());
  if(m)
    nlp->calc_Gc(xo);

  // Create the matrices C and D
  BasisSystem::mat_nonsing_fcty_ptr_t::element_type::obj_ptr_t
    C = ( m ? basis_sys->factory_C()->create() : Teuchos::null);
  BasisSystem::mat_fcty_ptr_t::element_type::obj_ptr_t
    D = ( m && n > m && basis_sys->factory_C().get() ? basis_sys->factory_C()->create() : Teuchos::null);
  BasisSystem::mat_fcty_ptr_t::element_type::obj_ptr_t
    GcUP = ( m && n > m && basis_sys->factory_GcUP().get()  ? basis_sys->factory_GcUP()->create() : Teuchos::null);

  // Initialize C and D with basis_sys
  basis_sys->update_basis(
    *Gc
    ,C.get()
    ,D.get()
    ,GcUP.get()
    );

  // Test the basis and basis system objects.
  BasisSystemTester
    basis_sys_tester;
  if(options) {
    BasisSystemTesterSetOptions
      opt_setter(&basis_sys_tester);
    opt_setter.set_options(*options);
  }
  const bool result = basis_sys_tester.test_basis_system(
    *basis_sys
    ,Gc.get()
    ,C.get()
    ,NULL    // Create the N matrix internally
    ,D.get()
    ,GcUP.get()
    ,out
    );

  return result;
}
bool NLPInterfacePack::test_nlp_first_order(
  NLPFirstOrder                                 *nlp
  ,OptionsFromStreamPack::OptionsFromStream     *options
  ,std::ostream                                 *out
  )
{
  namespace rcp = MemMngPack;
  using TestingHelperPack::update_success;

  bool result;
  bool success = true;
  
  Teuchos::VerboseObjectTempState<NLP>
    nlpOutputTempState(Teuchos::rcp(nlp,false),Teuchos::getFancyOStream(Teuchos::rcp(out,false)),Teuchos::VERB_LOW);

  if(out)
    *out << "\n*********************************"
         << "\n*** test_nlp_first_order(...) ***"
         << "\n*********************************\n";
  
  nlp->initialize(true);

  // Test the DVector spaces
  if(out)
    *out << "\nTesting the vector spaces ...\n";
  
  VectorSpaceTester vec_space_tester;
  if(options) {
    VectorSpaceTesterSetOptions
      opt_setter(&vec_space_tester);
    opt_setter.set_options(*options);
  }

  if(out)
    *out << "\nTesting nlp->space_x() ...\n";
  result = vec_space_tester.check_vector_space(*nlp->space_x(),out);
  if(out) {
    if(result)
      *out << "nlp->space_x() checks out!\n";
    else
      *out << "nlp->space_x() check failed!\n";
  }
  update_success( result, &success );

  if( nlp->m() ) {
    if(out)
      *out << "\nTesting nlp->space_c() ...\n";
    result = vec_space_tester.check_vector_space(*nlp->space_c(),out);
    if(out) {
      if(result)
        *out << "nlp->space_c() checks out!\n";
      else
        *out << "nlp->space_c() check failed!\n";
    }
    update_success( result, &success );
  }

  // Test the NLP interface first!

  NLPTester nlp_tester;
  if(options) {
    NLPTesterSetOptions
      nlp_tester_opt_setter(&nlp_tester);
    nlp_tester_opt_setter.set_options(*options);
  }
  const bool print_all_warnings = nlp_tester.print_all();

  result = nlp_tester.test_interface(
    nlp, nlp->xinit(), print_all_warnings, out );
  update_success( result, &success );
  
  // Test the NLPFirstOrder interface now!

  const size_type
    n  = nlp->n(),
    m  = nlp->m();
  VectorSpace::vec_mut_ptr_t
    c   = m  ? nlp->space_c()->create_member() : Teuchos::null,
    Gf  =      nlp->space_x()->create_member();
  NLPFirstOrder::mat_fcty_ptr_t::element_type::obj_ptr_t
    Gc  = m  ? nlp->factory_Gc()->create() : Teuchos::null;

  if(m) {
    if(out)
      *out << "\nCalling nlp->calc_Gc(...) at nlp->xinit() ...\n";
    nlp->set_Gc( Gc.get() );
    nlp->calc_Gc( nlp->xinit(), true );
    if(nlp_tester.print_all()) {
      *out << "\nGc =\n" << *Gc;
    }
  }

  if(out)
    *out << "\nCalling nlp->calc_Gf(...) at nlp->xinit() ...\n";
  nlp->set_Gf( Gf.get() );
  nlp->calc_Gf( nlp->xinit(), m == 0 );
  if(nlp_tester.print_all())
    *out << "\nGf =\n" << *Gf;

  CalcFiniteDiffProd
    calc_fd_prod;
  if(options) {
    CalcFiniteDiffProdSetOptions
      options_setter( &calc_fd_prod );
    options_setter.set_options(*options);
  }
  NLPFirstDerivTester
    nlp_first_derivatives_tester(Teuchos::rcp(&calc_fd_prod,false));
  if(options) {
    NLPFirstDerivTesterSetOptions
      nlp_tester_opt_setter(&nlp_first_derivatives_tester);
    nlp_tester_opt_setter.set_options(*options);
  }
  result = nlp_first_derivatives_tester.finite_diff_check(
    nlp, nlp->xinit()
    ,nlp->num_bounded_x() ? &nlp->xl() : NULL
    ,nlp->num_bounded_x() ? &nlp->xu() : NULL
    ,Gc.get(), Gf.get()
    ,print_all_warnings, out
    );
  update_success( result, &success );

  return success;
}