/**
   * Performs the two-phase voting on the decree. After the voting each group member remains in the
   * same state as others.
   */
  public boolean vote(Object decree, long timeout, VoteResponseProcessor voteResponseProcessor)
      throws ChannelException {
    // wrap real decree
    TwoPhaseWrapper wrappedDecree = new TwoPhaseWrapper(decree);

    // check the decree acceptance
    try {
      if (voteChannel.vote(wrappedDecree, timeout / 3, voteResponseProcessor)) {
        wrappedDecree.commit();

        // try to commit decree
        if (!voteChannel.vote(wrappedDecree, timeout / 3, voteResponseProcessor)) {
          // strange, should fail during prepare... abort all
          wrappedDecree.abort();
          voteChannel.vote(wrappedDecree, timeout / 3, voteResponseProcessor);
          return false;
        } else return true;

      } else {
        // somebody is not accepting the decree... abort
        wrappedDecree.abort();
        voteChannel.vote(wrappedDecree, timeout / 3, voteResponseProcessor);
        return false;
      }
    } catch (ChannelException chex) {
      wrappedDecree.abort();
      voteChannel.vote(wrappedDecree, timeout / 3, voteResponseProcessor);
      throw chex;
    }
  }
 /** Removes the listener from the voteChannel */
 public void removeListener(TwoPhaseVotingListener listener) {
   voteChannel.removeVoteListener(new TwoPhaseVoteWrapper(listener));
 }
 /** Wraps actual listener with the VoteChannelListener and adds to the voteChannel */
 public void addListener(TwoPhaseVotingListener listener) {
   voteChannel.addVoteListener(new TwoPhaseVoteWrapper(listener));
 }