virtual void Shuffle()
      {
        Random &rand = Random::GetInstance();
        if((rand.GetInt(0, 1024) / 1024.0) > N) {
          ShuffleRound::Shuffle();
          return;
        }

        SetTriggered();

        for(int idx = 0; idx < _server_state->shuffle_input.count(); idx++) {
          for(int jdx = 0; jdx < _server_state->shuffle_input.count(); jdx++) {
            if(idx == jdx) {
              continue;
            }
            if(_server_state->shuffle_input[idx] != _server_state->shuffle_input[jdx]) {
              continue;
            }
            qWarning() << "Found duplicate cipher texts... blaming";
            _state->blame = true;
          }
        }

        int x = Random::GetInstance().GetInt(0, _server_state->shuffle_input.count());
        int y = Random::GetInstance().GetInt(0, _server_state->shuffle_input.count());
        while(y == x) {
          y = Random::GetInstance().GetInt(0, _server_state->shuffle_input.count());
        }

        _server_state->shuffle_input[x] = _server_state->shuffle_input[y];
  
        QVector<int> bad;
        QSharedPointer<OnionEncryptor> oe;
        if(Utils::MultiThreading) {
          oe = QSharedPointer<OnionEncryptor>(new ThreadedOnionEncryptor());
        } else {
          oe = QSharedPointer<OnionEncryptor>(new OnionEncryptor());
        }

        if(!oe->Decrypt(_server_state->outer_key, _server_state->shuffle_input,
              _server_state->shuffle_output, &bad))
        {
          qWarning() << GetGroup().GetIndex(GetLocalId()) << GetLocalId() <<
            ": failed to decrypt layer due to block at indexes" << bad;
          _state->blame = true;
        } 
        
        oe->RandomizeBlocks(_server_state->shuffle_output);
        
        const Id &next = GetShufflers().Next(GetLocalId());
        MessageType mtype = (next == Id::Zero()) ? ENCRYPTED_DATA : SHUFFLE_DATA;
        
        QByteArray msg;
        QDataStream out_stream(&msg, QIODevice::WriteOnly);
        out_stream << mtype << GetRoundId() << _server_state->shuffle_output;
          
        if(mtype == ENCRYPTED_DATA) {
          VerifiableBroadcast(msg);
        } else {
          VerifiableSend(next, msg);
        }

        _state_machine.StateComplete();
      }