/**
  * Using the criteria in {@code parentIdMap}, recursively adds all children under the partition ID
  * of {@code parentNode} to {@code parentNode}.
  *
  * @param parentNode required
  * @param parentIdMap the multimap from parent partition ID to list of child criteria
  */
 private static void addChildNodes(
     ProductPartitionNode parentNode, ListMultimap<Long, AdGroupCriterion> parentIdMap) {
   if (parentIdMap.containsKey(parentNode.getProductPartitionId())) {
     parentNode = parentNode.asSubdivision();
   }
   for (AdGroupCriterion adGroupCriterion : parentIdMap.get(parentNode.getProductPartitionId())) {
     ProductPartition partition = (ProductPartition) adGroupCriterion.getCriterion();
     ProductPartitionNode childNode = parentNode.addChild(partition.getCaseValue());
     childNode = childNode.setProductPartitionId(partition.getId());
     if (ProductPartitionType.SUBDIVISION.equals(partition.getPartitionType())) {
       childNode = childNode.asSubdivision();
     } else {
       if (adGroupCriterion instanceof BiddableAdGroupCriterion) {
         childNode = childNode.asBiddableUnit();
         Money cpcBidAmount = getBid((BiddableAdGroupCriterion) adGroupCriterion);
         if (cpcBidAmount != null) {
           childNode = childNode.setBid(cpcBidAmount.getMicroAmount());
         }
       } else {
         childNode = childNode.asExcludedUnit();
       }
     }
     addChildNodes(childNode, parentIdMap);
   }
 }