public function appendFieldsToPropertyList(PhabricatorCustomFieldInterface $object, PhabricatorUser $viewer, PHUIPropertyListView $view)
 {
     $this->readFieldsFromStorage($object);
     $fields = $this->fields;
     foreach ($fields as $field) {
         $field->setViewer($viewer);
     }
     // Move all the blocks to the end, regardless of their configuration order,
     // because it always looks silly to render a block in the middle of a list
     // of properties.
     $head = array();
     $tail = array();
     foreach ($fields as $key => $field) {
         $style = $field->getStyleForPropertyView();
         switch ($style) {
             case 'property':
             case 'header':
                 $head[$key] = $field;
                 break;
             case 'block':
                 $tail[$key] = $field;
                 break;
             default:
                 throw new Exception(pht("Unknown field property view style '%s'; valid styles are " . "'%s' and '%s'.", $style, 'block', 'property'));
         }
     }
     $fields = $head + $tail;
     $add_header = null;
     $phids = array();
     foreach ($fields as $key => $field) {
         $phids[$key] = $field->getRequiredHandlePHIDsForPropertyView();
     }
     $all_phids = array_mergev($phids);
     if ($all_phids) {
         $handles = id(new PhabricatorHandleQuery())->setViewer($viewer)->withPHIDs($all_phids)->execute();
     } else {
         $handles = array();
     }
     foreach ($fields as $key => $field) {
         $field_handles = array_select_keys($handles, $phids[$key]);
         $label = $field->renderPropertyViewLabel();
         $value = $field->renderPropertyViewValue($field_handles);
         if ($value !== null) {
             switch ($field->getStyleForPropertyView()) {
                 case 'header':
                     // We want to hide headers if the fields the're assciated with
                     // don't actually produce any visible properties. For example, in a
                     // list like this:
                     //
                     //   Header A
                     //   Prop A: Value A
                     //   Header B
                     //   Prop B: Value B
                     //
                     // ...if the "Prop A" field returns `null` when rendering its
                     // property value and we rendered naively, we'd get this:
                     //
                     //   Header A
                     //   Header B
                     //   Prop B: Value B
                     //
                     // This is silly. Instead, we hide "Header A".
                     $add_header = $value;
                     break;
                 case 'property':
                     if ($add_header !== null) {
                         // Add the most recently seen header.
                         $view->addSectionHeader($add_header);
                         $add_header = null;
                     }
                     $view->addProperty($label, $value);
                     break;
                 case 'block':
                     $icon = $field->getIconForPropertyView();
                     $view->invokeWillRenderEvent();
                     if ($label !== null) {
                         $view->addSectionHeader($label, $icon);
                     }
                     $view->addTextContent($value);
                     break;
             }
         }
     }
 }