/**
  * Checks whether the {@code Cache} is activated and in case it is activated, all {@link Task}s of
  * the given {@link ResultSet}, which are loaded for the present time, will be put in the {@code
  * Cache}.
  *
  * @param resultSet The {@code ResultSet} with the {@code Task}s
  */
 private void putTasksIntoCache(ResultSetImpl<TaskID, Task> resultSet) {
   if (cacheActivated) {
     for (Task task : resultSet.getLoadedData()) {
       cache.put(new Element(task.getID(), task));
     }
   }
 }
  @Override
  public Task getTask(TaskID taskID, boolean loadCompletely, boolean forceAPICall) {
    if (taskID == null) {
      throw new NullPointerException();
    }

    Task task;

    if (cacheActivated) {
      if (!forceAPICall) {
        Element element = cache.get(taskID);

        if (element != null) {
          task = (Task) element.getObjectValue();

          if (loadCompletely && !((Cachable) task).isCompletelyLoaded()) {
            task = getDataFactory().getTask(taskID, loadCompletely);
          }
        } else {
          task = getDataFactory().getTask(taskID, loadCompletely);
        }
      } else {
        task = getDataFactory().getTask(taskID, loadCompletely);
      }

      if (task != null) {
        cache.put(new Element(task.getID(), task));
      }
    } else {
      task = getDataFactory().getTask(taskID, loadCompletely);
    }

    return task;
  }
  @Override
  public LinkedHashMap<TaskID, Task> getNextPageData(ResultSetImpl<TaskID, Task> resultSet) {
    if (resultSet == null) {
      throw new NullPointerException();
    }

    LinkedHashMap<TaskID, Task> resultMap = getDataFactory().getNextPageData(resultSet);

    if (cacheActivated) {
      for (Task task : resultMap.values()) {
        cache.put(new Element(task.getID(), task));
      }
    }

    return resultMap;
  }
  @Override
  public ResultSet<TaskID, Task> getAllCachedTasks() {
    if (cacheActivated) {
      LinkedHashMap<TaskID, Task> tasks = new LinkedHashMap<TaskID, Task>();

      Element element;
      Task task;

      for (Object key : cache.getKeysWithExpiryCheck()) {
        element = cache.get(key);

        if (element != null) {
          task = (Task) element.getObjectValue();
          tasks.put(task.getID(), task);
        }
      }

      return ResultSetFactory.getResultSetInstance(
          null, systemSession, false, LoadType.METADATA, tasks, null);
    } else {
      throw new CacheNotActivatedException();
    }
  }
  @Override
  public ResultSet<TaskID, Task> getTasksByIDs(
      List<TaskID> taskIDs, boolean loadCompletely, boolean forceAPICall) {
    LoadType loadType;

    if (loadCompletely) {
      loadType = LoadType.COMPLETE;
    } else {
      loadType = LoadType.METADATA;
    }

    LinkedHashMap<TaskID, Task> resultMap;

    if (taskIDs == null) {
      throw new NullPointerException();
    } else if (taskIDs.size() > maxTaskRequestSize) {
      throw new TooManyEntitiesRequestedException();
    } else if (taskIDs.size() == 0) {
      return ResultSetFactory.getResultSetInstance(
          null, systemSession, false, loadType, new LinkedHashMap<TaskID, Task>(), null);
    } else if (taskIDs.size() == 1) {
      resultMap = new LinkedHashMap<TaskID, Task>();
      resultMap.put(taskIDs.get(0), getTask(taskIDs.get(0), loadCompletely, forceAPICall));

      return ResultSetFactory.getResultSetInstance(
          null, systemSession, false, loadType, resultMap, null);
    }

    if (cacheActivated) {
      if (!forceAPICall) {
        resultMap = new LinkedHashMap<TaskID, Task>();
        LinkedHashMap<TaskID, Task> tempMap = new LinkedHashMap<TaskID, Task>();
        List<TaskID> missingTasks = new LinkedList<TaskID>();

        Task task;
        Element element;

        for (TaskID taskID : taskIDs) {
          element = cache.get(taskID);

          if (element != null) {
            task = (Task) element.getObjectValue();

            if (loadCompletely && !((Cachable) task).isCompletelyLoaded()) {
              missingTasks.add(taskID);
            } else {
              tempMap.put(taskID, task);
            }
          } else {
            missingTasks.add(taskID);
          }
        }

        if (missingTasks.size() > 0) {
          tempMap.putAll(getDataFactory().getTasksByIDs(missingTasks, loadCompletely));

          for (TaskID taskID : taskIDs) {
            resultMap.put(taskID, tempMap.get(taskID));
          }
        } else {
          return ResultSetFactory.getResultSetInstance(
              null, systemSession, false, loadType, tempMap, null);
        }
      } else {
        resultMap = getDataFactory().getTasksByIDs(taskIDs, loadCompletely);
      }

      if (resultMap.size() > 0) {
        for (Task task : resultMap.values()) {
          cache.put(new Element(task.getID(), task));
        }
      }
    } else {
      resultMap = getDataFactory().getTasksByIDs(taskIDs, loadCompletely);
    }

    return ResultSetFactory.getResultSetInstance(
        null, systemSession, false, loadType, resultMap, null);
  }