/*
   * Empty implementation, to be filled by derived classes.
   */
   bool ReplicaMove::move()
   {
      MPI::Request request[8];
      MPI::Status  status;
      double ptParam,  myWeight, ptWeight;
      int    isLeft, iAccept, myPort, ptPort;
      System::MoleculeIterator molIter;
      Molecule::AtomIterator   atomPtr;
      int iA;

      // Default value for idle processor
      isLeft  = -1;
      iAccept = 0;

      // Idenfity active processor and its parter ID; left one has smaller ID.
      if ((myId_ + xFlag_)%2 == 0 && myId_ < nProcs_-1) {
         isLeft = 1;
         ptId_ = myId_ + 1;
      } else if ((myId_ + xFlag_)%2 == 1 && myId_ > 0) {
         isLeft = 0;
         ptId_ = myId_ - 1;
      }

      // Start to talk with partner
      if (isLeft == 1 || isLeft == 0) {

         // Set the port value for message tag
         myPort = myId_%2;
         ptPort = ptId_%2;

         // Update accumulator
         repxAttempt_[isLeft] += 1;

         // Exchange coupling parameters with partner
         request[0] = communicatorPtr_->Irecv(&ptParam, 1, MPI::DOUBLE, ptId_,
                                              TagParam[ptPort]);
         request[1] = communicatorPtr_->Isend(&myParam_, 1, MPI::DOUBLE, ptId_,
                                              TagParam[myPort]);

         // Synchronizing
         request[0].Wait();
         request[1].Wait();

         // Evaluating energy change.
         myWeight = system().perturbation().difference(ptParam);

         // Collect tempering weights and make decision
         if (isLeft == 1) {

            // Receive energy difference from the right box
            request[2] = communicatorPtr_->Irecv(&ptWeight, 1, MPI::DOUBLE,
                                                 ptId_, TagDecision[ptPort]);
            request[2].Wait();

            // Metropolis test
            iAccept = system().simulation().random().
                      metropolis(exp(-myWeight - ptWeight)) ? 1 : 0;

           // Output the two weights and the metropolis of their summation.
           // energyFile_ << setw(10) << myWeight << setw(10)
           //             << ptWeight << setw(2) << iAccept << std::endl;


            // Send decision to the right box
            request[3] = communicatorPtr_->Isend(&iAccept, 1, MPI::INT,
                                                 ptId_, TagDecision[myPort]);
            request[3].Wait();

         } else {

            // Send energy difference to the left box
            request[2] = communicatorPtr_->Isend(&myWeight, 1, MPI::DOUBLE,
                                                 ptId_, TagDecision[myPort]);
            request[2].Wait();

            // Receive decision from the left box
            request[3] = communicatorPtr_->Irecv(&iAccept, 1, MPI::INT,
                                                 ptId_, TagDecision[ptPort]);
            request[3].Wait();

         }

         // Exchange particle configurations if the move is accepted
         if (iAccept == 1) {
         
            // Update accumulator
            repxAccept_[isLeft] += 1;

            // Pack atomic positions and types.
            iA = 0;
            for (int iSpec=0; iSpec < system().simulation().nSpecies(); ++iSpec){
               for (system().begin(iSpec, molIter); !molIter.isEnd(); ++molIter){
                  for (molIter->begin(atomPtr); !atomPtr.isEnd(); ++atomPtr) {
                     myPositionPtr_[iA] = atomPtr->position();
                     iA++;
                  }
               }
            }

            // Accomodate new configuration.
            request[4] = communicatorPtr_->Irecv(ptPositionPtr_, iA,
                             MpiTraits<Vector>::type, ptId_, TagConfig[ptPort]);

            // Send old configuration.
            request[5] = communicatorPtr_->Isend(myPositionPtr_, iA,
                             MpiTraits<Vector>::type, ptId_, TagConfig[myPort]);

            request[4].Wait();
            request[5].Wait();

            // Adopt the new atomic positions.
            iA = 0;
            for (int iSpec=0; iSpec < system().simulation().nSpecies(); ++iSpec){
               for (system().begin(iSpec, molIter); !molIter.isEnd(); ++molIter){
                  for (molIter->begin(atomPtr); !atomPtr.isEnd(); ++atomPtr) {
                     atomPtr->position() = ptPositionPtr_[iA];
                     ++iA;
                  }
               }
            }

            // Notify component observers.
            //notifyObservers(ptId_);
            Notifier<int>::notifyObservers(ptId_);

         }  else {
         }

      }


      // Output results needed to build exchange profile.
      outputFile_ << ((isLeft != -1 && iAccept == 1) ? ptId_ : myId_)
                  << std::endl;

      // Flip the value of xFlag_ before exit.
      xFlag_ = (xFlag_ == 0 ? 1 : 0);

      return (iAccept == 1 ? true : false);

   }