public synchronized void recover(TransactionRecoveryListener listener) throws IOException {
    for (Map.Entry<TransactionId, List<Operation>> entry :
        theStore.preparedTransactions.entrySet()) {
      XATransactionId xid = (XATransactionId) entry.getKey();
      ArrayList<Message> messageList = new ArrayList<Message>();
      ArrayList<MessageAck> ackList = new ArrayList<MessageAck>();

      for (Operation op : entry.getValue()) {
        if (op.getClass() == AddOpperation.class) {
          AddOpperation addOp = (AddOpperation) op;
          Message msg =
              (Message)
                  wireFormat()
                      .unmarshal(new DataInputStream(addOp.getCommand().getMessage().newInput()));
          messageList.add(msg);
        } else {
          RemoveOpperation rmOp = (RemoveOpperation) op;
          Buffer ackb = rmOp.getCommand().getAck();
          MessageAck ack =
              (MessageAck) wireFormat().unmarshal(new DataInputStream(ackb.newInput()));
          ackList.add(ack);
        }
      }

      Message[] addedMessages = new Message[messageList.size()];
      MessageAck[] acks = new MessageAck[ackList.size()];
      messageList.toArray(addedMessages);
      ackList.toArray(acks);
      xid.setPreparedAcks(ackList);
      theStore.trackRecoveredAcks(ackList);
      listener.recover(xid, addedMessages, acks);
    }
  }