Collection unprovidedTasks;
  protected void execute() {    //clear our new refill list    newRefills.clear();    // need to call these at beginning of execute cycle    supplyTaskScheduler.initForExecuteCycle();    projectionTaskScheduler.initForExecuteCycle();    // if the OM changed and the window is further out then before    // then mark the flag true so we process previously ignored tasks    // and allocation results.  If it went down - don't undo work    if (!Level6OMSubscription.getChangedCollection().isEmpty()) {      long currentLevel6 = getEndOfLevelSix();      if (logger.isInfoEnabled()) {        logger.info("Inv Mgr got changed OM ... new end of level 6 window is: " +                    currentLevel6 + " in agent: " + getAgentIdentifier() +                    " supply type: " + getSupplyType());      }      if (currentLevel6 > prevLevel6) {        OMChange = true;      }      //reset the previous level 6 to the current      prevLevel6 = currentLevel6;    }    if (inventoryPolicy == null) {      updateInventoryPolicy(inventoryPolicySubscription);    }    updateInventoryPolicy(inventoryPolicySubscription.getChangedCollection());    processDetReq(detReqSubscription.getAddedCollection());    cycleStamp = (new Date()).getTime();    if (inventoryPolicy == null) {      if (logger.isInfoEnabled()) {        logger.info("\n InventoryPlugin " + supplyType +                    " not ready to process tasks yet." +                    " my inv policy is: " + inventoryPolicy + " in " + getMyOrganization());      }      return;    }    if (myOrganization == null) {      myOrganization = getMyOrganization(selfOrganizations.elements());    }    if (myOrganization == null) {      if (logger.isInfoEnabled()) {        logger.info("\n InventoryPlugin " + supplyType +                    " not ready to process tasks yet." +                    " my org is: " + myOrganization);      }      return;    }    if (!initialized) {      myOrgName = myOrganization.getItemIdentificationPG().getItemIdentification();//       inventoryFile = getInventoryFile(supplyType);//       getInventoryData();      initialized = true;    }    if ((logOPlan == null) || logisticsOPlanSubscription.hasChanged()) {      Collection c = logisticsOPlanSubscription.getCollection();      for (Iterator i = c.iterator(); i.hasNext();) {        logOPlan = (LogisticsOPlan) i.next();        //        System.out.println("logOplan in :" + getAgentIdentifier().toString() +        //                   " is: " + logOPlan);        resetLogOPlanForInventories();        break;      }    }    // if our top level MI task got removed, clean out the references .    if (! aggMILSubscription.getRemovedCollection().isEmpty()) {      detReqHandler.resetAggMITask();      if (logger.isDebugEnabled()) {        logger.debug("Agent: " + getAgentIdentifier().toString() + " Top Level MI removed["+supplyType+"]");      }    }    //Extra debugging to check for same object on add and remove    if (logger.isDebugEnabled()) {      Collection addedRefills = refillSubscription.getAddedCollection();      Collection removedRefills = refillSubscription.getRemovedCollection();      Iterator addRefIt = addedRefills.iterator();      while (addRefIt.hasNext()) {        Task addedRefillTask = (Task) addRefIt.next();        if (removedRefills.contains(addedRefillTask)) {          logger.debug("Agent " + getAgentIdentifier().toString() + "InvPlugin[" +                             getSupplyType() + "] Got a Refill Task added and removed in my subscription " +                             addedRefillTask.getVerb() + " "+ addedRefillTask.getUID());        }      }      Collection addedWithdraws = withdrawTaskSubscription.getAddedCollection();      Collection removedWithdraws = withdrawTaskSubscription.getRemovedCollection();      Iterator addWD = addedWithdraws.iterator();      while (addWD.hasNext()) {        Task addedWDTask = (Task) addWD.next();        if (removedWithdraws.contains(addedWDTask)) {          logger.debug("Agent " + getAgentIdentifier().toString() + "InvPlugin[" +                       getSupplyType() + "] Got a Withdraw Task added and removed in my subscription " +                       addedWDTask.getVerb() + " "+ addedWDTask.getUID());        }      }    }    if ((detReqHandler.getDetermineRequirementsTask(aggMILSubscription) != null) &&        (logOPlan != null)) {      if (rehydrateInvs) {        addRehydratedInventories(blackboard.query(new InventoryPredicate(supplyType)));        if (logger.isDebugEnabled()) {          logger.debug("Agent: " + getAgentIdentifier().toString() + "Rehydrating Inventories for InvPlugin["+supplyType+"]" );        }        rehydrateInvs = false;      }      //Process all the removes at once - note that the supplyExpander.handleRemovedProjections sets the      //touchedRemovedProjections boolean for use later.      boolean touchedRemovedProjections = processRemoves();      Collection addedSupply = supplyTaskScheduler.getAddedCollection();      if (! commStatusSub.isEmpty()) {        supplyExpander.determineCommStatus(commStatusSub, addedSupply);      }      TimeSpan timeSpan = null;      if (turnOnTaskSched) {        timeSpan = supplyTaskScheduler.getCurrentTimeSpan();      } else {        timeSpan = new ScheduleElementImpl(getLogOPlanStartTime(),                                           getLogOPlanEndTime());      }      if (!addedSupply.isEmpty()) {        expandIncomingRequisitions(getTasksWithoutPEs(addedSupply)); // fix for bug #1695      }      Collection changedSupply = supplyTaskScheduler.getChangedCollection();      if (!changedSupply.isEmpty()) {        supplyExpander.updateChangedRequisitions(changedSupply);      }      supplyTaskScheduler.finishedExecuteCycle();      Collection addedProjections = projectionTaskScheduler.getAddedCollection();      TimeSpan timeSpan2 = null;      if (turnOnTaskSched) {        timeSpan2 = projectionTaskScheduler.getCurrentTimeSpan();      } else {        timeSpan2 = new ScheduleElementImpl(getLogOPlanStartTime(),                                            getLogOPlanEndTime());      }      if (!addedProjections.isEmpty()) {        // getTasksWithoutPEs is fix for bug #1695        touchedProjections = expandIncomingProjections(getTasksWithoutPEs(addedProjections));      }      Collection changedProjections = projectionTaskScheduler.getChangedCollection();      if (!changedProjections.isEmpty()) {        supplyExpander.updateChangedProjections(changedProjections);        touchedChangedProjections = true;// System.out.println("Touched changed projections in " + getAgentIdentifier() +//                                " type is" + getSupplyType());      }      projectionTaskScheduler.finishedExecuteCycle();      // Rescind tasks that no longer have a provider      // and      // Allocate any refill tasks from previous executions that were not allocated to providers      // but only if we are not about to rip out previous work we have done      if (didOrgRelationshipsChange()) {        if (logger.isDebugEnabled()) {          logger.debug("ORG RELATIONSHIPS CHANGED SDSD myorg: " + myOrganization + " supply type:" +                      supplyType + " role: " + getRole(supplyType) + "\n");        }        // Handle unprovided tasks        HashMap providerStartDates = new HashMap();	HashMap providerEndDates = new HashMap();        HashMap providerAvailSchedule = relationshipScheduleMap();        Collection unprovidedTasks;        getOverlappingTasks(refillAllocationSubscription, Constants.Verb.Supply,                                              providerAvailSchedule);        getOverlappingTasks(refillAllocationSubscription, Constants.Verb.ProjectSupply,                                              providerAvailSchedule);        // Handle unallocated tasks        Collection unalloc = null;        if (addedSupply.isEmpty() && changedSupply.isEmpty()) {          unalloc = getTaskUtils().getUnallocatedTasks(refillSubscription,                                                       Constants.Verb.Supply);          if (!unalloc.isEmpty()){            if (logger.isWarnEnabled())              logger.warn("TRYING TO ALLOCATE SUPPLY REFILL TASKS...");            externalAllocator.allocateRefillTasks(unalloc);          }        }        if (addedProjections.isEmpty() && changedProjections.isEmpty()) {          unalloc = getTaskUtils().getUnallocatedTasks(refillSubscription,                                                       Constants.Verb.ProjectSupply);          if (!unalloc.isEmpty()) {            if (logger.isWarnEnabled())              logger.warn("TRYING TO ALLOCATE PROJECTION REFILL TASKS...");            externalAllocator.allocateRefillTasks(unalloc);          }        }      }      // call the Refill Generators if we have new demand      if (!getTouchedInventories().isEmpty()) {        // update the inventory customer hash tables when we have new demand        rebuildPGCustomerHash();        //check to see if we have new projections        if (touchedProjections || touchedRemovedProjections || touchedChangedProjections) {          if (logger.isDebugEnabled()) {            logger.debug("Agent: " + getAgentIdentifier().toString() + "InvPlugin" + supplyType+"]" +                         "something touched: tprojections: " + touchedProjections +                         " tRemovedProj" + touchedRemovedProjections + " tChangedProj: " + touchedChangedProjections);          }          //check to see if the OM changed.  If it did process all inventories          //since we probably ignored some demand tasks before the change          if (OMChange) {            refillProjGenerator.calculateRefillProjections(getInventories(),                                                           criticalLevel,                                                           getEndOfLevelSix(),                                                           getEndOfLevelTwo(),                                                           refillComparator);          } else {            refillProjGenerator.calculateRefillProjections(getTouchedInventories(),                                                           criticalLevel,                                                           getEndOfLevelSix(),                                                           getEndOfLevelTwo(),                                                           refillComparator);          }        }        refillGenerator.calculateRefills(getTouchedInventories(), refillComparator);        externalAllocator.allocateRefillTasks(newRefills);        //we might get new demand where we don't need to generate any new refills        // such as small demand from the stimulator servlet - when this happens we        // need to kick the allocation assessor to allocate the withdraws        allocationAssessor.reconcileInventoryLevels(getActionableInventories());      }      // if we are in downward flow ONLY check the withdraw expansion results      // note we may go through the whole list multiple times - but this seems like the      // simplest fix to get rid of places where we miss change reports because the AA      // compares previous results to new ones and leaves the old ones if they are equal.      // note that the updates only occur if the reported result is not equal to the estimated      // so we will not be waking up the whole chain by checking these more than once.      HashSet backwardFlowTouched = null;      if (getTouchedInventories().isEmpty()) {        supplyExpander.updateAllocationResult(expansionSubscription);        backwardFlowTouched =            externalAllocator.updateAllocationResult(refillAllocationSubscription);        // if the OM changed, process ALL inventories for demand projections and        // allocation results since some results were likely ignored before        // the OM level 6 window changed.        if (OMChange) {          refillProjGenerator.calculateRefillProjections(getInventories(),                                                         criticalLevel,                                                         getEndOfLevelSix(),                                                         getEndOfLevelTwo(),                                                         refillComparator);          externalAllocator.allocateRefillTasks(newRefills);          allocationAssessor.reconcileInventoryLevels(getInventories());        } else {          allocationAssessor.reconcileInventoryLevels(backwardFlowTouched);        }      } else {        // if the we are not in backwards flow but the OM changed        // process ARs anyway because we may not get woken up again to        // process them if they have all come in already        if (OMChange) {          allocationAssessor.reconcileInventoryLevels(getInventories());        }      }      // update the Maintain Inventory Expansion results      PluginHelper.updateAllocationResult(MIExpansionSubscription);      PluginHelper.updateAllocationResult(MITopExpansionSubscription);      PluginHelper.updateAllocationResult(DetReqInvExpansionSubscription);      if (backwardFlowTouched != null) {        takeInventorySnapshot(backwardFlowTouched);      }      takeInventorySnapshot(getTouchedInventories());      takeInventorySnapshot(getInventoriesWithDeletions());      // touchedInventories and inventoriesWithDeletions should not be cleared until      // the end of transaction      touchedInventories.clear();      inventoriesWithDeletions.clear();      //backwardFlowInventories.clear(); //###      touchedProjections = false;      touchedChangedProjections = false;      OMChange = false;      //testBG();    } else {      //process any removes if the DetReq task returns null - this should catch the case where it gets rescinded.      // to reduce the amount of times this gets run at start up - only do it if we don't have      // a log oplan also.  Note that if the oplan gets rescinded this might need to change.      if (logOPlan != null) {        processRemoves();        takeInventorySnapshot(getTouchedInventories());        touchedInventories.clear();      }    }    supplyExpander.checkCommStatusAlarms();  }