TripleDecompositionProtocolInstance::TripleDecompositionProtocolInstance
( int braid_rank , 
  quadruple< Word , Word , Word , Word > conjugators ,
  quintuple< Word , Word , Word , Word , Word > privateKeyA ,
  quintuple< Word , Word , Word , Word , Word > privateKeyB ) :
  theRank( braid_rank ),
  theConjugators( conjugators ),
  thePrivateKeyA( privateKeyA ),
  thePrivateKeyB( privateKeyB )
{
  thePublicKeyA.first  = DehornoyForm( braid_rank ,  privateKeyA.first  * privateKeyA.fourth ).getDehornoyForm( );
  thePublicKeyA.second = DehornoyForm( braid_rank , -privateKeyA.fourth * privateKeyA.second * privateKeyA.fifth ).getDehornoyForm( );
  thePublicKeyA.third  = DehornoyForm( braid_rank , -privateKeyA.fifth  * privateKeyA.third ).getDehornoyForm( );
  
  thePublicKeyB.first  = DehornoyForm( braid_rank ,  privateKeyB.first  * privateKeyB.fourth ).getDehornoyForm( );
  thePublicKeyB.second = DehornoyForm( braid_rank , -privateKeyB.fourth * privateKeyB.second * privateKeyB.fifth ).getDehornoyForm( );
  thePublicKeyB.third  = DehornoyForm( braid_rank , -privateKeyB.fifth  * privateKeyB.third ).getDehornoyForm( );
  
  theSharedKey = ThRightNormalForm( braid_rank , privateKeyA.first * privateKeyB.first * privateKeyA.second * privateKeyB.second * privateKeyA.third * privateKeyB.third );
  
  
}
set<ThRightNormalForm> 
ThRightNormalForm::computeCentralizer( ) const
{
  const Permutation omega = Permutation::getHalfTwistPermutation( theRank );
  
  set<ThRightNormalForm> result;
  
  map< ThRightNormalForm , ThRightNormalForm > new_states;
  map< ThRightNormalForm , ThRightNormalForm > unchecked_states;
  map< ThRightNormalForm , ThRightNormalForm > checked_states;
  
  if( theOmegaPower<0 ) {
    ThRightNormalForm rep = *this;
    rep.theOmegaPower = -theOmegaPower%2;
    cout << "Power = " << rep.theOmegaPower << endl;
    new_states[rep] = ThRightNormalForm( theRank );
  } else 
    new_states[*this] = ThRightNormalForm( theRank );
/*
  cout << endl << "  init:" << endl;
  cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
  cout << (*new_states.begin( )).first;
  cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
*/  
  
  while( !new_states.empty( ) ) {
    
    { // was unsupported by MSVC++
      // checked_states.insert( unchecked_states.begin(), unchecked_states.end() );
      map< ThRightNormalForm , ThRightNormalForm >::iterator m_it = unchecked_states.begin( );
      for( ; m_it!=unchecked_states.end( ) ; ++m_it )
        checked_states.insert( *m_it );
    }

    // process all new vertices:
    unchecked_states = new_states;
    new_states.clear( );
    
    size_t counter = 0;
    map< ThRightNormalForm , ThRightNormalForm >::const_iterator 
      it = unchecked_states.begin( );
    for( ; it!=unchecked_states.end( ) ; ++it ) {
      
      ThRightNormalForm cur_el = (*it).first;
      ThRightNormalForm cur_conj = (*it).second;

/*
			cout << endl << "  cur_el:" << endl;
			cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
			cout << cur_el;
			cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
*/
      // cout << "c1" << endl;
      // cout << cur_el << endl;
      // set<Permutation> conjugators = getSimpleSummitConjugators( G , cur_el );
      set<Permutation> conjugators = cur_el.getSimpleConjugators( );
      // cout << "c2" << endl;
      
      for( set<Permutation>::const_iterator conj_it = conjugators.begin( ) ; conj_it!=conjugators.end( ) ; ++conj_it ) {
				
	ThRightNormalForm r_mult( theRank , 0 , list<Permutation>( 1 , *conj_it ) );
	if( *conj_it==omega )
	  r_mult = ThRightNormalForm( theRank , 1 , list<Permutation>( 0 ) );
	ThRightNormalForm new_el = -r_mult * cur_el * r_mult;
	ThRightNormalForm new_conj = cur_conj * r_mult;

/*
				cout << "**********************************************" << endl;
				cout << endl << "  new_el:" << endl;
				cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
				cout << new_el;
				cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;

				cout << endl << "  new_conj:" << endl;
				cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
				cout << new_conj;
				cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
*/
				
	// check whether we made a loop
	map< ThRightNormalForm , ThRightNormalForm >::const_iterator 
	  fit = new_states.find( new_el );
	if( fit!=new_states.end( ) ) {
	  result.insert( new_conj * -(*fit).second );
	  continue;
	}
	
	fit = unchecked_states.find( new_el );
	if( fit!=unchecked_states.end( ) ) {
	  result.insert( new_conj * -(*fit).second );
	  continue;
	}
	
	fit = checked_states.find( new_el );
	if( fit!=checked_states.end( ) ) {
	  result.insert( new_conj * -(*fit).second );
	  continue;
	}
	
	cout << "Size = " << new_states.size( ) << "," << unchecked_states.size( ) << "," << checked_states.size( ) << " (" << result.size( ) << ")" << endl;
	new_states[new_el] = new_conj;
	// cout << cur_el << endl;
	// cout << new_el;
	// cout << "+++++++++++++++++++++++++++++++" << endl;

	if( counter!=result.size( ) ) {
	  ofstream of( "out.txt" );
	  set<ThRightNormalForm>::iterator r_it = result.begin();
	  for( ; r_it!=result.end( ) ; ++r_it ) {
	    Word w = shortBraidForm( theRank , (*r_it).getShortWord() );
	    of << w << endl;
	  }
	  counter = result.size( );
	}
	
	
	
	if( new_el.theOmegaPower<0 ) {
	  cerr << "Fail" << endl;
	  exit(1);
	}
      }
    }
  }


  cout << "+++++++++++++++++++++++++++++++" << endl;
  set<ThRightNormalForm>::iterator r_it = result.begin( );
	for( ; r_it!=result.end( ) ; ++r_it ) {
		cout << *r_it << endl;
		ThRightNormalForm n = -(*r_it) * (*this) * (*r_it);
		if( n!=*this ) {
			cout << "Error!" << endl;
			exit( 23 );
		}
	}


  return result;
}