private void allCorrect() {
    int reg;
    for (reg = 0; reg < NUM_REGISTERS; reg++) {

      boolean allAcks = true;
      int i;
      for (i = 0; (i < correct.getSize()) && allAcks; i++) {
        SampleProcess p = correct.getProcess(i);
        if (p.isCorrect() && !writeSet.get(reg).contains(p)) allAcks = false;
      }
      if (allAcks) {
        writeSet.get(reg).clear();

        try {
          SharedWriteReturn ev = new SharedWriteReturn(mainchannel, Direction.UP, this);
          ev.reg = reg;
          ev.go();

          debug("Sent WriteReturn");
        } catch (AppiaEventException ex) {
          ex.printStackTrace();
        }
      }
    }
  }
 private void handleProcessInit(ProcessInitEvent event) {
   correct = event.getProcessSet();
   init();
   try {
     event.go();
   } catch (AppiaEventException ex) {
     ex.printStackTrace();
   }
 }
 private void handleSharedRead(SharedRead event) {
   try {
     SharedReadReturn ev = new SharedReadReturn(mainchannel, Direction.UP, this);
     ev.reg = event.reg;
     ev.value = value[event.reg];
     ev.go();
   } catch (AppiaEventException ex) {
     ex.printStackTrace();
   }
 }
  private void handleCrash(Crash event) {
    correct.setCorrect(event.getCrashedProcess(), false);

    try {
      event.go();
    } catch (AppiaEventException ex) {
      ex.printStackTrace();
    }

    allCorrect();
  }
  private void handleSharedWrite(SharedWrite event) {
    debug("received SharedWrite");

    try {
      WriteEvent ev = new WriteEvent(mainchannel, Direction.DOWN, this);
      ev.getMessage().pushObject(event.value);
      ev.getMessage().pushInt(event.reg);
      ev.go();
    } catch (AppiaEventException ex) {
      ex.printStackTrace();
    }
  }
  private void handleWriteEvent(WriteEvent event) {
    int reg = event.getMessage().popInt();
    Object val = event.getMessage().popObject();

    value[reg] = val;

    try {
      AckEvent ev = new AckEvent(pp2pchannel, Direction.DOWN, this);
      ev.getMessage().pushInt(reg);
      ev.dest = event.source;
      ev.go();
    } catch (AppiaEventException ex) {
      ex.printStackTrace();
    }
  }
  public void handle(Event event) {

    if (event instanceof ChannelInit) handleChannelInit((ChannelInit) event);
    else if (event instanceof ProcessInitEvent) handleProcessInit((ProcessInitEvent) event);
    else if (event instanceof Crash) handleCrash((Crash) event);
    else if (event instanceof SharedRead) handleSharedRead((SharedRead) event);
    else if (event instanceof SharedWrite) handleSharedWrite((SharedWrite) event);
    else if (event instanceof WriteEvent) handleWriteEvent((WriteEvent) event);
    else if (event instanceof AckEvent) handleAckEvent((AckEvent) event);
    else {
      debug("Unwanted event received (\"" + event + "\"), ignoring.");
      try {
        event.go();
      } catch (AppiaEventException ex) {
        ex.printStackTrace();
      }
    }
  }
  private void handleChannelInit(ChannelInit init) {
    if (mainchannel == null) {
      mainchannel = init.getChannel();
      debug("mainchannel initiated");
      try {
        pp2pinit.start();
      } catch (AppiaDuplicatedSessionsException ex) {
        ex.printStackTrace();
      }
    } else {
      if (init.getChannel() == pp2pinit) {
        pp2pchannel = init.getChannel();
      }
    }

    try {
      init.go();
    } catch (AppiaEventException ex) {
      ex.printStackTrace();
    }
  }