@Override
    public void receiveOrder(OrderMessage message) throws RemoteException {
        LOGGER.debug(echoIndex() + "received order from " + message.getSender());
        incomingMessages.put(message.getAlreadyProcessed(), message);
        sendAck(message);

        //valid for the exchange rounds starting from 2, when commander doesn't participate in the exchange process
        if (message.getSender() != 0) {
            LOGGER.debug(echoIndex() + "Traitors: " + message.getMaxTraitors());
            Step step = stepMap.get(message.getMaxTraitors());
            if (step == null) {
                step = new Step(numProcesses, message.getMaxTraitors());
                stepMap.put(message.getMaxTraitors(), step);
            }
            step.addMessage(message);
            if (step.isReady()) {
                LOGGER.debug(echoIndex() + "Step ready");
                processStep(step);
            } else if (step.isWaitingForMissedMessages()) {
                LOGGER.debug(echoIndex() + "Step waiting");
                try {
                    Thread.sleep(Step.WAITING_TIME_OUT * 2);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                if (firstMessageReceived) {
                    processStep(step);
                }
            }

            //valid for rounds 0 and 1, when commander receives order from client (0)
            // and redistributes it among lieutenants (1)
        } else {
            firstMessageReceived = true;
            process(message);
            Step firstStep = stepMap.get(message.getMaxTraitors() - 1);
            if (firstStep != null && firstStep.isReady()) {
                LOGGER.debug(echoIndex() + "firstStep ready");
                processStep(firstStep);
            }
        }
    }