/**
  * Returns the enterprise objects fetched with decoded <code>formValues</code> from <code>
  * entityName</code>.
  *
  * @param ec the editing context to fetch the objects from
  * @param entityName the entity to fetch the objects from
  * @param formValues dictionary where the values are an encoded representation of the primary key
  *     values in either cleartext or encrypted format.
  * @return the enterprise objects
  */
 public static NSArray enterpriseObjectsForEntityNamedFromFormValues(
     EOEditingContext ec, String entityName, NSDictionary formValues) {
   NSArray formValueObjects = decodeEnterpriseObjectsFromFormValues(ec, formValues);
   NSDictionary groups = ERXArrayUtilities.arrayGroupedByKeyPath(formValueObjects, "entityName");
   EOEntity entity = ERXEOAccessUtilities.entityNamed(ec, entityName);
   NSMutableArray entityGroup = new NSMutableArray();
   if (entity != null && entity.isAbstractEntity()) {
     for (Enumeration e = ERXUtilities.allSubEntitiesForEntity(entity, false).objectEnumerator();
         e.hasMoreElements(); ) {
       EOEntity subEntity = (EOEntity) e.nextElement();
       NSArray aGroup = (NSArray) groups.objectForKey(subEntity.name());
       if (aGroup != null) entityGroup.addObjectsFromArray(aGroup);
     }
   } else {
     entityGroup.addObjectsFromArray((NSArray) groups.objectForKey(entityName));
   }
   return entityGroup != null ? entityGroup : NSArray.EmptyArray;
 }
  /**
   * Decodes all of the objects for a given set of form values in the given editing context. The
   * object encoding is very simple, just a generic entity name primary key pair where the key is
   * potentially encrypted using blowfish. The specific encoding is specified in the method: <code>
   * encodeEnterpriseObjectsPrimaryKeyForUrl
   * </code>.
   *
   * @param ec editingcontext to fetch the objects from
   * @param values form value dictionary where the values are an encoded representation of the
   *     primary key values in either cleartext or encrypted format.
   * @return array of enterprise objects corresponding to the passed in form values.
   */
  public static NSArray decodeEnterpriseObjectsFromFormValues(
      EOEditingContext ec, NSDictionary values) {
    if (ec == null)
      throw new IllegalArgumentException(
          "Attempting to decode enterprise objects with null editing context.");
    if (values == null)
      throw new IllegalArgumentException(
          "Attempting to decode enterprise objects with null form values.");
    if (log.isDebugEnabled()) log.debug("values = " + values);
    NSMutableArray result = new NSMutableArray();

    String separator =
        values.objectForKey("sep") != null
            ? (String) values.objectForKey("sep")
            : entityNameSeparator();

    for (Enumeration e = values.keyEnumerator(); e.hasMoreElements(); ) {
      Object o = e.nextElement();
      String key = (String) o;
      if (key.indexOf(separator) != -1) {
        boolean isEncrypted = key.indexOf(separator + "E") != -1;
        String encodedEntityName = key.substring(0, key.indexOf(separator));
        String entityName = entityNameDecode(encodedEntityName);
        entityName = entityName == null ? encodedEntityName : entityName;
        EOEntity entity = ERXEOAccessUtilities.entityNamed(ec, entityName);
        if (entity != null) {
          NSDictionary pk =
              processPrimaryKeyValue((String) values.objectForKey(key), entity, isEncrypted);
          result.addObject(EOUtilities.objectWithPrimaryKey(ec, entity.name(), pk));
        } else {
          log.warn("Unable to find entity for name: " + entityName);
        }
      }
    }
    return result;
  }