@Override
  public void moveObjectsOfPositionTo(
      ShortPoint2D position, AbstractMaterialRequestPriorityQueue newAbstractQueue) {
    assert newAbstractQueue instanceof MaterialsForBuildingsRequestPrioQueue
        : "can't move positions between diffrent types of queues.";

    MaterialsForBuildingsRequestPrioQueue newQueue =
        (MaterialsForBuildingsRequestPrioQueue) newAbstractQueue;
    final int numberOfBuildings = settings.getNumberOfBuildings();

    for (int prioIdx = 0; prioIdx < queues.length; prioIdx++) {
      DoubleLinkedList<MaterialRequestObject>[] prioQueue = queues[prioIdx];
      for (int queueIdx = 0; queueIdx < numberOfBuildings; queueIdx++) {
        Iterator<MaterialRequestObject> iter = prioQueue[queueIdx].iterator();
        while (iter.hasNext()) {
          MaterialRequestObject curr = iter.next();
          if (curr.getPos().equals(position)) {
            iter.remove();
            newQueue.queues[prioIdx][queueIdx].pushEnd(curr);
            curr.requestQueue = newQueue;
          }
        }
      }
    }
  }
  @Override
  protected MaterialRequestObject getRequestForPrio(int prio) {
    DoubleLinkedList<MaterialRequestObject>[] queues = this.queues[prio];

    int startIndex = getRandomStartIndex();

    final int numberOfBuildings = settings.getNumberOfBuildings();
    for (int i = 0; i < numberOfBuildings; i++) {
      int buildingIdx = (i + startIndex) % numberOfBuildings;

      if (settings.getProbablity(buildingIdx)
          <= 0.0f) // if this building type should not receive any materials, skip it
      continue;

      DoubleLinkedList<MaterialRequestObject> queue = queues[buildingIdx];

      int numberOfElements = queue.size();

      for (int handledElements = 0; handledElements < numberOfElements; handledElements++) {
        MaterialRequestObject result = queue.getFront();

        int inDelivery = result.inDelivery;
        int stillNeeded = result.getStillNeeded();

        // if the request is done
        if (stillNeeded <= 0) {
          result.requestQueue = null;
          queue.popFront(); // remove the request
          numberOfElements--;
        }

        // if all needed are in delivery, or there can not be any more in delivery
        else if (stillNeeded <= inDelivery || inDelivery >= result.getInDeliveryable()) {
          queue.pushEnd(queue.popFront()); // move the request to the end.
        }

        // everything fine, take this request
        else {
          if (result.isRoundRobinRequest()) {
            queue.pushEnd(queue.popFront()); // put the request to the end of the queue.
          }

          return result;
        }
      }
    }

    return null;
  }
  @Override
  public void mergeInto(AbstractMaterialRequestPriorityQueue newAbstractQueue) {
    assert newAbstractQueue instanceof MaterialsForBuildingsRequestPrioQueue
        : "can't move positions between diffrent types of queues.";

    MaterialsForBuildingsRequestPrioQueue newQueue =
        (MaterialsForBuildingsRequestPrioQueue) newAbstractQueue;
    final int numberOfBuildings = settings.getNumberOfBuildings();

    for (int prioIdx = 0; prioIdx < queues.length; prioIdx++) {
      for (int queueIdx = 0; queueIdx < numberOfBuildings; queueIdx++) {
        DoubleLinkedList<MaterialRequestObject> currList = queues[prioIdx][queueIdx];
        DoubleLinkedList<MaterialRequestObject> newList = newQueue.queues[prioIdx][queueIdx];
        for (MaterialRequestObject request : currList) {
          request.requestQueue = newQueue;
        }
        currList.mergeInto(newList);
      }
    }
  }