@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
  protected void aktion() {

    Vector2Double einheit = (Vector2Double) _einheit.getProperty("position");
    Vector2Double meinepos = (Vector2Double) _avatar.getProperty(Space2D.PROPERTY_POSITION);

    if ((einheit.getDistance(meinepos)).getAsDouble() <= 1.0) {
      _ausfuehr = false;
      return;
    }

    if (_schritt == 0) {
      IVector2 zielpos = (IVector2) _einheit.getProperty("position");
      _mypos = (IVector2) _avatar.getProperty(Space2D.PROPERTY_POSITION);
      _startvektor = _mypos.copy();
      _zielvektor = zielpos.copy();

      _suche = new AStarSearch(_startvektor, _zielvektor, grid, true);
      _erreichbar = _suche.istErreichbar();
      if (_erreichbar) {

        Stack<Vector2Int> pfad = _suche.gibPfad();

        if (pfad.isEmpty()) {
          _ausfuehr = false;
          return;
        }
        pfad.pop();
        Vector2Int nextp = new Vector2Int(pfad.pop());

        Vector2Double nextpdouble = new Vector2Double(nextp);

        IVector2 nextpos = nextpdouble.add(0.5);

        _x_m = _mypos.copy().getXAsDouble();
        _y_m = _mypos.copy().getYAsDouble();
        double x_ne = nextpos.copy().getXAsDouble();
        double y_ne = nextpos.copy().getYAsDouble();
        _x_nd = x_ne - _x_m;
        _y_nd = _y_m - y_ne;
      } else {
        _ausfuehr = false;
        return;
      }
    }

    if (_erreichbar) {
      bewegung();
    }
  }
  @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 void updateAgentBeliefs() {
    ISpaceObject myself = (ISpaceObject) getBeliefbase().getBelief("myself").getFact();
    PerceptContainer localPerceptContainer =
        (PerceptContainer) myself.getProperty("perceptContainer");
    // Update Agent Beliefs
    Set<String> perceptIDSet = localPerceptContainer.perceptIDSet();
    // System.out.println("~~~~~Inside belief update :" + perceptIDSet.size() +"-"+this);
    // for (String perceptID : perceptIDSet)
    Object[] perceptIDSetA = perceptIDSet.toArray();
    for (int m = 0; m < perceptIDSetA.length; m++) {
      String perceptID = (String) perceptIDSetA[m];
      startAtomic();
      IGoal[] oldGoal = this.getGoalbase().getGoals();
      try {
        if (getBeliefbase().containsBelief(perceptID)) {
          Object oldFact = getBeliefbase().getBelief(perceptID).getFact();
          Object newFact = localPerceptContainer.read(perceptID);
          //					if (oldFact == null)
          //						System.out.println("NULLL OLD FACT CREATE EXCEPTION!");
          if (!newFact.equals(oldFact)) {
            getBeliefbase().getBelief(perceptID).setFact(newFact);
          }
          // System.out.println("------Inside belief update :" + perceptID +"-"+this);
        } else if (getBeliefbase().containsBeliefSet(perceptID)) {
          IBeliefSet beliefSet = getBeliefbase().getBeliefSet(perceptID);
          Object newFact = localPerceptContainer.read(perceptID);

          if (newFact.getClass().equals(beliefSet.getClazz())) {
            // Replace the old fact with the new one
            if (beliefSet.containsFact(newFact) == true) beliefSet.removeFact(newFact);
            beliefSet.addFact(newFact);
          } else {
            Object[] newFacts = (Object[]) newFact;
            for (int i = 0; i < newFacts.length; i++) {
              if (beliefSet.containsFact(newFacts[i]) == true) beliefSet.removeFact(newFacts[i]);
              beliefSet.addFact(newFacts[i]);
            }
            String nh = "";
            for (int i = 0; i < newFacts.length; i++) {
              nh = nh + newFacts[i].toString();
            }
            System.out.println(agentID + nh);
          }
        } else {
          // System.out.println("------Inside belief update");
          LOGGER.severe("perceptID is not recognized by Jadex's belief/beliefset");
          // throw new RuntimeException ("perceptID is not recognized by Jadex's belief/beliefset");
        }
      } catch (Exception e) {
        LOGGER.severe(e.getMessage());
      }

      // No need to track new number of goals, because the goal itself is created and the plan
      // are in queue to be launched even before this idleplan could dispatch another idleplan
      int noOfNewlyGeneratedGoal = this.getNoOfNewlyGeneratedGoalSince(oldGoal);
      endAtomic();
      if (noOfNewlyGeneratedGoal > 0) {
        SyncInteger noOfTopLevelGoal =
            (SyncInteger) getBeliefbase().getBelief("noOfTopLevelGoal").getFact();
        //				noOfTopLevelGoal = noOfTopLevelGoal + noOfNewlyGeneratedGoal;
        noOfTopLevelGoal.add(noOfNewlyGeneratedGoal);
        getBeliefbase().getBelief("noOfTopLevelGoal").setFact(noOfTopLevelGoal);
      }
      // System.out.println("------Inside belief update :" + perceptID +"-"+this);
    }
  }
  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;
  }