public double handleUnplanned(Task unplanned) {
   if (_gp.getLoggingService().isDebugEnabled())
     _gp.getLoggingService().debug("Filler.handleUnplanned - replanning " + unplanned.getUID());
   List agglist = new ArrayList();
   // packer.subtractTaskFromReceiver (unplanned);
   agglist.add(unplanned);
   double loadedQuantity = createMPTask(agglist);
   return loadedQuantity;
 }
  protected String getReceiverID(Task task) {
    String receiverID;

    Object receiver = task.getPrepositionalPhrase(Constants.Preposition.FOR);

    if (receiver != null) receiver = ((PrepositionalPhrase) receiver).getIndirectObject();

    // Add field with recipient
    if (receiver == null) {
      receiverID = UNKNOWN;
      _gp.getLoggingService()
          .error("Filler.addContentsInfo - Task " + task.getUID() + " had no FOR prep.");
    } else if (receiver instanceof String) {
      receiverID = (String) receiver;
    } else if (!(receiver instanceof Asset)) {
      receiverID = UNKNOWN;
    } else {
      ItemIdentificationPG itemIdentificationPG = ((Asset) receiver).getItemIdentificationPG();
      if ((itemIdentificationPG == null)
          || (itemIdentificationPG.getItemIdentification() == null)
          || (itemIdentificationPG.getItemIdentification().equals(""))) {
        receiverID = UNKNOWN;
      } else {
        receiverID = itemIdentificationPG.getItemIdentification();
      }
    }
    return receiverID;
  }
  /** 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;
  }
  protected void addContentsInfo(GLMAsset container, List agglist) {
    ArrayList typeIDs = new ArrayList();
    ArrayList nomenclatures = new ArrayList();
    ArrayList weights = new ArrayList();
    ArrayList receivers = new ArrayList();

    for (Iterator iterator = agglist.iterator(); iterator.hasNext(); ) {
      Task task = (Task) iterator.next();
      TypeIdentificationPG typeIdentificationPG = task.getDirectObject().getTypeIdentificationPG();
      String typeID;
      String nomenclature;
      if (typeIdentificationPG != null) {
        typeID = typeIdentificationPG.getTypeIdentification();
        if ((typeID == null) || (typeID.equals(""))) {
          typeID = UNKNOWN;
        }

        nomenclature = typeIdentificationPG.getNomenclature();
        if ((nomenclature == null) || (nomenclature.equals(""))) {
          nomenclature = UNKNOWN;
        }
      } else {
        typeID = UNKNOWN;
        nomenclature = UNKNOWN;
      }
      typeIDs.add(typeID);
      nomenclatures.add(nomenclature);

      double quantity = task.getPreferredValue(AspectType.QUANTITY);
      Mass mass = Mass.newMass(quantity, Mass.SHORT_TONS);
      weights.add(mass);

      String receiverID;
      if (FIND_FOR_UNIT_PREP_ON_TASK) {
        receiverID = getReceiverID(task);
      } else {
        receiverID = _gp.getGPMessageAddress().getAddress();
      }

      _gp.getLoggingService()
          .info(
              "Adding - "
                  + task.getUID()
                  + " for "
                  + receiverID
                  + " - "
                  + typeID
                  + " - "
                  + quantity);
      packer.addToReceiver(receiverID, typeID, quantity);

      receivers.add(receiverID);
    }

    // Contents
    NewContentsPG contentsPG = PropertyGroupFactory.newContentsPG();
    contentsPG.setNomenclatures(nomenclatures);
    contentsPG.setTypeIdentifications(typeIDs);
    contentsPG.setWeights(weights);
    contentsPG.setReceivers(receivers);
    container.setContentsPG(contentsPG);
  }