inline real
    FixedPairListTypesInteractionTemplate < _Potential >::
    computeEnergy() {
      LOG4ESPP_INFO(theLogger, "compute energy of the FixedPair list pairs");

      real e = 0.0;
      real es = 0.0;
      const bc::BC& bc = *getSystemRef().bc;  // boundary conditions
      for (FixedPairList::PairList::Iterator it(*fixedpairList);
           it.isValid(); ++it) {
        Particle &p1 = *it->first;
        Particle &p2 = *it->second;
        int type1 = p1.type();
        int type2 = p2.type();
        const Potential &potential = getPotential(type1, type2);
        // shared_ptr<Potential> potential = getPotential(type1, type2);
        Real3D r21;
        bc.getMinimumImageVectorBox(r21, p1.position(), p2.position());
        //e   = potential._computeEnergy(p1, p2);
        // e   = potential->_computeEnergy(p1, p2);
        e = potential._computeEnergy(p1,p2,r21);
        es += e;
        LOG4ESPP_TRACE(theLogger, "id1=" << p1.id() << " id2=" << p2.id() << " potential energy=" << e);
        //std::cout << "id1=" << p1.id() << " id2=" << p2.id() << " potential energy=" << e << std::endl;
      }

      // reduce over all CPUs
      real esum;
      boost::mpi::all_reduce(*mpiWorld, es, esum, std::plus<real>());
      return esum;
    }
inline real
FixedTripleListTypesInteractionTemplate<_Potential>::
computeEnergy() {
  LOG4ESPP_INFO(theLogger, "compute energy of the FixedTriple list pairs");

  real e = 0.0;
  const bc::BC &bc = *getSystemRef().bc;  // boundary conditions
  for (FixedTripleList::TripleList::Iterator it(*fixedtripleList); it.isValid(); ++it) {
    const Particle &p1 = *it->first;
    const Particle &p2 = *it->second;
    const Particle &p3 = *it->third;
    int type1 = p1.type();
    int type2 = p2.type();
    int type3 = p3.type();

    const Potential &potential = getPotential(type1, type2, type3);

    Real3D dist12 = bc.getMinimumImageVector(p1.position(), p2.position());
    Real3D dist32 = bc.getMinimumImageVector(p3.position(), p2.position());
    e += potential._computeEnergy(dist12, dist32);
    LOG4ESPP_TRACE(theLogger, "id1=" << p1.id() << " id2="
        << p2.id() << " id3=" << p3.id() << " potential energy=" << e);
  }

  // reduce over all CPUs
  real esum;
  boost::mpi::all_reduce(*mpiWorld, e, esum, std::plus<real>());
  return esum;
}
    inline CellListAllTriplesIterator &
    CellListAllTriplesIterator::
    operator++() {
//pit1 = ParticleList::Iterator((*cit1)->particles);
//cit2 = NeighborCellList::Iterator((*cit1)->neighborCells);
//pit2 = ParticleList::Iterator(cit2->cell->particles);
//std::cout << "p1: "<< pit1->id() << " p2isd: "<<pit2.isValid()<<std::endl;
//if(pit2.isDone()) cout << "Something strange pit2 isDone by inSelfLoop="<< inSelfLoop <<endl;
      
      bool shouldNotReturn = true;
      while(shouldNotReturn){
        
        shouldNotReturn = false;
        ++pit3;
        if(pit3.isValid() && pit3->id()==pit1->id()){
          ++pit3;
        }
        if(inSelfLoop==2 && pit3.isValid() && pit3->id()==pit2->id()){
          ++pit3;
        }
        while (pit3.isDone()) {
          switch ( inSelfLoop ) {
            case 0:
              ++pit2;
              if(pit2.isValid() && pit2->id()==pit1->id()){
                ++pit2;
              }
              break;
            case 1:
              ++cit3;
              if(cit3.isDone()){
                ++pit2;
                if(pit2.isValid() && pit2->id()==pit1->id()){
                  ++pit2;
                }
                cit3 = NeighborCellList::Iterator((*cit1)->neighborCells);
              }
              break;
            case 2:
              ++pit2;
              break;
            case 3:
              ++cit3;
              if(cit3.isValid() &&  cit3->cell == cit2->cell){
                ++cit3;
              }
              if(cit3.isDone()){
                ++pit2;
                // **
                //cit3 = NeighborCellList::Iterator((*cit1)->neighborCells);
                cit3 = cit2;
                ++cit3;
                if(cit3.isDone()){
                  cout<<"cit3 is done. But it should not happen"<<endl;
                }
              }
              break;
            default:
              cout<<"It is default. pit3 is done. BEGIN"<<endl;
          }
          
          while (pit2.isDone()) {
            
            switch ( inSelfLoop ) {
              case 0:
                ++pit1;
                break;
              case 1:
                ++pit1;
                break;
              case 2:
                ++cit2;
                if(cit2.isDone()){
                  ++pit1;
                  cit2 = NeighborCellList::Iterator((*cit1)->neighborCells);
                }
                break;
              case 3:
                ++cit2;
                if(cit2.isDone()){
                  ++pit1;
                  cit2 = NeighborCellList::Iterator((*cit1)->neighborCells);
                }
                cit3 = cit2;
                ++cit3;
                if(cit3.isDone()){
                  ++pit1;
                  cit2 = NeighborCellList::Iterator((*cit1)->neighborCells);
                  cit3 = cit2;
                  ++cit3;
                }
                break;
              default:
                cout<<"It is default. pit3 is done. BEGIN"<<endl;
            }
            
            while (pit1.isDone()) {

              switch ( inSelfLoop ) {
                case 0:
                  inSelfLoop = 1;
                  pit1 = ParticleList::Iterator((*cit1)->particles);
                  cit3 = NeighborCellList::Iterator((*cit1)->neighborCells);
                  //pit3 = ParticleList::Iterator(cit3->cell->particles);
//if(pit1->id()==0)
//  cout << "inSelfLoop 0->1: "<< inSelfLoop <<endl;
                  break;
                case 1:
                  inSelfLoop = 2;
                  pit1 = ParticleList::Iterator((*cit1)->particles);
                  cit2 = NeighborCellList::Iterator((*cit1)->neighborCells);
                  //shouldNotReturn = true;
//if(pit1->id()==0)
                  //cout << "inSelfLoop 1->2: "<< inSelfLoop <<endl;
                  break;
                case 2:
                  inSelfLoop = 3;
                  pit1 = ParticleList::Iterator((*cit1)->particles);
                  cit2 = NeighborCellList::Iterator((*cit1)->neighborCells);
                  cit3 = cit2;
                  ++cit3;
//if(pit1->id()==0)
                  //cout << "inSelfLoop 2->3: "<< inSelfLoop <<endl;
                  break;
                case 3:
                  ++cit1;
                  if(cit1.isDone())return *this;
                  inSelfLoop = 0;
                  pit1 = ParticleList::Iterator((*cit1)->particles);
                  while (pit1.isDone()) {
                    ++cit1;
                    if (cit1.isDone()) return *this;
                    pit1 = ParticleList::Iterator((*cit1)->particles);
                  }
                  //shouldNotReturn = true;
//if(pit1->id()==0)
                  //cout << "inSelfLoop 3->0: "<< inSelfLoop <<endl;
                  break;
                default:
                  cout<<"It is default"<<endl;
              }
              //cout << "After "<< inSelfLoop << " pit1 "<< pit1.isValid() <<endl;

            }
            // pit 2 is done
            switch ( inSelfLoop ) {
              case 0:
                pit2 = ParticleList::Iterator((*cit1)->particles);
                if(pit2->id()==pit1->id()){
                  ++pit2;
                }
                break;
              case 1:
                pit2 = ParticleList::Iterator((*cit1)->particles);
                if(pit2->id()==pit1->id()){
                  ++pit2;
                }
                break;
              case 2:
                pit2 = ParticleList::Iterator(cit2->cell->particles);
                break;
              case 3:
                pit2 = ParticleList::Iterator(cit2->cell->particles);
                break;
              default:
                cout<<"It is default. pit2 is done"<<endl;
            }
          }

          // pit 3 is done
          switch ( inSelfLoop ) {
            case 0:
              pit3 = pit2;
              ++pit3;
              
              if(pit3.isValid() && pit3->id()==pit1->id()){
                ++pit3;
              }
              break;
            case 1:
              pit3 = ParticleList::Iterator(cit3->cell->particles);
              break;
            case 2:
              pit3 = pit2;
              ++pit3;
              break;
            case 3:
              pit3 = ParticleList::Iterator(cit3->cell->particles);
              break;
            default:
              cout<<"It is default. pit3 is done"<<endl;
          }
        }
      
      }
      
      current.second = &*pit1;
      if(pit2->id()<pit3->id()){
        current.first  = &*pit2;
        current.third  = &*pit3;
      }
      else{
        current.first  = &*pit3;
        current.third  = &*pit2;
      }

      
      /*
      if(current.first->id()==1 && current.second->id()==0 &&  current.third->id()==6){
cout << "case1 part3 "<< inSelfLoop <<endl;
        
      std::cout << "current triple: (" << current.first->id() << ", " 
              << current.second->id() << ", " << current.third->id() << ")";
      std::cout << "  isGhost: (" << current.first->ghost() << ", " 
              << current.second->ghost() << ", " << current.third->ghost() << ")";
      std::cout << "  real: (" << pit2->id() << ", " 
              << pit1->id() << ", " << pit3->id() << ")"<<std::endl;
      }*/
      
      
      LOG4ESPP_TRACE(theLogger,
             "current triple: (" << current.first->id() <<
             ", " << current.second->id() << ", " << current.third->id() << ")"
             );
      return *this;
    }