/* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#stepSimulation(agentgui.simulationService.environment.EnvironmentModel, boolean)
   */
  @Override
  public void stepSimulation(EnvironmentModel envModel, boolean aSynchron) throws IMTPException {

    try {
      // --- Notify the LoadService -----------------
      GenericCommand cmd = new GenericCommand(SIM_STEP_SIMULATION, LoadService.NAME, null);
      getNode().accept(cmd);

      // --- Notify the SimulationService -----------
      cmd = new GenericCommand(SIM_STEP_SIMULATION, SimulationService.NAME, null);
      cmd.addParam(envModel);
      cmd.addParam(aSynchron);

      Object result = getNode().accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  public void synchReplication(GlobalReplicationInfo info) throws IMTPException {
    GenericCommand cmd = new GenericCommand(H_SYNCHREPLICATION, AgentReplicationService.NAME, null);
    cmd.addParam(info.getVirtual());
    cmd.addParam(info.getMaster());
    cmd.addParam(info.getReplicationMode());
    cmd.addParam(info.getAllReplicas());

    try {
      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Error accessing remote node", se);
    }
  }
  public void invokeAgentMethod(AID aid, String methodName, Object[] arguments)
      throws IMTPException, ServiceException, NotFoundException {
    GenericCommand cmd =
        new GenericCommand(H_INVOKEAGENTMETHOD, AgentReplicationService.NAME, null);
    cmd.addParam(aid);
    cmd.addParam(methodName);
    cmd.addParam(arguments);

    Node n = getNode();
    Object result = n.accept(cmd);
    if ((result != null) && (result instanceof Throwable)) {
      if (result instanceof NotFoundException) {
        throw (NotFoundException) result;
      } else if (result instanceof ServiceException) {
        throw (ServiceException) result;
      } else if (result instanceof IMTPException) {
        throw (IMTPException) result;
      } else {
        throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
      }
    }
  }
  public void notifyReplicaRemoved(AID masterAid, AID removedReplica, Location where)
      throws IMTPException {
    GenericCommand cmd =
        new GenericCommand(H_NOTIFYREPLICAREMOVED, AgentReplicationService.NAME, null);
    cmd.addParam(masterAid);
    cmd.addParam(removedReplica);
    cmd.addParam(where);

    try {
      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Error accessing remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#setEnvironmentModel(agentgui.simulationService.environment.EnvironmentModel)
   */
  @Override
  public void setEnvironmentModel(EnvironmentModel envModel, boolean notifySensorAgents)
      throws IMTPException {

    try {
      GenericCommand cmd =
          new GenericCommand(SIM_SET_ENVIRONMENT_MODEL, SimulationService.NAME, null);
      cmd.addParam(envModel);
      cmd.addParam(notifySensorAgents);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#notifyAgent(jade.core.AID, agentgui.simulationService.transaction.EnvironmentNotification)
   */
  @Override
  public boolean notifyAgent(AID agentAID, EnvironmentNotification notification)
      throws IMTPException {

    try {
      GenericCommand cmd = new GenericCommand(SIM_NOTIFY_AGENT, SimulationService.NAME, null);
      cmd.addParam(agentAID);
      cmd.addParam(notification);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
      return (Boolean) result;
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  public void notifyBecomeMaster(AID masterAid) throws IMTPException {
    GenericCommand cmd =
        new GenericCommand(H_NOTIFYBECOMEMASTER, AgentReplicationService.NAME, null);
    cmd.addParam(masterAid);

    try {
      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Error accessing remote node", se);
    }
  }
  public void replicaCreationRequested(AID virtualAid, AID replicaAid) throws IMTPException {
    GenericCommand cmd =
        new GenericCommand(H_REPLICACREATIONREQUESTED, AgentReplicationService.NAME, null);
    cmd.addParam(virtualAid);
    cmd.addParam(replicaAid);

    try {
      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Error accessing remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#setManagerAgent(agentgui.simulationService.transaction.EnvironmentManagerDescription)
   */
  @Override
  public void setManagerAgent(EnvironmentManagerDescription envManager) throws IMTPException {

    try {
      GenericCommand cmd = new GenericCommand(SIM_SET_MANAGER_AGENT, SimulationService.NAME, null);
      cmd.addParam(envManager);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#setAgentMigration(java.util.Vector)
   */
  @Override
  public void setAgentMigration(Vector<AID_Container> transferAgents) throws IMTPException {
    try {
      GenericCommand cmd =
          new GenericCommand(SERVICE_SET_AGENT_MIGRATION, SimulationService.NAME, null);
      cmd.addParam(transferAgents);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#setPauseSimulation(boolean)
   */
  @Override
  public void setPauseSimulation(boolean pauseSimulation) throws IMTPException {

    try {
      GenericCommand cmd = new GenericCommand(SIM_PAUSE_SIMULATION, SimulationService.NAME, null);
      cmd.addParam(pauseSimulation);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#setAnswersExpected(int)
   */
  @Override
  public void setAnswersExpected(int answersExpected) throws IMTPException {

    try {
      GenericCommand cmd =
          new GenericCommand(SIM_SET_ANSWERS_EXPECTED, SimulationService.NAME, null);
      cmd.addParam(answersExpected);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#setRemoteTimeDiff(long)
   */
  @Override
  public void setRemoteTimeDiff(long timeDifference) throws IMTPException {

    try {
      GenericCommand cmd =
          new GenericCommand(SERVICE_SYNCH_SET_TIME_DIFF, SimulationService.NAME, null);
      cmd.addParam(timeDifference);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#displayAgentNotification(agentgui.simulationService.transaction.EnvironmentNotification)
   */
  @Override
  public void displayAgentNotification(EnvironmentNotification notification) throws IMTPException {
    try {
      GenericCommand cmd =
          new GenericCommand(SERVICE_DISPLAY_AGENT_NOTIFICATION, SimulationService.NAME, null);
      cmd.addParam(notification);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }

    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#notifyManagerPutAgentAnswers(java.util.Hashtable)
   */
  @Override
  public void notifyManagerPutAgentAnswers(Hashtable<AID, Object> allAgentAnswers)
      throws IMTPException {
    try {
      GenericCommand cmd =
          new GenericCommand(SIM_NOTIFY_MANAGER_PUT_AGENT_ANSWERS, SimulationService.NAME, null);
      cmd.addParam(allAgentAnswers);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
  public ContainerID getAgentLocation(AID aid) throws IMTPException, NotFoundException {
    GenericCommand cmd = new GenericCommand(H_GETAGENTLOCATION, AgentReplicationService.NAME, null);
    cmd.addParam(aid);

    try {
      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof NotFoundException) {
          throw (NotFoundException) result;
        } else if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
      return (ContainerID) result;
    } catch (ServiceException se) {
      throw new IMTPException("Error accessing remote node", se);
    }
  }
  /* (non-Javadoc)
   * @see agentgui.simulationService.SimulationServiceSlice#setEnvironmentInstanceNextPart(java.util.Hashtable)
   */
  @Override
  public void setEnvironmentInstanceNextPart(Hashtable<AID, Object> nextPartsLocal)
      throws IMTPException {

    try {
      GenericCommand cmd =
          new GenericCommand(SIM_SET_ENVIRONMENT_NEXT_PART, SimulationService.NAME, null);
      cmd.addParam(nextPartsLocal);

      Node n = getNode();
      Object result = n.accept(cmd);
      if ((result != null) && (result instanceof Throwable)) {
        if (result instanceof IMTPException) {
          throw (IMTPException) result;
        } else {
          throw new IMTPException("An undeclared exception was thrown", (Throwable) result);
        }
      }
    } catch (ServiceException se) {
      throw new IMTPException("Unable to access remote node", se);
    }
  }
    public VerticalCommand serve(HorizontalCommand cmd) {
      VerticalCommand result = null;
      try {
        String cmdName = cmd.getName();
        Object[] params = cmd.getParams();

        if (cmdName.equals(AgentManagementSlice.H_CREATEAGENT)) {
          GenericCommand gCmd =
              new GenericCommand(
                  AgentManagementSlice.REQUEST_CREATE, AgentManagementSlice.NAME, null);
          AID agentID = (AID) params[0];
          String className = (String) params[1];
          Object[] arguments = (Object[]) params[2];
          JADEPrincipal owner = (JADEPrincipal) params[3];
          Credentials initialCredentials = (Credentials) params[4];
          Boolean startIt = (Boolean) params[5];
          gCmd.addParam(agentID);
          gCmd.addParam(className);
          gCmd.addParam(arguments);
          gCmd.addParam(owner);
          gCmd.addParam(initialCredentials);
          gCmd.addParam(startIt);

          result = gCmd;
        } else if (cmdName.equals(AgentManagementSlice.H_KILLAGENT)) {
          GenericCommand gCmd =
              new GenericCommand(
                  AgentManagementSlice.REQUEST_KILL, AgentManagementSlice.NAME, null);
          AID agentID = (AID) params[0];
          gCmd.addParam(agentID);

          result = gCmd;
        } else if (cmdName.equals(AgentManagementSlice.H_CHANGEAGENTSTATE)) {
          GenericCommand gCmd =
              new GenericCommand(
                  AgentManagementSlice.REQUEST_STATE_CHANGE, AgentManagementSlice.NAME, null);
          AID agentID = (AID) params[0];
          Integer newState = (Integer) params[1];
          gCmd.addParam(agentID);
          gCmd.addParam(newState);

          result = gCmd;
        } else if (cmdName.equals(AgentManagementSlice.H_BORNAGENT)) {
          GenericCommand gCmd =
              new GenericCommand(
                  AgentManagementSlice.INFORM_CREATED, AgentManagementSlice.NAME, null);
          AID agentID = (AID) params[0];
          ContainerID cid = (ContainerID) params[1];
          gCmd.addParam(agentID);
          gCmd.addParam(cid);

          JADEPrincipal owner = cmd.getPrincipal();
          if (myLogger.isLoggable(Logger.FINE)) {
            String ownerInfo = owner != null ? ", Owner = " + owner : "";
            myLogger.log(
                Logger.CONFIG,
                "Local slice processing H-command BORN_AGENT. Name is "
                    + agentID.getName()
                    + ownerInfo);
          }

          result = gCmd;
        } else if (cmdName.equals(AgentManagementSlice.H_DEADAGENT)) {
          GenericCommand gCmd =
              new GenericCommand(
                  AgentManagementSlice.INFORM_KILLED, AgentManagementSlice.NAME, null);
          AID agentID = (AID) params[0];
          gCmd.addParam(agentID);

          result = gCmd;
        } else if (cmdName.equals(AgentManagementSlice.H_SUSPENDEDAGENT)) {
          GenericCommand gCmd =
              new GenericCommand(
                  AgentManagementSlice.INFORM_STATE_CHANGED, AgentManagementSlice.NAME, null);
          AID agentID = (AID) params[0];
          gCmd.addParam(agentID);
          gCmd.addParam(jade.domain.FIPAAgentManagement.AMSAgentDescription.SUSPENDED);
          gCmd.addParam("*");

          result = gCmd;
        } else if (cmdName.equals(AgentManagementSlice.H_RESUMEDAGENT)) {
          GenericCommand gCmd =
              new GenericCommand(
                  AgentManagementSlice.INFORM_STATE_CHANGED, AgentManagementSlice.NAME, null);
          AID agentID = (AID) params[0];
          gCmd.addParam(agentID);
          gCmd.addParam(jade.domain.FIPAAgentManagement.AMSAgentDescription.ACTIVE);
          gCmd.addParam(jade.domain.FIPAAgentManagement.AMSAgentDescription.SUSPENDED);

          result = gCmd;
        } else if (cmdName.equals(AgentManagementSlice.H_EXITCONTAINER)) {
          GenericCommand gCmd =
              new GenericCommand(
                  AgentManagementSlice.KILL_CONTAINER, AgentManagementSlice.NAME, null);

          result = gCmd;
        }

      } catch (Throwable t) {
        cmd.setReturnValue(t);
      }
      return result;
    }