@SuppressWarnings({"rawtypes", "unchecked"})
  @Override
  public void planBody() {
    ABMBDILoggerSetter.setup(LOGGER);
    // *System.out.println("["+agentID+"]"+"---IN IDLE PLAN BEFORE CALCULATE ROOT");
    int noOfRoot = calculateNoOfRoot();
    noOfRoot--; // This plan itself is considered as a TopLevelGoal root.
    int noOfWait = ((SyncInteger) getBeliefbase().getBelief("noOfWait").getFact()).read();
    // System.out.println("["+agentID+"]"+"---NO WAIT :"+noOfWait + "---NO ROOT :"+noOfRoot);
    // This rechecks of condition is required,
    // as there is a possibility of messages to be handed down during
    if (noOfRoot == noOfWait) {
      startAtomic();
      // *System.out.println("["+agentID+"]"+"*****************IDLE*********");
      // Prevent other plan to execute
      getBeliefbase().getBelief("isIdle").setFact(true);
      ISpaceObject myself = (ISpaceObject) getBeliefbase().getBelief("myself").getFact();
      // idle
      getBeliefbase().getBelief("agentState").setFact(IDLE);

      Map parameters = new HashMap();
      parameters.put("objectID", myself.getId());
      parameters.put("objectType", myself.getType());
      parameters.put("agentID", myself.getProperty("agentID"));

      callEnvironmentAction("idle_action", parameters);
      // LOGGER.info(myself.getProperty("agentID") + " IDLE");
      endAtomic();
      super.waitForFactChanged("agentState"); // agentState change will be triggered by Environment

      int agentState = (Integer) getBeliefbase().getBelief("agentState").getFact();
      // *System.out.println(agentID+"------just wake up");
      // updateBelief
      if (agentState == RUN_ACTION_PERCEPT || agentState == RUN_NOACTION_PERCEPT) {
        updateAgentBeliefs();
      }
      // System.out.println("------belief updated :" + this);
      // Signal Changes of Action State.
      if (agentState == RUN_ACTION_PERCEPT || agentState == RUN_ACTION_NOPERCEPT) {
        getBeliefbase()
            .getBelief("actionChange")
            .setFact(!((Boolean) getBeliefbase().getBelief("actionChange").getFact()));
        // System.out.println("------belief updated :" + this);
      }
      getBeliefbase().getBelief("isIdle").setFact(false);

    } else {
      fail();
    }
  }
  @Override
  public void execute(
      IEnvironmentSpace environment, ISpaceObject obj, long progress, IClockService clock) {

    Vector2Int targetPosition = (Vector2Int) getProperty(PROPERTY_DESTINATION);

    Collection<ISpaceObject> spaceObjectsByGridPosition =
        ((Grid2D) environment).getSpaceObjectsByGridPosition(targetPosition, null);
    for (ISpaceObject spaceObject : spaceObjectsByGridPosition) {
      for (MapType mapType : MapType.getOnlySolids()) {
        if (mapType.toString().equals(spaceObject.getType())) {
          currentTaskSpaceObject = (SpaceObject) spaceObject;
        }
      }
    }

    TileChanger tilechanger = new TileChanger((Grid2D) environment);
    String neighborhood = (String) currentTaskSpaceObject.getProperty(ISO.Properties.NEIGHBORHOOD);
    tilechanger
        .addParameter("bearbeitung", new Integer(0))
        .addParameter(ISO.Properties.STATUS, "byImpCreated")
        .addParameter(ISO.Properties.CLICKED, false)
        .addParameter(ISO.Properties.LOCKED, false)
        .addParameter(ISO.Properties.NEIGHBORHOOD, neighborhood)
        .addParameter(ISO.Properties.INTPOSITION, targetPosition)
        .addParameter(
            ISO.Properties.DOUBLE_POSITION,
            new Vector2Double(targetPosition.getXAsDouble(), targetPosition.getYAsDouble()))
        .changeTile(
            targetPosition,
            MapType.DIRT_PATH,
            new ArrayList<MapType>(Arrays.asList(MapType.GOLD_DROPED)));

    // imp stop claiming the sector ground
    obj.setProperty(ISObjStrings.PROPERTY_STATUS, "Idle");

    this.setFinished(environment, obj, true);
  }
  private IFuture<Void> reachTargetDestination(final Task currentImpTask) {
    final Future<Void> ret = new Future<Void>();

    final Vector2Int currentImpTaskPosition = currentImpTask.getTargetPosition();

    Collection<ISpaceObject> spaceObjectsByGridPosition =
        environment.getSpaceObjectsByGridPosition(currentImpTask.getTargetPosition(), null);
    for (ISpaceObject spaceObject : spaceObjectsByGridPosition) {
      if (MapType.DIRT_PATH.toString().equals(spaceObject.getType())) {
        currentTaskSpaceObject = (SpaceObject) spaceObject;
      }
    }

    if (currentImpTaskPosition != null && currentTaskSpaceObject != null) {
      // went to the position where the imp can dig from
      if (currentImpTask.getTargetPosition() != null) {
        IFuture<AchieveMoveToSector> reachSectorToDigFrom =
            rplan.dispatchSubgoal(capa.new AchieveMoveToSector(currentImpTask.getTargetPosition()));

        reachSectorToDigFrom.addResultListener(
            new ExceptionDelegationResultListener<AbstractCreatureBDI.AchieveMoveToSector, Void>(
                ret) {
              public void customResultAvailable(AbstractCreatureBDI.AchieveMoveToSector amt) {
                claimSector(currentImpTask)
                    .addResultListener(
                        new DelegationResultListener<Void>(ret) {
                          public void customResultAvailable(Void result) {
                            // add new Tile and remove the old, claim the sector ground

                            Map<String, Object> props = new HashMap<String, Object>();
                            props.put("Task", currentImpTask);
                            props.put(
                                ClaimSectorChangeTileTask.PROPERTY_DESTINATION,
                                currentImpTask.getTargetPosition());
                            claimtaskid =
                                capa.getEnvironment()
                                    .createObjectTask(
                                        ClaimSectorChangeTileTask.PROPERTY_TYPENAME,
                                        props,
                                        capa.getMySpaceObject().getId());
                            cplan
                                .invokeInterruptable(
                                    new IResultCommand<IFuture<Void>, Void>() {
                                      public IFuture<Void> execute(Void args) {
                                        return capa.getEnvironment()
                                            .waitForTask(
                                                claimtaskid, capa.getMySpaceObject().getId());
                                      }
                                    })
                                .addResultListener(new DelegationResultListener<Void>(ret));

                            ret.setResult(null);
                          }
                        });
              }
            });
      } else {
        // TODO: fail!! sector from task should be reachable for destroy
        // => catch
        System.out.println("fail!! sector from task should be reachable for destroy ");
        capa.getMySpaceObject().setProperty(ISObjStrings.PROPERTY_STATUS, "Idle");
        rplan.abort();
      }
    } else {
      System.out.println("ClaimSectorPlan: Task has no Int Position");
      rplan.abort();
    }
    return ret;
  }