void Example::BCStrategy_Interface_WeakDirichletMatch<EvalT>::
buildAndRegisterEvaluators(PHX::FieldManager<panzer::Traits>& fm,
			   const panzer::PhysicsBlock& pb,
			   const panzer::ClosureModelFactory_TemplateManager<panzer::Traits>& factory,
			   const Teuchos::ParameterList& models,
			   const Teuchos::ParameterList& user_data) const
{
  using Teuchos::ParameterList;
  using Teuchos::RCP;
  using Teuchos::rcp;
  using std::string; 

  const std::vector<boost::tuples::tuple<string,string,string,int,Teuchos::RCP<panzer::PureBasis>,
    Teuchos::RCP<panzer::IntegrationRule> > > data = this->getResidualContributionData();

  string residual_name = data[0].get<0>();
  string dof_name = data[0].get<1>();
  string diff_name = data[0].get<2>();

  RCP<panzer::IntegrationRule> ir = data[0].get<5>();
  RCP<const panzer::FieldLayoutLibrary> fll = pb.getFieldLibrary()->buildFieldLayoutLibrary(*ir);
  RCP<panzer::BasisIRLayout> basis = fll->lookupLayout(dof_name);

  if (this->getDetailsIndex() == 0) {
    const std::string
      dof_grad_name = dof_name + "_gradient",
      cancel_natural_name = dof_name + "_cancel",
      my_normal_name = "My_Normal",
      sum_contributions_name = "Sum_Contributions";
    // Weak Dirichlet match.
    {
      { // Get values on my side.
        ParameterList p("My DOF");
        p.set("Name", dof_name);
        p.set("Basis", basis); 
        p.set("IR", ir);
        const RCP< PHX::Evaluator<panzer::Traits> >
          op = rcp(new panzer::DOF<EvalT,panzer::Traits>(p));
        this->template registerEvaluator<EvalT>(fm, op);
      }
      { // Other DOF - my DOF.
        ParameterList p("other DOF - my DOF");
        p.set("Sum Name", diff_name);
        setSumValues(p, other_dof_name, 1, dof_name, -1);
        p.set("Data Layout", ir->dl_scalar);
        const RCP< PHX::Evaluator<panzer::Traits> >
          op = rcp(new panzer::Sum<EvalT,panzer::Traits>(p));
        this->template registerEvaluator<EvalT>(fm, op);
      }
    }
    // Cancel my natural (Neumann) BC.
    {
      { // Normal.
        ParameterList p("My Side Normal");
        p.set("Name", my_normal_name);
        p.set("Side ID", pb.cellData().side());
        p.set("IR", ir);
        p.set("Normalize", true);
        const RCP< PHX::Evaluator<panzer::Traits> >
          op = rcp(new panzer::Normals<EvalT,panzer::Traits>(p));
        this->template registerEvaluator<EvalT>(fm, op);
      }
      { // Gradient.
        ParameterList p("My DOF gradient");
        p.set("Name", dof_name);
        p.set("Gradient Name", dof_grad_name);
        p.set("Basis", basis); 
        p.set("IR", ir);
        const RCP< PHX::Evaluator<panzer::Traits> >
          op = rcp(new panzer::DOFGradient<EvalT,panzer::Traits>(p));
        this->template registerEvaluator<EvalT>(fm, op);
      }
      { // dot(DOF gradient, normal).
        ParameterList p("dot(my DOF gradient, my normal)");
        p.set("Result Name", cancel_natural_name);
        p.set("Vector A Name", dof_grad_name);
        p.set("Vector B Name", my_normal_name);
        p.set("Point Rule", Teuchos::rcp_dynamic_cast<const panzer::PointRule>(ir));
        const RCP< PHX::Evaluator<panzer::Traits> >
          op = rcp(new panzer::DotProduct<EvalT,panzer::Traits>(p));
        this->template registerEvaluator<EvalT>(fm, op);
      }
    }
    // Add contributions to the residual.
    {
      { // Weak Dirichlet Match + Cancel Neumann
        ParameterList p("Weak Dirichlet Match + Cancel Neumann");
        p.set("Sum Name", sum_contributions_name);
        setSumValues(p, diff_name, 1e5, cancel_natural_name, -1);
        p.set("Data Layout", ir->dl_scalar);
        const RCP< PHX::Evaluator<panzer::Traits> >
          op = rcp(new panzer::Sum<EvalT,panzer::Traits>(p));
        this->template registerEvaluator<EvalT>(fm, op);
      }
      {
        ParameterList p("Weak Dirichlet Match And Cancel Neumann Residual");
        p.set("Residual Name", residual_name);
        p.set("Value Name", sum_contributions_name);
        p.set("Basis", basis);
        p.set("IR", ir);
        p.set("Multiplier", 1.0);
        const RCP< PHX::Evaluator<panzer::Traits> >
          op = rcp(new panzer::Integrator_BasisTimesScalar<EvalT,panzer::Traits>(p));
        this->template registerEvaluator<EvalT>(fm, op);
      }
    }
  } else {
    { // Get values on other side.
      ParameterList p("Other DOF");
      p.set("Name", dof_name);
      p.set("Basis", basis); 
      p.set("IR", ir);
      const RCP< PHX::Evaluator<panzer::Traits> >
        op = rcp(new panzer::DOF<EvalT,panzer::Traits>(p));
      this->template registerEvaluator<EvalT>(fm, op);
    }
  }
}