// Run the protocol without creating a new thread.
  public Transaction runProtocol(
      long amount, // The amount to be shuffled per player.
      long fee, // The miner fee to be paid per player.
      SigningKey sk, // The signing key of the current player.
      // The set of players, sorted alphabetically by address.
      SortedSet<VerificationKey> players,
      Address addrNew, // My new (anonymous) address.
      Address change, // Change address. (can be null)
      // If this is not null, the machine is put in this channel so that another thread can
      // query the phase as it runs.
      Send<Phase> chan)
      throws TimeoutException, Matrix, InterruptedException, InvalidParticipantSetException,
          FormatException, IOException, CoinNetworkException, ExecutionException,
          AddressFormatException {

    if (amount <= 0) {
      throw new IllegalArgumentException();
    }
    if (sk == null || players == null) {
      throw new NullPointerException();
    }

    CurrentPhase machine;
    if (chan == null) {
      machine = new CurrentPhase();
    } else {
      machine = new CurrentPhase(chan);
    }

    // Get the initial ordering of the players.
    int i = 1;
    Map<Integer, VerificationKey> numberedPlayers = new TreeMap<>();
    for (VerificationKey player : players) {
      numberedPlayers.put(i, player);
      i++;
    }

    // Make an inbox for the next round.
    Mailbox mailbox = new Mailbox(sk.VerificationKey(), numberedPlayers.values(), messages);

    return this.new Round(machine, amount, fee, sk, numberedPlayers, addrNew, change, mailbox)
        .protocolDefinition();
  }
    // A round is a single run of the protocol.
    Round(
        CurrentPhase phase,
        long amount,
        long fee,
        SigningKey sk,
        Map<Integer, VerificationKey> players,
        Address addrNew,
        Address change,
        Mailbox mailbox)
        throws InvalidParticipantSetException {

      this.phase = phase;
      this.amount = amount;
      this.fee = fee;
      this.sk = sk;
      this.players = players;
      this.change = change;
      vk = sk.VerificationKey();
      this.mailbox = mailbox;
      this.addrNew = addrNew;

      int m = -1;
      N = players.size();

      // Determine what my index number is.
      for (int i = 1; i <= N; i++) {
        if (players.get(i).equals(vk)) {
          m = i;
          break;
        }
      }
      me = m;

      if (me < 0) {
        throw new InvalidParticipantSetException(vk, players);
      }
    }