private function getFieldGroups(HeraldAdapter $adapter, array $field_map)
 {
     $group_map = array();
     foreach ($field_map as $field_key => $field_name) {
         $group_key = $adapter->getFieldGroupKey($field_key);
         $group_map[$group_key][$field_key] = $field_name;
     }
     return $this->getGroups($group_map, HeraldFieldGroup::getAllFieldGroups());
 }
 private function setupEditorBehavior(HeraldRule $rule, array $handles, HeraldAdapter $adapter)
 {
     $serial_conditions = array(array('default', 'default', ''));
     if ($rule->getConditions()) {
         $serial_conditions = array();
         foreach ($rule->getConditions() as $condition) {
             $value = $adapter->getEditorValueForCondition($this->getViewer(), $condition, $handles);
             $serial_conditions[] = array($condition->getFieldName(), $condition->getFieldCondition(), $value);
         }
     }
     $serial_actions = array(array('default', ''));
     if ($rule->getActions()) {
         $serial_actions = array();
         foreach ($rule->getActions() as $action) {
             switch ($action->getAction()) {
                 case HeraldAdapter::ACTION_FLAG:
                 case HeraldAdapter::ACTION_BLOCK:
                     $current_value = $action->getTarget();
                     break;
                 default:
                     if (is_array($action->getTarget())) {
                         $target_map = array();
                         foreach ((array) $action->getTarget() as $fbid) {
                             $target_map[$fbid] = $handles[$fbid]->getName();
                         }
                         $current_value = $target_map;
                     } else {
                         $current_value = $action->getTarget();
                     }
                     break;
             }
             $serial_actions[] = array($action->getAction(), $current_value);
         }
     }
     $all_rules = $this->loadRulesThisRuleMayDependUpon($rule);
     $all_rules = mpull($all_rules, 'getName', 'getPHID');
     asort($all_rules);
     $all_fields = $adapter->getFieldNameMap();
     $all_conditions = $adapter->getConditionNameMap();
     $all_actions = $adapter->getActionNameMap($rule->getRuleType());
     $fields = $adapter->getFields();
     $field_map = array_select_keys($all_fields, $fields);
     // Populate any fields which exist in the rule but which we don't know the
     // names of, so that saving a rule without touching anything doesn't change
     // it.
     foreach ($rule->getConditions() as $condition) {
         $field_name = $condition->getFieldName();
         if (empty($field_map[$field_name])) {
             $field_map[$field_name] = pht('<Unknown Field "%s">', $field_name);
         }
     }
     $actions = $adapter->getActions($rule->getRuleType());
     $action_map = array_select_keys($all_actions, $actions);
     // Populate any actions which exist in the rule but which we don't know the
     // names of, so that saving a rule without touching anything doesn't change
     // it.
     foreach ($rule->getActions() as $action) {
         $action_name = $action->getAction();
         if (empty($action_map[$action_name])) {
             $action_map[$action_name] = pht('<Unknown Action "%s">', $action_name);
         }
     }
     $group_map = array();
     foreach ($field_map as $field_key => $field_name) {
         $group_key = $adapter->getFieldGroupKey($field_key);
         $group_map[$group_key][$field_key] = $field_name;
     }
     $field_groups = HeraldFieldGroup::getAllFieldGroups();
     $groups = array();
     foreach ($group_map as $group_key => $options) {
         asort($options);
         $field_group = idx($field_groups, $group_key);
         if ($field_group) {
             $group_label = $field_group->getGroupLabel();
             $group_order = $field_group->getSortKey();
         } else {
             $group_label = nonempty($group_key, pht('Other'));
             $group_order = 'Z';
         }
         $groups[] = array('label' => $group_label, 'options' => $options, 'order' => $group_order);
     }
     $groups = array_values(isort($groups, 'order'));
     $config_info = array();
     $config_info['fields'] = $groups;
     $config_info['conditions'] = $all_conditions;
     $config_info['actions'] = $action_map;
     $config_info['valueMap'] = array();
     foreach ($field_map as $field => $name) {
         try {
             $field_conditions = $adapter->getConditionsForField($field);
         } catch (Exception $ex) {
             $field_conditions = array(HeraldAdapter::CONDITION_UNCONDITIONALLY);
         }
         $config_info['conditionMap'][$field] = $field_conditions;
     }
     foreach ($field_map as $field => $fname) {
         foreach ($config_info['conditionMap'][$field] as $condition) {
             $value_key = $adapter->getValueTypeForFieldAndCondition($field, $condition);
             if ($value_key instanceof HeraldFieldValue) {
                 $value_key->setViewer($this->getViewer());
                 $spec = $value_key->getControlSpecificationDictionary();
                 $value_key = $value_key->getFieldValueKey();
                 $config_info['valueMap'][$value_key] = $spec;
             }
             $config_info['values'][$field][$condition] = $value_key;
         }
     }
     $config_info['rule_type'] = $rule->getRuleType();
     foreach ($config_info['actions'] as $action => $name) {
         try {
             $value_key = $adapter->getValueTypeForAction($action, $rule->getRuleType());
         } catch (Exception $ex) {
             $value_key = new HeraldEmptyFieldValue();
         }
         if ($value_key instanceof HeraldFieldValue) {
             $value_key->setViewer($this->getViewer());
             $spec = $value_key->getControlSpecificationDictionary();
             $value_key = $value_key->getFieldValueKey();
             $config_info['valueMap'][$value_key] = $spec;
         }
         $config_info['targets'][$action] = $value_key;
     }
     Javelin::initBehavior('herald-rule-editor', array('root' => 'herald-rule-edit-form', 'conditions' => (object) $serial_conditions, 'actions' => (object) $serial_actions, 'template' => $this->buildTokenizerTemplates() + array('rules' => $all_rules), 'info' => $config_info));
 }