int 
DistributedSparseGenColLinSOE::solve(void)
{
  static ID result(1);

  //
  // if subprocess send B and A and receive back result X, B & result
  //

  if (processID != 0) {
    Channel *theChannel = theChannels[0];

    // send B
    theChannel->sendVector(0, 0, *myVectB);

    // send A in packets placed in vector X
    if (factored == false) {
      Vector vectA(A, nnz);    
      theChannel->sendVector(0, 0, vectA);
    }

    LinearSOESolver *theSoeSolver = this->getSolver();
    if (theSoeSolver->getClassTag() == SOLVER_TAGS_DistributedSuperLU)
      this->LinearSOE::solve();

    // receive X,B and result
    theChannel->recvVector(0, 0, *vectX);
    theChannel->recvVector(0, 0, *vectB);
    theChannel->recvID(0, 0, result);
    factored = true;
  } 

  //
  // if main process, recv B & A from all, solve and send back X, B & result
  //

  else {

    // add P0 contribution to B
    *vectB = *myVectB;

    // receive X and A contribution from subprocess & add them in
    for (int j=0; j<numChannels; j++) {

      // get X & add
      Channel *theChannel = theChannels[j];
      theChannel->recvVector(0, 0, *vectX);
      *vectB += *vectX;

      if (factored == false) {
	Vector vectA(workArea, nnz);
	theChannel->recvVector(0, 0, vectA);
	for (int i=0; i<nnz; i++)
	  A[i] += workArea[i];	
      }	

      /*
      // get A & add using local map
      const ID &localMap = *(localCol[j]);
      int localSize = localMap.Size() * half_band;
      Vector vectA(workArea, localSize);    
      theChannel->recvVector(0, 0, vectA);

      int loc = 0;
      for (int i=0; i<localMap.Size(); i++) {
	int pos = localMap(i)*half_band;
	for (int k=0; k<half_band; k++) 
	  A[pos++] += workArea[loc++];
      }    
      */
    }


    // solve
    result(0) = this->LinearSOE::solve();

    // send results back
    for (int j=0; j<numChannels; j++) {
      Channel *theChannel = theChannels[j];
      theChannel->sendVector(0, 0, *vectX);
      theChannel->sendVector(0, 0, *vectB);

      theChannel->sendID(0, 0, result);      
    }
  } 
  
  return result(0);
}