// get all non-discontinued virtuals, see if all variant ProductAssocs are expired, if discontinue
EntityCondition condition = EntityCondition.makeCondition(UtilMisc.toList(
EntityCondition.makeCondition("isVirtual", EntityOperator.EQUALS, "Y"),
EntityCondition.makeCondition(EntityCondition.makeCondition("salesDiscontinuationDate", EntityOperator.EQUALS, null), EntityOperator.OR, EntityCondition.makeCondition("salesDiscontinuationDate", EntityOperator.GREATER_THAN_EQUAL_TO, nowTimestamp))
), EntityOperator.AND);
EntityListIterator eli = delegator.find("Product", condition, null, null, null, null);
GenericValue product = null;
int numSoFar = 0;
while ((product = eli.next()) != null) {
List<GenericValue> passocList = delegator.findByAnd("ProductAssoc", UtilMisc.toMap("productId", product.get("productId"), "productAssocTypeId", "PRODUCT_VARIANT"));
passocList = EntityUtil.filterByDate(passocList);