EvaluatePartition<Adapter>::EvaluatePartition(
  const RCP<const Environment> &env,
  const RCP<const Comm<int> > &problemComm,
  const RCP<const typename Adapter::base_adapter_t> &ia, 
  const PartitioningSolution<Adapter> *soln,
  const RCP<const GraphModel<typename Adapter::base_adapter_t> > &graphModel):
    env_(env), numGlobalParts_(0), targetGlobalParts_(0),
    graphMetrics_(),  graphMetricsConst_()
{

  env->debug(DETAILED_STATUS,
	     std::string("Entering EvaluatePartition"));
  env->timerStart(MACRO_TIMERS, "Computing graph metrics");
  // When we add parameters for which weights to use, we
  // should check those here.  For now we compute graph metrics
  // using all weights.

  typedef typename Adapter::part_t part_t;
  typedef typename Adapter::base_adapter_t base_adapter_t;

  std::bitset<NUM_MODEL_FLAGS> modelFlags;

  // Create a GraphModel based on input data.

  RCP<GraphModel<base_adapter_t> > graph;
  if (graphModel == Teuchos::null)
    graph = rcp(new GraphModel<base_adapter_t>(ia,env,problemComm,modelFlags));

  // Local number of objects.

  size_t numLocalObjects = ia->getLocalNumIDs();

  // Parts to which objects are assigned.

  const part_t *parts;
  if (soln) {
    parts = soln->getPartListView();
    env->localInputAssertion(__FILE__, __LINE__, "parts not set",
      ((numLocalObjects == 0) || parts), BASIC_ASSERTION);
  } else {
    part_t *procs = new part_t [numLocalObjects];
    for (size_t i=0; i<numLocalObjects; i++) procs[i] = problemComm->getRank();
    parts = procs;
  }
  ArrayView<const part_t> partArray(parts, numLocalObjects);

  ArrayRCP<scalar_t> globalSums;

  if (graphModel == Teuchos::null) {
    try{
      globalWeightedCutsByPart<Adapter>(env,
					problemComm, graph, partArray,
					numGlobalParts_, graphMetrics_,
					globalSums);
    }
    Z2_FORWARD_EXCEPTIONS;
  } else {
    try{
  EvaluatePartition<Adapter>::EvaluatePartition(
  const RCP<const Environment> &env,
  const RCP<const Comm<int> > &problemComm,
  const RCP<const typename Adapter::base_adapter_t> &ia, 
  const PartitioningSolution<Adapter> *soln,
  bool useDegreeAsWeight,
  const RCP<const GraphModel<typename Adapter::base_adapter_t> > &graphModel):
    env_(env), numGlobalParts_(0), targetGlobalParts_(0), numNonEmpty_(0),
    metrics_(),  metricsConst_(), graphMetrics_(), graphMetricsConst_()
{

  env->debug(DETAILED_STATUS, std::string("Entering EvaluatePartition"));
  env->timerStart(MACRO_TIMERS, "Computing metrics");

  // When we add parameters for which weights to use, we
  // should check those here.  For now we compute metrics
  // using all weights.

  const Teuchos::ParameterList &pl = env->getParameters();

  multiCriteriaNorm mcnorm = normBalanceTotalMaximum;
  const Teuchos::ParameterEntry *pe = pl.getEntryPtr("partitioning_objective");
  if (pe){
    std::string strChoice = pe->getValue<std::string>(&strChoice);
    if (strChoice == std::string("multicriteria_minimize_total_weight"))
      mcnorm = normMinimizeTotalWeight;
    else if (strChoice == std::string("multicriteria_minimize_maximum_weight"))
      mcnorm = normMinimizeMaximumWeight;
  } 

  try{
    objectMetrics<Adapter>(env, problemComm, mcnorm, ia, soln,
			   useDegreeAsWeight, graphModel, numGlobalParts_,
			   numNonEmpty_,metrics_);
  }
  Z2_FORWARD_EXCEPTIONS;

  if (soln)
  targetGlobalParts_ = soln->getTargetGlobalNumberOfParts();
  else
    targetGlobalParts_ = problemComm->getSize();

  env->timerStop(MACRO_TIMERS, "Computing metrics");

  BaseAdapterType inputType = ia->adapterType();

  if (inputType == GraphAdapterType ||
      inputType == MatrixAdapterType ||
      inputType == MeshAdapterType){
    env->timerStart(MACRO_TIMERS, "Computing graph metrics");
    // When we add parameters for which weights to use, we
    // should check those here.  For now we compute graph metrics
    // using all weights.

    std::bitset<NUM_MODEL_FLAGS> modelFlags;

    // Create a GraphModel based on input data.

    RCP<GraphModel<base_adapter_t> > graph;
    if (graphModel == Teuchos::null)
      graph=rcp(new GraphModel<base_adapter_t>(ia,env,problemComm,modelFlags));

    // Local number of objects.

    size_t numLocalObjects = ia->getLocalNumIDs();

    // Parts to which objects are assigned.

    const part_t *parts;
    if (soln) {
      parts = soln->getPartListView();
      env->localInputAssertion(__FILE__, __LINE__, "parts not set",
        ((numLocalObjects == 0) || parts), BASIC_ASSERTION);
    } else {
      part_t *procs = new part_t [numLocalObjects];
      for (size_t i=0; i<numLocalObjects; i++) procs[i]=problemComm->getRank();
      parts = procs;
    }
    ArrayView<const part_t> partArray(parts, numLocalObjects);

    ArrayRCP<scalar_t> globalSums;

    if (graphModel == Teuchos::null) {
      try{
	globalWeightedCutsByPart<Adapter>(env,
					  problemComm, graph, partArray,
					  numGlobalParts_, graphMetrics_,
					  globalSums);
      }
      Z2_FORWARD_EXCEPTIONS;
    } else {
      try{
  void EvaluatePartition<Adapter>::sharedConstructor(
  const Adapter *ia, 
  ParameterList *p,
  const RCP<const Comm<int> > &comm,
  const PartitioningSolution<Adapter> *soln,
  const RCP<const GraphModel<typename Adapter::base_adapter_t> > &graphModel)
{
  RCP<const Comm<int> > problemComm;
  if (comm == Teuchos::null) {
    problemComm = DefaultComm<int>::getComm();//communicator is Teuchos default
  } else {
    problemComm = comm;
  }
  RCP<Environment> env = rcp(new Environment(*p, problemComm));
  env->debug(DETAILED_STATUS, std::string("Entering EvaluatePartition"));
  env->timerStart(MACRO_TIMERS, "Computing metrics");

  // When we add parameters for which weights to use, we
  // should check those here.  For now we compute metrics
  // using all weights.

  multiCriteriaNorm mcnorm = normBalanceTotalMaximum;
  const Teuchos::ParameterEntry *pe = p->getEntryPtr("partitioning_objective");
  if (pe){
    std::string strChoice = pe->getValue<std::string>(&strChoice);
    if (strChoice == std::string("multicriteria_minimize_total_weight"))
      mcnorm = normMinimizeTotalWeight;
    else if (strChoice == std::string("multicriteria_minimize_maximum_weight"))
      mcnorm = normMinimizeMaximumWeight;
  } 

  const RCP<const base_adapter_t> bia =
    rcp(dynamic_cast<const base_adapter_t *>(ia), false);

  try{
    objectMetrics<Adapter>(env, problemComm, mcnorm, ia, soln, graphModel,
			   numGlobalParts_, numNonEmpty_,metrics_);
  }
  Z2_FORWARD_EXCEPTIONS;

  if (soln)
  targetGlobalParts_ = soln->getTargetGlobalNumberOfParts();
  else
    targetGlobalParts_ = problemComm->getSize();

  env->timerStop(MACRO_TIMERS, "Computing metrics");

  BaseAdapterType inputType = bia->adapterType();

  if (inputType == GraphAdapterType ||
      inputType == MatrixAdapterType ||
      inputType == MeshAdapterType){
    env->timerStart(MACRO_TIMERS, "Computing graph metrics");
    // When we add parameters for which weights to use, we
    // should check those here.  For now we compute graph metrics
    // using all weights.

    std::bitset<NUM_MODEL_FLAGS> modelFlags;

    // Create a GraphModel based on input data.

    RCP<GraphModel<base_adapter_t> > graph;
    if (graphModel == Teuchos::null)
      graph = rcp(new GraphModel<base_adapter_t>(bia, env, problemComm, 
						 modelFlags));

    // Local number of objects.

    size_t numLocalObjects = bia->getLocalNumIDs();

    // Parts to which objects are assigned.

    const part_t *parts;
    if (soln) {
      // User provided a partitioning solution; use it.
      parts = soln->getPartListView();
      env->localInputAssertion(__FILE__, __LINE__, "parts not set",
        ((numLocalObjects == 0) || parts), BASIC_ASSERTION);
    } else {
      // User did not provide a partitioning solution;
      // Use input adapter partition.

      parts = NULL;
      bia->getPartsView(parts);
      if (parts == NULL) {
	// User has not provided input parts in input adapter
	part_t *procs = new part_t [numLocalObjects];
	for (size_t i=0;i<numLocalObjects;i++) procs[i]=problemComm->getRank();
	parts = procs;
      }
    }
    ArrayView<const part_t> partArray(parts, numLocalObjects);

    ArrayRCP<scalar_t> globalSums;

    if (graphModel == Teuchos::null) {
      try{
	globalWeightedCutsByPart<Adapter>(env,
					  problemComm, graph, partArray,
					  numGlobalParts_, graphMetrics_,
					  globalSums);
      }
      Z2_FORWARD_EXCEPTIONS;
    } else {
      try{