/** agglist is the list of parent tasks */
  protected double createMPTask(List agglist) {
    // now we do the aggregation
    NewMPTask mpt = _ac.newTask();

    HashSet set = new HashSet();
    Iterator taskIt = agglist.iterator();
    Task parentTask;
    while (taskIt.hasNext()) {
      parentTask = (Task) taskIt.next();
      if (parentTask.getContext() != null) {
        set.addAll((ContextOfOplanIds) parentTask.getContext());
      }
    }
    mpt.setContext(new ContextOfOplanIds(set));

    // Set ContentsPG on container
    addContentsInfo((GLMAsset) mpt.getDirectObject(), agglist);

    // BOZO
    mpt.setPreferences(
        new Vector(_pa.aggregatePreferences(agglist.iterator(), _gp.getGPFactory())).elements());
    double loadedQuantity = mpt.getPreferredValue(AspectType.QUANTITY);
    Plan plan = ((Task) agglist.get(0)).getPlan();

    _gp.createAggregation(agglist.iterator(), mpt, plan, _ard);

    if (mpt.getComposition().getParentTasks().size() != agglist.size())
      _gp.getLoggingService()
          .error(
              "Filler.createMPTask - received "
                  + agglist.size()
                  + " tasks to be agggregated, but only "
                  + mpt.getComposition().getParentTasks().size()
                  + " tasks as parents of "
                  + mpt.getUID());
    // System.out.println( " FILLER : what is the loadedQuantity " + loadedQuantity);
    return loadedQuantity;
  }
  /** This is the driving function in the whole packing process. */
  public double execute() {
    // boolean finished = false;
    double tonsPacked = 0;

    if (_gp.getLoggingService().isInfoEnabled())
      _gp.getLoggingService().info("Filler.execute - entered.");
    int numTasks = 0;
    int numParents = 0;

    // while there's still ammo to put in milvans
    while (_sz.moreTasksInQueue()) {
      // initialize the aggregation
      ArrayList agglist = new ArrayList();
      double amount = 0.0;
      double earliest = 0.0;
      double latest = java.lang.Double.POSITIVE_INFINITY;

      // while our milvan is not yet full and there is more ammo left to pack
      while (_ac.getQuantity() - amount > MIN_DELTA && _sz.moreTasksInQueue()) {
        // ask the sizer for what an amount that would fill the milvan
        Task t = _sz.provide(_ac.getQuantity() - amount, earliest, latest);
        if (t == null) { // the next task is outside the earliest->latest window
          //	    finished = true;
          break;
        }
        numTasks++;

        // if we reach here, t is a Task that provides
        // some amount towards our overall amount
        double provided = t.getPreferredValue(AspectType.QUANTITY);

        if (_gp.getLoggingService().isInfoEnabled()) {
          _gp.getLoggingService()
              .info(
                  "Filler.execute - adding "
                      + provided
                      + " to agg list vs "
                      + (_ac.getQuantity() - amount)
                      + " amount "
                      + amount);
        }

        Preference endDatePref = t.getPreference(AspectType.END_TIME);
        ScoringFunction sf = endDatePref.getScoringFunction();

        AspectScorePoint aspStart = sf.getDefinedRange().getRangeStartPoint();
        AspectScorePoint aspBest = sf.getBest();
        AspectScorePoint aspEnd = sf.getDefinedRange().getRangeEndPoint();

        Date taskEarlyDate = new Date((long) aspStart.getValue());
        Date taskBestDateMinusFiveDays =
            new Date((long) aspBest.getValue() - MAX_GROUP_DAYS * ONE_DAY_MILLIS);

        // no earlier than earliest arrival, but no more than 5 days before best
        if (taskBestDateMinusFiveDays.getTime() < taskEarlyDate.getTime())
          taskBestDateMinusFiveDays = taskEarlyDate;
        if (taskBestDateMinusFiveDays.getTime() > earliest) {
          earliest = taskBestDateMinusFiveDays.getTime();
        }

        // restrict the window of time within which we'll aggregate tasks together
        // to be
        //
        //   earliest arrival->best date + one day
        //
        // instead of
        //
        //   earliest arrival->latest arrival
        //
        // because that can have problems when we replan
        // tasks without plan elements (happens when all aggregations of an mptask get
        // removed when any parent is removed). Resulting task has too narrow a time
        // window, since the replanned transport task will have an arrival window of
        // now->best date, and now could potentially be too close to the best date.

        Date taskLateDate = new Date((long) aspEnd.getValue());
        Date taskBestDatePlusOneDay = new Date((long) aspBest.getValue() + ONE_DAY_MILLIS);

        // no later than late date, but no more than one day after best
        if (taskBestDatePlusOneDay.getTime() > taskLateDate.getTime())
          taskBestDatePlusOneDay = taskLateDate;
        if (taskBestDatePlusOneDay.getTime() < latest) {
          latest = taskBestDatePlusOneDay.getTime();
        }

        amount += provided;
        agglist.add(t);
      }

      if (!agglist.isEmpty()) {
        double loadedQuantity = createMPTask(agglist);
        numParents += agglist.size();
        TRANSPORT_TONS += loadedQuantity;
        tonsPacked += loadedQuantity;
      }

      if (_gp.getLoggingService().isInfoEnabled()) {
        _gp.getLoggingService()
            .info("Filler.execute - aggregating together " + agglist.size() + " parents:");
        for (Iterator iter = agglist.iterator(); iter.hasNext(); ) {
          Task task = (Task) iter.next();
          _gp.getLoggingService()
              .info(
                  "Filler.execute - "
                      + task.getUID()
                      + " end date "
                      + new Date((long) task.getPreferredValue(AspectType.END_TIME)));
        }
      }
    }

    if (numTasks != numParents)
      _gp.getLoggingService()
          .error(
              "Filler.execute - num tasks created "
                  + numTasks
                  + " != parents of MPTask "
                  + numParents);

    if (numParents != _sz.sizedMade)
      _gp.getLoggingService()
          .error(
              "Filler.execute - sizer num tasks made "
                  + _sz.sizedMade
                  + " != total parents of MPTask "
                  + numParents);

    if (_gp.getLoggingService().isInfoEnabled())
      _gp.getLoggingService()
          .info("Packer  - current aggregated requested transport: " + TRANSPORT_TONS + " tons.");

    if (_gp.getLoggingService().isInfoEnabled())
      _gp.getLoggingService().info("Filler.execute - exited.");

    return tonsPacked;
  }