diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index b417fe9407..c82e0e5555 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,6252 +1,6266 @@
 <?php
 
 /**
  * This file is automatically generated. Use 'arc liberate' to rebuild it.
  *
  * @generated
  * @phutil-library-version 2
  */
 phutil_register_library_map(array(
   '__library_version__' => 2,
   'class' => array(
     'AlmanacAddress' => 'applications/almanac/util/AlmanacAddress.php',
     'AlmanacBinding' => 'applications/almanac/storage/AlmanacBinding.php',
     'AlmanacBindingEditController' => 'applications/almanac/controller/AlmanacBindingEditController.php',
     'AlmanacBindingEditor' => 'applications/almanac/editor/AlmanacBindingEditor.php',
     'AlmanacBindingPHIDType' => 'applications/almanac/phid/AlmanacBindingPHIDType.php',
     'AlmanacBindingQuery' => 'applications/almanac/query/AlmanacBindingQuery.php',
     'AlmanacBindingTableView' => 'applications/almanac/view/AlmanacBindingTableView.php',
     'AlmanacBindingTransaction' => 'applications/almanac/storage/AlmanacBindingTransaction.php',
     'AlmanacBindingTransactionQuery' => 'applications/almanac/query/AlmanacBindingTransactionQuery.php',
     'AlmanacBindingViewController' => 'applications/almanac/controller/AlmanacBindingViewController.php',
     'AlmanacConduitAPIMethod' => 'applications/almanac/conduit/AlmanacConduitAPIMethod.php',
     'AlmanacConsoleController' => 'applications/almanac/controller/AlmanacConsoleController.php',
     'AlmanacController' => 'applications/almanac/controller/AlmanacController.php',
     'AlmanacCoreCustomField' => 'applications/almanac/customfield/AlmanacCoreCustomField.php',
     'AlmanacCreateDevicesCapability' => 'applications/almanac/capability/AlmanacCreateDevicesCapability.php',
     'AlmanacCreateNetworksCapability' => 'applications/almanac/capability/AlmanacCreateNetworksCapability.php',
     'AlmanacCreateServicesCapability' => 'applications/almanac/capability/AlmanacCreateServicesCapability.php',
     'AlmanacCustomField' => 'applications/almanac/customfield/AlmanacCustomField.php',
     'AlmanacDAO' => 'applications/almanac/storage/AlmanacDAO.php',
     'AlmanacDevice' => 'applications/almanac/storage/AlmanacDevice.php',
     'AlmanacDeviceController' => 'applications/almanac/controller/AlmanacDeviceController.php',
     'AlmanacDeviceEditController' => 'applications/almanac/controller/AlmanacDeviceEditController.php',
     'AlmanacDeviceEditor' => 'applications/almanac/editor/AlmanacDeviceEditor.php',
     'AlmanacDeviceListController' => 'applications/almanac/controller/AlmanacDeviceListController.php',
     'AlmanacDevicePHIDType' => 'applications/almanac/phid/AlmanacDevicePHIDType.php',
     'AlmanacDeviceQuery' => 'applications/almanac/query/AlmanacDeviceQuery.php',
     'AlmanacDeviceSearchEngine' => 'applications/almanac/query/AlmanacDeviceSearchEngine.php',
     'AlmanacDeviceTransaction' => 'applications/almanac/storage/AlmanacDeviceTransaction.php',
     'AlmanacDeviceTransactionQuery' => 'applications/almanac/query/AlmanacDeviceTransactionQuery.php',
     'AlmanacDeviceViewController' => 'applications/almanac/controller/AlmanacDeviceViewController.php',
     'AlmanacInterface' => 'applications/almanac/storage/AlmanacInterface.php',
     'AlmanacInterfaceDatasource' => 'applications/almanac/typeahead/AlmanacInterfaceDatasource.php',
     'AlmanacInterfaceEditController' => 'applications/almanac/controller/AlmanacInterfaceEditController.php',
     'AlmanacInterfacePHIDType' => 'applications/almanac/phid/AlmanacInterfacePHIDType.php',
     'AlmanacInterfaceQuery' => 'applications/almanac/query/AlmanacInterfaceQuery.php',
     'AlmanacInterfaceTableView' => 'applications/almanac/view/AlmanacInterfaceTableView.php',
     'AlmanacManagementTrustKeyWorkflow' => 'applications/almanac/management/AlmanacManagementTrustKeyWorkflow.php',
     'AlmanacManagementUntrustKeyWorkflow' => 'applications/almanac/management/AlmanacManagementUntrustKeyWorkflow.php',
     'AlmanacManagementWorkflow' => 'applications/almanac/management/AlmanacManagementWorkflow.php',
     'AlmanacNames' => 'applications/almanac/util/AlmanacNames.php',
     'AlmanacNamesTestCase' => 'applications/almanac/util/__tests__/AlmanacNamesTestCase.php',
     'AlmanacNetwork' => 'applications/almanac/storage/AlmanacNetwork.php',
     'AlmanacNetworkController' => 'applications/almanac/controller/AlmanacNetworkController.php',
     'AlmanacNetworkEditController' => 'applications/almanac/controller/AlmanacNetworkEditController.php',
     'AlmanacNetworkEditor' => 'applications/almanac/editor/AlmanacNetworkEditor.php',
     'AlmanacNetworkListController' => 'applications/almanac/controller/AlmanacNetworkListController.php',
     'AlmanacNetworkPHIDType' => 'applications/almanac/phid/AlmanacNetworkPHIDType.php',
     'AlmanacNetworkQuery' => 'applications/almanac/query/AlmanacNetworkQuery.php',
     'AlmanacNetworkSearchEngine' => 'applications/almanac/query/AlmanacNetworkSearchEngine.php',
     'AlmanacNetworkTransaction' => 'applications/almanac/storage/AlmanacNetworkTransaction.php',
     'AlmanacNetworkTransactionQuery' => 'applications/almanac/query/AlmanacNetworkTransactionQuery.php',
     'AlmanacNetworkViewController' => 'applications/almanac/controller/AlmanacNetworkViewController.php',
     'AlmanacProperty' => 'applications/almanac/storage/AlmanacProperty.php',
     'AlmanacPropertyController' => 'applications/almanac/controller/AlmanacPropertyController.php',
     'AlmanacPropertyEditController' => 'applications/almanac/controller/AlmanacPropertyEditController.php',
     'AlmanacPropertyInterface' => 'applications/almanac/property/AlmanacPropertyInterface.php',
     'AlmanacPropertyQuery' => 'applications/almanac/query/AlmanacPropertyQuery.php',
     'AlmanacQuery' => 'applications/almanac/query/AlmanacQuery.php',
     'AlmanacQueryServicesConduitAPIMethod' => 'applications/almanac/conduit/AlmanacQueryServicesConduitAPIMethod.php',
     'AlmanacSchemaSpec' => 'applications/almanac/storage/AlmanacSchemaSpec.php',
     'AlmanacService' => 'applications/almanac/storage/AlmanacService.php',
     'AlmanacServiceController' => 'applications/almanac/controller/AlmanacServiceController.php',
     'AlmanacServiceEditController' => 'applications/almanac/controller/AlmanacServiceEditController.php',
     'AlmanacServiceEditor' => 'applications/almanac/editor/AlmanacServiceEditor.php',
     'AlmanacServiceListController' => 'applications/almanac/controller/AlmanacServiceListController.php',
     'AlmanacServicePHIDType' => 'applications/almanac/phid/AlmanacServicePHIDType.php',
     'AlmanacServiceQuery' => 'applications/almanac/query/AlmanacServiceQuery.php',
     'AlmanacServiceSearchEngine' => 'applications/almanac/query/AlmanacServiceSearchEngine.php',
     'AlmanacServiceTransaction' => 'applications/almanac/storage/AlmanacServiceTransaction.php',
     'AlmanacServiceTransactionQuery' => 'applications/almanac/query/AlmanacServiceTransactionQuery.php',
     'AlmanacServiceViewController' => 'applications/almanac/controller/AlmanacServiceViewController.php',
     'Aphront304Response' => 'aphront/response/Aphront304Response.php',
     'Aphront400Response' => 'aphront/response/Aphront400Response.php',
     'Aphront403Response' => 'aphront/response/Aphront403Response.php',
     'Aphront404Response' => 'aphront/response/Aphront404Response.php',
     'AphrontAbstractAttachedFileView' => 'view/control/AphrontAbstractAttachedFileView.php',
     'AphrontAjaxResponse' => 'aphront/response/AphrontAjaxResponse.php',
     'AphrontApplicationConfiguration' => 'aphront/configuration/AphrontApplicationConfiguration.php',
     'AphrontBarView' => 'view/widget/bars/AphrontBarView.php',
     'AphrontCSRFException' => 'aphront/exception/AphrontCSRFException.php',
     'AphrontCalendarEventView' => 'applications/calendar/view/AphrontCalendarEventView.php',
     'AphrontContextBarView' => 'view/layout/AphrontContextBarView.php',
     'AphrontController' => 'aphront/AphrontController.php',
     'AphrontCursorPagerView' => 'view/control/AphrontCursorPagerView.php',
     'AphrontDefaultApplicationConfiguration' => 'aphront/configuration/AphrontDefaultApplicationConfiguration.php',
     'AphrontDialogResponse' => 'aphront/response/AphrontDialogResponse.php',
     'AphrontDialogView' => 'view/AphrontDialogView.php',
     'AphrontErrorView' => 'view/form/AphrontErrorView.php',
     'AphrontException' => 'aphront/exception/AphrontException.php',
     'AphrontFileResponse' => 'aphront/response/AphrontFileResponse.php',
     'AphrontFormCheckboxControl' => 'view/form/control/AphrontFormCheckboxControl.php',
     'AphrontFormChooseButtonControl' => 'view/form/control/AphrontFormChooseButtonControl.php',
     'AphrontFormControl' => 'view/form/control/AphrontFormControl.php',
     'AphrontFormCropControl' => 'view/form/control/AphrontFormCropControl.php',
     'AphrontFormDateControl' => 'view/form/control/AphrontFormDateControl.php',
     'AphrontFormDividerControl' => 'view/form/control/AphrontFormDividerControl.php',
     'AphrontFormFileControl' => 'view/form/control/AphrontFormFileControl.php',
     'AphrontFormImageControl' => 'view/form/control/AphrontFormImageControl.php',
     'AphrontFormMarkupControl' => 'view/form/control/AphrontFormMarkupControl.php',
     'AphrontFormPasswordControl' => 'view/form/control/AphrontFormPasswordControl.php',
     'AphrontFormPolicyControl' => 'view/form/control/AphrontFormPolicyControl.php',
     'AphrontFormRadioButtonControl' => 'view/form/control/AphrontFormRadioButtonControl.php',
     'AphrontFormRecaptchaControl' => 'view/form/control/AphrontFormRecaptchaControl.php',
     'AphrontFormSectionControl' => 'view/form/control/AphrontFormSectionControl.php',
     'AphrontFormSelectControl' => 'view/form/control/AphrontFormSelectControl.php',
     'AphrontFormStaticControl' => 'view/form/control/AphrontFormStaticControl.php',
     'AphrontFormSubmitControl' => 'view/form/control/AphrontFormSubmitControl.php',
     'AphrontFormTextAreaControl' => 'view/form/control/AphrontFormTextAreaControl.php',
     'AphrontFormTextControl' => 'view/form/control/AphrontFormTextControl.php',
     'AphrontFormTextWithSubmitControl' => 'view/form/control/AphrontFormTextWithSubmitControl.php',
     'AphrontFormToggleButtonsControl' => 'view/form/control/AphrontFormToggleButtonsControl.php',
     'AphrontFormTokenizerControl' => 'view/form/control/AphrontFormTokenizerControl.php',
     'AphrontFormTypeaheadControl' => 'view/form/control/AphrontFormTypeaheadControl.php',
     'AphrontFormView' => 'view/form/AphrontFormView.php',
     'AphrontGlyphBarView' => 'view/widget/bars/AphrontGlyphBarView.php',
     'AphrontHTMLResponse' => 'aphront/response/AphrontHTMLResponse.php',
     'AphrontHTTPSink' => 'aphront/sink/AphrontHTTPSink.php',
     'AphrontHTTPSinkTestCase' => 'aphront/sink/__tests__/AphrontHTTPSinkTestCase.php',
     'AphrontIsolatedDatabaseConnectionTestCase' => 'infrastructure/storage/__tests__/AphrontIsolatedDatabaseConnectionTestCase.php',
     'AphrontIsolatedHTTPSink' => 'aphront/sink/AphrontIsolatedHTTPSink.php',
     'AphrontJSONResponse' => 'aphront/response/AphrontJSONResponse.php',
     'AphrontJavelinView' => 'view/AphrontJavelinView.php',
     'AphrontKeyboardShortcutsAvailableView' => 'view/widget/AphrontKeyboardShortcutsAvailableView.php',
     'AphrontListFilterView' => 'view/layout/AphrontListFilterView.php',
     'AphrontMiniPanelView' => 'view/layout/AphrontMiniPanelView.php',
     'AphrontMoreView' => 'view/layout/AphrontMoreView.php',
     'AphrontMultiColumnView' => 'view/layout/AphrontMultiColumnView.php',
     'AphrontMySQLDatabaseConnectionTestCase' => 'infrastructure/storage/__tests__/AphrontMySQLDatabaseConnectionTestCase.php',
     'AphrontNullView' => 'view/AphrontNullView.php',
     'AphrontPHPHTTPSink' => 'aphront/sink/AphrontPHPHTTPSink.php',
     'AphrontPageView' => 'view/page/AphrontPageView.php',
     'AphrontPagerView' => 'view/control/AphrontPagerView.php',
     'AphrontPanelView' => 'view/layout/AphrontPanelView.php',
     'AphrontPlainTextResponse' => 'aphront/response/AphrontPlainTextResponse.php',
     'AphrontProgressBarView' => 'view/widget/bars/AphrontProgressBarView.php',
     'AphrontProxyResponse' => 'aphront/response/AphrontProxyResponse.php',
     'AphrontRedirectResponse' => 'aphront/response/AphrontRedirectResponse.php',
     'AphrontRedirectResponseTestCase' => 'aphront/response/__tests__/AphrontRedirectResponseTestCase.php',
     'AphrontReloadResponse' => 'aphront/response/AphrontReloadResponse.php',
     'AphrontRequest' => 'aphront/AphrontRequest.php',
     'AphrontRequestTestCase' => 'aphront/__tests__/AphrontRequestTestCase.php',
     'AphrontResponse' => 'aphront/response/AphrontResponse.php',
     'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.php',
     'AphrontStackTraceView' => 'view/widget/AphrontStackTraceView.php',
     'AphrontTableView' => 'view/control/AphrontTableView.php',
     'AphrontTagView' => 'view/AphrontTagView.php',
     'AphrontTokenizerTemplateView' => 'view/control/AphrontTokenizerTemplateView.php',
     'AphrontTwoColumnView' => 'view/layout/AphrontTwoColumnView.php',
     'AphrontTypeaheadTemplateView' => 'view/control/AphrontTypeaheadTemplateView.php',
     'AphrontURIMapper' => 'aphront/AphrontURIMapper.php',
     'AphrontUsageException' => 'aphront/exception/AphrontUsageException.php',
     'AphrontView' => 'view/AphrontView.php',
     'AphrontWebpageResponse' => 'aphront/response/AphrontWebpageResponse.php',
     'ArcanistConduitAPIMethod' => 'applications/arcanist/conduit/ArcanistConduitAPIMethod.php',
     'ArcanistProjectInfoConduitAPIMethod' => 'applications/arcanist/conduit/ArcanistProjectInfoConduitAPIMethod.php',
     'AuditActionMenuEventListener' => 'applications/audit/events/AuditActionMenuEventListener.php',
     'AuditConduitAPIMethod' => 'applications/audit/conduit/AuditConduitAPIMethod.php',
     'AuditQueryConduitAPIMethod' => 'applications/audit/conduit/AuditQueryConduitAPIMethod.php',
     'CalendarColors' => 'applications/calendar/constants/CalendarColors.php',
     'CalendarConstants' => 'applications/calendar/constants/CalendarConstants.php',
     'CalendarTimeUtil' => 'applications/calendar/util/CalendarTimeUtil.php',
     'CalendarTimeUtilTestCase' => 'applications/calendar/__tests__/CalendarTimeUtilTestCase.php',
     'CelerityAPI' => 'applications/celerity/CelerityAPI.php',
     'CelerityManagementMapWorkflow' => 'applications/celerity/management/CelerityManagementMapWorkflow.php',
     'CelerityManagementWorkflow' => 'applications/celerity/management/CelerityManagementWorkflow.php',
     'CelerityPhabricatorResourceController' => 'applications/celerity/controller/CelerityPhabricatorResourceController.php',
     'CelerityPhabricatorResources' => 'applications/celerity/resources/CelerityPhabricatorResources.php',
     'CelerityPhysicalResources' => 'applications/celerity/resources/CelerityPhysicalResources.php',
     'CelerityResourceController' => 'applications/celerity/controller/CelerityResourceController.php',
     'CelerityResourceGraph' => 'applications/celerity/CelerityResourceGraph.php',
     'CelerityResourceMap' => 'applications/celerity/CelerityResourceMap.php',
     'CelerityResourceMapGenerator' => 'applications/celerity/CelerityResourceMapGenerator.php',
     'CelerityResourceTransformer' => 'applications/celerity/CelerityResourceTransformer.php',
     'CelerityResourceTransformerTestCase' => 'applications/celerity/__tests__/CelerityResourceTransformerTestCase.php',
     'CelerityResources' => 'applications/celerity/resources/CelerityResources.php',
     'CelerityResourcesOnDisk' => 'applications/celerity/resources/CelerityResourcesOnDisk.php',
     'CeleritySpriteGenerator' => 'applications/celerity/CeleritySpriteGenerator.php',
     'CelerityStaticResourceResponse' => 'applications/celerity/CelerityStaticResourceResponse.php',
     'ChatLogConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogConduitAPIMethod.php',
     'ChatLogQueryConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogQueryConduitAPIMethod.php',
     'ChatLogRecordConduitAPIMethod' => 'applications/chatlog/conduit/ChatLogRecordConduitAPIMethod.php',
     'ConduitAPIMethod' => 'applications/conduit/method/ConduitAPIMethod.php',
     'ConduitAPIRequest' => 'applications/conduit/protocol/ConduitAPIRequest.php',
     'ConduitAPIResponse' => 'applications/conduit/protocol/ConduitAPIResponse.php',
     'ConduitApplicationNotInstalledException' => 'applications/conduit/protocol/exception/ConduitApplicationNotInstalledException.php',
     'ConduitCall' => 'applications/conduit/call/ConduitCall.php',
     'ConduitCallTestCase' => 'applications/conduit/call/__tests__/ConduitCallTestCase.php',
     'ConduitConnectConduitAPIMethod' => 'applications/conduit/method/ConduitConnectConduitAPIMethod.php',
     'ConduitConnectionGarbageCollector' => 'applications/conduit/garbagecollector/ConduitConnectionGarbageCollector.php',
     'ConduitException' => 'applications/conduit/protocol/exception/ConduitException.php',
     'ConduitGetCertificateConduitAPIMethod' => 'applications/conduit/method/ConduitGetCertificateConduitAPIMethod.php',
     'ConduitLogGarbageCollector' => 'applications/conduit/garbagecollector/ConduitLogGarbageCollector.php',
     'ConduitMethodDoesNotExistException' => 'applications/conduit/protocol/exception/ConduitMethodDoesNotExistException.php',
     'ConduitMethodNotFoundException' => 'applications/conduit/protocol/exception/ConduitMethodNotFoundException.php',
     'ConduitPingConduitAPIMethod' => 'applications/conduit/method/ConduitPingConduitAPIMethod.php',
     'ConduitQueryConduitAPIMethod' => 'applications/conduit/method/ConduitQueryConduitAPIMethod.php',
     'ConduitSSHWorkflow' => 'applications/conduit/ssh/ConduitSSHWorkflow.php',
     'ConpherenceActionMenuEventListener' => 'applications/conpherence/events/ConpherenceActionMenuEventListener.php',
     'ConpherenceConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceConduitAPIMethod.php',
     'ConpherenceConfigOptions' => 'applications/conpherence/config/ConpherenceConfigOptions.php',
     'ConpherenceConstants' => 'applications/conpherence/constants/ConpherenceConstants.php',
     'ConpherenceController' => 'applications/conpherence/controller/ConpherenceController.php',
     'ConpherenceCreateThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceCreateThreadConduitAPIMethod.php',
     'ConpherenceCreateThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceCreateThreadMailReceiver.php',
     'ConpherenceDAO' => 'applications/conpherence/storage/ConpherenceDAO.php',
     'ConpherenceEditor' => 'applications/conpherence/editor/ConpherenceEditor.php',
     'ConpherenceFileWidgetView' => 'applications/conpherence/view/ConpherenceFileWidgetView.php',
     'ConpherenceHovercardEventListener' => 'applications/conpherence/events/ConpherenceHovercardEventListener.php',
     'ConpherenceLayoutView' => 'applications/conpherence/view/ConpherenceLayoutView.php',
     'ConpherenceListController' => 'applications/conpherence/controller/ConpherenceListController.php',
     'ConpherenceMenuItemView' => 'applications/conpherence/view/ConpherenceMenuItemView.php',
     'ConpherenceNewController' => 'applications/conpherence/controller/ConpherenceNewController.php',
     'ConpherenceNotificationPanelController' => 'applications/conpherence/controller/ConpherenceNotificationPanelController.php',
     'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php',
     'ConpherenceParticipantCountQuery' => 'applications/conpherence/query/ConpherenceParticipantCountQuery.php',
     'ConpherenceParticipantQuery' => 'applications/conpherence/query/ConpherenceParticipantQuery.php',
     'ConpherenceParticipationStatus' => 'applications/conpherence/constants/ConpherenceParticipationStatus.php',
     'ConpherencePeopleWidgetView' => 'applications/conpherence/view/ConpherencePeopleWidgetView.php',
     'ConpherenceQueryThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryThreadConduitAPIMethod.php',
     'ConpherenceQueryTransactionConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceQueryTransactionConduitAPIMethod.php',
     'ConpherenceReplyHandler' => 'applications/conpherence/mail/ConpherenceReplyHandler.php',
     'ConpherenceSchemaSpec' => 'applications/conpherence/storage/ConpherenceSchemaSpec.php',
     'ConpherenceSettings' => 'applications/conpherence/constants/ConpherenceSettings.php',
     'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.php',
     'ConpherenceThreadListView' => 'applications/conpherence/view/ConpherenceThreadListView.php',
     'ConpherenceThreadMailReceiver' => 'applications/conpherence/mail/ConpherenceThreadMailReceiver.php',
     'ConpherenceThreadQuery' => 'applications/conpherence/query/ConpherenceThreadQuery.php',
     'ConpherenceTransaction' => 'applications/conpherence/storage/ConpherenceTransaction.php',
     'ConpherenceTransactionComment' => 'applications/conpherence/storage/ConpherenceTransactionComment.php',
     'ConpherenceTransactionQuery' => 'applications/conpherence/query/ConpherenceTransactionQuery.php',
     'ConpherenceTransactionType' => 'applications/conpherence/constants/ConpherenceTransactionType.php',
     'ConpherenceTransactionView' => 'applications/conpherence/view/ConpherenceTransactionView.php',
     'ConpherenceUpdateActions' => 'applications/conpherence/constants/ConpherenceUpdateActions.php',
     'ConpherenceUpdateController' => 'applications/conpherence/controller/ConpherenceUpdateController.php',
     'ConpherenceUpdateThreadConduitAPIMethod' => 'applications/conpherence/conduit/ConpherenceUpdateThreadConduitAPIMethod.php',
     'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php',
     'ConpherenceWidgetController' => 'applications/conpherence/controller/ConpherenceWidgetController.php',
     'ConpherenceWidgetView' => 'applications/conpherence/view/ConpherenceWidgetView.php',
     'DarkConsoleController' => 'applications/console/controller/DarkConsoleController.php',
     'DarkConsoleCore' => 'applications/console/core/DarkConsoleCore.php',
     'DarkConsoleDataController' => 'applications/console/controller/DarkConsoleDataController.php',
     'DarkConsoleErrorLogPlugin' => 'applications/console/plugin/DarkConsoleErrorLogPlugin.php',
     'DarkConsoleErrorLogPluginAPI' => 'applications/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php',
     'DarkConsoleEventPlugin' => 'applications/console/plugin/DarkConsoleEventPlugin.php',
     'DarkConsoleEventPluginAPI' => 'applications/console/plugin/event/DarkConsoleEventPluginAPI.php',
     'DarkConsolePlugin' => 'applications/console/plugin/DarkConsolePlugin.php',
     'DarkConsoleRequestPlugin' => 'applications/console/plugin/DarkConsoleRequestPlugin.php',
     'DarkConsoleServicesPlugin' => 'applications/console/plugin/DarkConsoleServicesPlugin.php',
     'DarkConsoleXHProfPlugin' => 'applications/console/plugin/DarkConsoleXHProfPlugin.php',
     'DarkConsoleXHProfPluginAPI' => 'applications/console/plugin/xhprof/DarkConsoleXHProfPluginAPI.php',
     'DatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DatabaseConfigurationProvider.php',
     'DefaultDatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DefaultDatabaseConfigurationProvider.php',
     'DifferentialAction' => 'applications/differential/constants/DifferentialAction.php',
     'DifferentialActionMenuEventListener' => 'applications/differential/event/DifferentialActionMenuEventListener.php',
     'DifferentialAddCommentView' => 'applications/differential/view/DifferentialAddCommentView.php',
     'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php',
     'DifferentialApplyPatchField' => 'applications/differential/customfield/DifferentialApplyPatchField.php',
     'DifferentialArcanistProjectField' => 'applications/differential/customfield/DifferentialArcanistProjectField.php',
     'DifferentialAsanaRepresentationField' => 'applications/differential/customfield/DifferentialAsanaRepresentationField.php',
     'DifferentialAuditorsField' => 'applications/differential/customfield/DifferentialAuditorsField.php',
     'DifferentialAuthorField' => 'applications/differential/customfield/DifferentialAuthorField.php',
     'DifferentialBlameRevisionField' => 'applications/differential/customfield/DifferentialBlameRevisionField.php',
     'DifferentialBranchField' => 'applications/differential/customfield/DifferentialBranchField.php',
     'DifferentialChangeType' => 'applications/differential/constants/DifferentialChangeType.php',
     'DifferentialChangesSinceLastUpdateField' => 'applications/differential/customfield/DifferentialChangesSinceLastUpdateField.php',
     'DifferentialChangeset' => 'applications/differential/storage/DifferentialChangeset.php',
     'DifferentialChangesetDetailView' => 'applications/differential/view/DifferentialChangesetDetailView.php',
     'DifferentialChangesetFileTreeSideNavBuilder' => 'applications/differential/view/DifferentialChangesetFileTreeSideNavBuilder.php',
     'DifferentialChangesetHTMLRenderer' => 'applications/differential/render/DifferentialChangesetHTMLRenderer.php',
     'DifferentialChangesetListView' => 'applications/differential/view/DifferentialChangesetListView.php',
     'DifferentialChangesetOneUpRenderer' => 'applications/differential/render/DifferentialChangesetOneUpRenderer.php',
     'DifferentialChangesetOneUpTestRenderer' => 'applications/differential/render/DifferentialChangesetOneUpTestRenderer.php',
     'DifferentialChangesetParser' => 'applications/differential/parser/DifferentialChangesetParser.php',
     'DifferentialChangesetParserTestCase' => 'applications/differential/parser/__tests__/DifferentialChangesetParserTestCase.php',
     'DifferentialChangesetQuery' => 'applications/differential/query/DifferentialChangesetQuery.php',
     'DifferentialChangesetRenderer' => 'applications/differential/render/DifferentialChangesetRenderer.php',
     'DifferentialChangesetTestRenderer' => 'applications/differential/render/DifferentialChangesetTestRenderer.php',
     'DifferentialChangesetTwoUpRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpRenderer.php',
     'DifferentialChangesetTwoUpTestRenderer' => 'applications/differential/render/DifferentialChangesetTwoUpTestRenderer.php',
     'DifferentialChangesetViewController' => 'applications/differential/controller/DifferentialChangesetViewController.php',
     'DifferentialCloseConduitAPIMethod' => 'applications/differential/conduit/DifferentialCloseConduitAPIMethod.php',
     'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php',
     'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php',
     'DifferentialCommitMessageParser' => 'applications/differential/parser/DifferentialCommitMessageParser.php',
     'DifferentialCommitMessageParserTestCase' => 'applications/differential/parser/__tests__/DifferentialCommitMessageParserTestCase.php',
     'DifferentialCommitsField' => 'applications/differential/customfield/DifferentialCommitsField.php',
     'DifferentialConduitAPIMethod' => 'applications/differential/conduit/DifferentialConduitAPIMethod.php',
     'DifferentialConflictsField' => 'applications/differential/customfield/DifferentialConflictsField.php',
     'DifferentialController' => 'applications/differential/controller/DifferentialController.php',
     'DifferentialCoreCustomField' => 'applications/differential/customfield/DifferentialCoreCustomField.php',
     'DifferentialCreateCommentConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateCommentConduitAPIMethod.php',
     'DifferentialCreateDiffConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateDiffConduitAPIMethod.php',
     'DifferentialCreateInlineConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateInlineConduitAPIMethod.php',
     'DifferentialCreateRawDiffConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateRawDiffConduitAPIMethod.php',
     'DifferentialCreateRevisionConduitAPIMethod' => 'applications/differential/conduit/DifferentialCreateRevisionConduitAPIMethod.php',
     'DifferentialCustomField' => 'applications/differential/customfield/DifferentialCustomField.php',
     'DifferentialCustomFieldDependsOnParser' => 'applications/differential/parser/DifferentialCustomFieldDependsOnParser.php',
     'DifferentialCustomFieldDependsOnParserTestCase' => 'applications/differential/parser/__tests__/DifferentialCustomFieldDependsOnParserTestCase.php',
     'DifferentialCustomFieldNumericIndex' => 'applications/differential/storage/DifferentialCustomFieldNumericIndex.php',
     'DifferentialCustomFieldRevertsParser' => 'applications/differential/parser/DifferentialCustomFieldRevertsParser.php',
     'DifferentialCustomFieldRevertsParserTestCase' => 'applications/differential/parser/__tests__/DifferentialCustomFieldRevertsParserTestCase.php',
     'DifferentialCustomFieldStorage' => 'applications/differential/storage/DifferentialCustomFieldStorage.php',
     'DifferentialCustomFieldStringIndex' => 'applications/differential/storage/DifferentialCustomFieldStringIndex.php',
     'DifferentialDAO' => 'applications/differential/storage/DifferentialDAO.php',
     'DifferentialDefaultViewCapability' => 'applications/differential/capability/DifferentialDefaultViewCapability.php',
     'DifferentialDependenciesField' => 'applications/differential/customfield/DifferentialDependenciesField.php',
     'DifferentialDependsOnField' => 'applications/differential/customfield/DifferentialDependsOnField.php',
     'DifferentialDiff' => 'applications/differential/storage/DifferentialDiff.php',
     'DifferentialDiffCreateController' => 'applications/differential/controller/DifferentialDiffCreateController.php',
     'DifferentialDiffCreationRejectException' => 'applications/differential/exception/DifferentialDiffCreationRejectException.php',
     'DifferentialDiffEditor' => 'applications/differential/editor/DifferentialDiffEditor.php',
     'DifferentialDiffPHIDType' => 'applications/differential/phid/DifferentialDiffPHIDType.php',
     'DifferentialDiffProperty' => 'applications/differential/storage/DifferentialDiffProperty.php',
     'DifferentialDiffQuery' => 'applications/differential/query/DifferentialDiffQuery.php',
     'DifferentialDiffTableOfContentsView' => 'applications/differential/view/DifferentialDiffTableOfContentsView.php',
     'DifferentialDiffTestCase' => 'applications/differential/storage/__tests__/DifferentialDiffTestCase.php',
     'DifferentialDiffTransaction' => 'applications/differential/storage/DifferentialDiffTransaction.php',
     'DifferentialDiffViewController' => 'applications/differential/controller/DifferentialDiffViewController.php',
     'DifferentialDoorkeeperRevisionFeedStoryPublisher' => 'applications/differential/doorkeeper/DifferentialDoorkeeperRevisionFeedStoryPublisher.php',
     'DifferentialDraft' => 'applications/differential/storage/DifferentialDraft.php',
     'DifferentialEditPolicyField' => 'applications/differential/customfield/DifferentialEditPolicyField.php',
     'DifferentialFieldParseException' => 'applications/differential/exception/DifferentialFieldParseException.php',
     'DifferentialFieldValidationException' => 'applications/differential/exception/DifferentialFieldValidationException.php',
     'DifferentialFindConduitAPIMethod' => 'applications/differential/conduit/DifferentialFindConduitAPIMethod.php',
     'DifferentialFinishPostponedLintersConduitAPIMethod' => 'applications/differential/conduit/DifferentialFinishPostponedLintersConduitAPIMethod.php',
     'DifferentialGetAllDiffsConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetAllDiffsConduitAPIMethod.php',
     'DifferentialGetCommitMessageConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetCommitMessageConduitAPIMethod.php',
     'DifferentialGetCommitPathsConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetCommitPathsConduitAPIMethod.php',
     'DifferentialGetDiffConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetDiffConduitAPIMethod.php',
     'DifferentialGetRawDiffConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetRawDiffConduitAPIMethod.php',
     'DifferentialGetRevisionCommentsConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetRevisionCommentsConduitAPIMethod.php',
     'DifferentialGetRevisionConduitAPIMethod' => 'applications/differential/conduit/DifferentialGetRevisionConduitAPIMethod.php',
     'DifferentialGetWorkingCopy' => 'applications/differential/DifferentialGetWorkingCopy.php',
     'DifferentialGitSVNIDField' => 'applications/differential/customfield/DifferentialGitSVNIDField.php',
     'DifferentialHostField' => 'applications/differential/customfield/DifferentialHostField.php',
     'DifferentialHovercardEventListener' => 'applications/differential/event/DifferentialHovercardEventListener.php',
     'DifferentialHunk' => 'applications/differential/storage/DifferentialHunk.php',
     'DifferentialHunkLegacy' => 'applications/differential/storage/DifferentialHunkLegacy.php',
     'DifferentialHunkModern' => 'applications/differential/storage/DifferentialHunkModern.php',
     'DifferentialHunkParser' => 'applications/differential/parser/DifferentialHunkParser.php',
     'DifferentialHunkParserTestCase' => 'applications/differential/parser/__tests__/DifferentialHunkParserTestCase.php',
     'DifferentialHunkQuery' => 'applications/differential/query/DifferentialHunkQuery.php',
     'DifferentialHunkTestCase' => 'applications/differential/storage/__tests__/DifferentialHunkTestCase.php',
     'DifferentialInlineComment' => 'applications/differential/storage/DifferentialInlineComment.php',
     'DifferentialInlineCommentEditController' => 'applications/differential/controller/DifferentialInlineCommentEditController.php',
     'DifferentialInlineCommentEditView' => 'applications/differential/view/DifferentialInlineCommentEditView.php',
     'DifferentialInlineCommentPreviewController' => 'applications/differential/controller/DifferentialInlineCommentPreviewController.php',
     'DifferentialInlineCommentQuery' => 'applications/differential/query/DifferentialInlineCommentQuery.php',
     'DifferentialInlineCommentView' => 'applications/differential/view/DifferentialInlineCommentView.php',
     'DifferentialJIRAIssuesField' => 'applications/differential/customfield/DifferentialJIRAIssuesField.php',
     'DifferentialLandingActionMenuEventListener' => 'applications/differential/landing/DifferentialLandingActionMenuEventListener.php',
     'DifferentialLandingStrategy' => 'applications/differential/landing/DifferentialLandingStrategy.php',
     'DifferentialLandingToGitHub' => 'applications/differential/landing/DifferentialLandingToGitHub.php',
     'DifferentialLandingToHostedGit' => 'applications/differential/landing/DifferentialLandingToHostedGit.php',
     'DifferentialLandingToHostedMercurial' => 'applications/differential/landing/DifferentialLandingToHostedMercurial.php',
     'DifferentialLintField' => 'applications/differential/customfield/DifferentialLintField.php',
     'DifferentialLintStatus' => 'applications/differential/constants/DifferentialLintStatus.php',
     'DifferentialLocalCommitsView' => 'applications/differential/view/DifferentialLocalCommitsView.php',
     'DifferentialMail' => 'applications/differential/mail/DifferentialMail.php',
     'DifferentialManiphestTasksField' => 'applications/differential/customfield/DifferentialManiphestTasksField.php',
     'DifferentialParseCacheGarbageCollector' => 'applications/differential/garbagecollector/DifferentialParseCacheGarbageCollector.php',
     'DifferentialParseCommitMessageConduitAPIMethod' => 'applications/differential/conduit/DifferentialParseCommitMessageConduitAPIMethod.php',
     'DifferentialParseRenderTestCase' => 'applications/differential/__tests__/DifferentialParseRenderTestCase.php',
     'DifferentialPathField' => 'applications/differential/customfield/DifferentialPathField.php',
     'DifferentialPrimaryPaneView' => 'applications/differential/view/DifferentialPrimaryPaneView.php',
     'DifferentialProjectReviewersField' => 'applications/differential/customfield/DifferentialProjectReviewersField.php',
     'DifferentialProjectsField' => 'applications/differential/customfield/DifferentialProjectsField.php',
     'DifferentialQueryConduitAPIMethod' => 'applications/differential/conduit/DifferentialQueryConduitAPIMethod.php',
     'DifferentialQueryDiffsConduitAPIMethod' => 'applications/differential/conduit/DifferentialQueryDiffsConduitAPIMethod.php',
     'DifferentialRawDiffRenderer' => 'applications/differential/render/DifferentialRawDiffRenderer.php',
     'DifferentialReleephRequestFieldSpecification' => 'applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php',
     'DifferentialRemarkupRule' => 'applications/differential/remarkup/DifferentialRemarkupRule.php',
     'DifferentialReplyHandler' => 'applications/differential/mail/DifferentialReplyHandler.php',
     'DifferentialRepositoryField' => 'applications/differential/customfield/DifferentialRepositoryField.php',
     'DifferentialRepositoryLookup' => 'applications/differential/query/DifferentialRepositoryLookup.php',
     'DifferentialRequiredSignaturesField' => 'applications/differential/customfield/DifferentialRequiredSignaturesField.php',
     'DifferentialResultsTableView' => 'applications/differential/view/DifferentialResultsTableView.php',
     'DifferentialRevertPlanField' => 'applications/differential/customfield/DifferentialRevertPlanField.php',
     'DifferentialReviewedByField' => 'applications/differential/customfield/DifferentialReviewedByField.php',
     'DifferentialReviewer' => 'applications/differential/storage/DifferentialReviewer.php',
     'DifferentialReviewerStatus' => 'applications/differential/constants/DifferentialReviewerStatus.php',
     'DifferentialReviewersField' => 'applications/differential/customfield/DifferentialReviewersField.php',
     'DifferentialReviewersView' => 'applications/differential/view/DifferentialReviewersView.php',
     'DifferentialRevision' => 'applications/differential/storage/DifferentialRevision.php',
     'DifferentialRevisionCloseDetailsController' => 'applications/differential/controller/DifferentialRevisionCloseDetailsController.php',
     'DifferentialRevisionControlSystem' => 'applications/differential/constants/DifferentialRevisionControlSystem.php',
     'DifferentialRevisionDetailView' => 'applications/differential/view/DifferentialRevisionDetailView.php',
     'DifferentialRevisionEditController' => 'applications/differential/controller/DifferentialRevisionEditController.php',
     'DifferentialRevisionHasTaskEdgeType' => 'applications/differential/edge/DifferentialRevisionHasTaskEdgeType.php',
     'DifferentialRevisionIDField' => 'applications/differential/customfield/DifferentialRevisionIDField.php',
     'DifferentialRevisionLandController' => 'applications/differential/controller/DifferentialRevisionLandController.php',
     'DifferentialRevisionListController' => 'applications/differential/controller/DifferentialRevisionListController.php',
     'DifferentialRevisionListView' => 'applications/differential/view/DifferentialRevisionListView.php',
     'DifferentialRevisionMailReceiver' => 'applications/differential/mail/DifferentialRevisionMailReceiver.php',
     'DifferentialRevisionPHIDType' => 'applications/differential/phid/DifferentialRevisionPHIDType.php',
     'DifferentialRevisionQuery' => 'applications/differential/query/DifferentialRevisionQuery.php',
     'DifferentialRevisionSearchEngine' => 'applications/differential/query/DifferentialRevisionSearchEngine.php',
     'DifferentialRevisionStatus' => 'applications/differential/constants/DifferentialRevisionStatus.php',
     'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/DifferentialRevisionUpdateHistoryView.php',
     'DifferentialRevisionViewController' => 'applications/differential/controller/DifferentialRevisionViewController.php',
     'DifferentialSchemaSpec' => 'applications/differential/storage/DifferentialSchemaSpec.php',
     'DifferentialSearchIndexer' => 'applications/differential/search/DifferentialSearchIndexer.php',
     'DifferentialSetDiffPropertyConduitAPIMethod' => 'applications/differential/conduit/DifferentialSetDiffPropertyConduitAPIMethod.php',
     'DifferentialStoredCustomField' => 'applications/differential/customfield/DifferentialStoredCustomField.php',
     'DifferentialSubscribersField' => 'applications/differential/customfield/DifferentialSubscribersField.php',
     'DifferentialSummaryField' => 'applications/differential/customfield/DifferentialSummaryField.php',
     'DifferentialTestPlanField' => 'applications/differential/customfield/DifferentialTestPlanField.php',
     'DifferentialTitleField' => 'applications/differential/customfield/DifferentialTitleField.php',
     'DifferentialTransaction' => 'applications/differential/storage/DifferentialTransaction.php',
     'DifferentialTransactionComment' => 'applications/differential/storage/DifferentialTransactionComment.php',
     'DifferentialTransactionEditor' => 'applications/differential/editor/DifferentialTransactionEditor.php',
     'DifferentialTransactionQuery' => 'applications/differential/query/DifferentialTransactionQuery.php',
     'DifferentialTransactionView' => 'applications/differential/view/DifferentialTransactionView.php',
     'DifferentialUnitField' => 'applications/differential/customfield/DifferentialUnitField.php',
     'DifferentialUnitStatus' => 'applications/differential/constants/DifferentialUnitStatus.php',
     'DifferentialUnitTestResult' => 'applications/differential/constants/DifferentialUnitTestResult.php',
     'DifferentialUpdateRevisionConduitAPIMethod' => 'applications/differential/conduit/DifferentialUpdateRevisionConduitAPIMethod.php',
     'DifferentialUpdateUnitResultsConduitAPIMethod' => 'applications/differential/conduit/DifferentialUpdateUnitResultsConduitAPIMethod.php',
     'DifferentialViewPolicyField' => 'applications/differential/customfield/DifferentialViewPolicyField.php',
     'DiffusionArcanistProjectDatasource' => 'applications/diffusion/typeahead/DiffusionArcanistProjectDatasource.php',
     'DiffusionAuditorDatasource' => 'applications/diffusion/typeahead/DiffusionAuditorDatasource.php',
     'DiffusionBranchQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionBranchQueryConduitAPIMethod.php',
     'DiffusionBranchTableController' => 'applications/diffusion/controller/DiffusionBranchTableController.php',
     'DiffusionBranchTableView' => 'applications/diffusion/view/DiffusionBranchTableView.php',
     'DiffusionBrowseController' => 'applications/diffusion/controller/DiffusionBrowseController.php',
     'DiffusionBrowseDirectoryController' => 'applications/diffusion/controller/DiffusionBrowseDirectoryController.php',
     'DiffusionBrowseFileController' => 'applications/diffusion/controller/DiffusionBrowseFileController.php',
     'DiffusionBrowseMainController' => 'applications/diffusion/controller/DiffusionBrowseMainController.php',
     'DiffusionBrowseQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionBrowseQueryConduitAPIMethod.php',
     'DiffusionBrowseResultSet' => 'applications/diffusion/data/DiffusionBrowseResultSet.php',
     'DiffusionBrowseSearchController' => 'applications/diffusion/controller/DiffusionBrowseSearchController.php',
     'DiffusionBrowseTableView' => 'applications/diffusion/view/DiffusionBrowseTableView.php',
     'DiffusionChangeController' => 'applications/diffusion/controller/DiffusionChangeController.php',
     'DiffusionCommitBranchesController' => 'applications/diffusion/controller/DiffusionCommitBranchesController.php',
     'DiffusionCommitChangeTableView' => 'applications/diffusion/view/DiffusionCommitChangeTableView.php',
     'DiffusionCommitController' => 'applications/diffusion/controller/DiffusionCommitController.php',
     'DiffusionCommitEditController' => 'applications/diffusion/controller/DiffusionCommitEditController.php',
     'DiffusionCommitHasTaskEdgeType' => 'applications/diffusion/edge/DiffusionCommitHasTaskEdgeType.php',
     'DiffusionCommitHash' => 'applications/diffusion/data/DiffusionCommitHash.php',
     'DiffusionCommitHookEngine' => 'applications/diffusion/engine/DiffusionCommitHookEngine.php',
     'DiffusionCommitHookRejectException' => 'applications/diffusion/exception/DiffusionCommitHookRejectException.php',
     'DiffusionCommitParentsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionCommitParentsQueryConduitAPIMethod.php',
     'DiffusionCommitQuery' => 'applications/diffusion/query/DiffusionCommitQuery.php',
     'DiffusionCommitRef' => 'applications/diffusion/data/DiffusionCommitRef.php',
     'DiffusionCommitRemarkupRule' => 'applications/diffusion/remarkup/DiffusionCommitRemarkupRule.php',
     'DiffusionCommitRemarkupRuleTestCase' => 'applications/diffusion/remarkup/__tests__/DiffusionCommitRemarkupRuleTestCase.php',
     'DiffusionCommitTagsController' => 'applications/diffusion/controller/DiffusionCommitTagsController.php',
     'DiffusionConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionConduitAPIMethod.php',
     'DiffusionController' => 'applications/diffusion/controller/DiffusionController.php',
     'DiffusionCreateCommentConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionCreateCommentConduitAPIMethod.php',
     'DiffusionCreateRepositoriesCapability' => 'applications/diffusion/capability/DiffusionCreateRepositoriesCapability.php',
     'DiffusionDefaultEditCapability' => 'applications/diffusion/capability/DiffusionDefaultEditCapability.php',
     'DiffusionDefaultPushCapability' => 'applications/diffusion/capability/DiffusionDefaultPushCapability.php',
     'DiffusionDefaultViewCapability' => 'applications/diffusion/capability/DiffusionDefaultViewCapability.php',
     'DiffusionDiffController' => 'applications/diffusion/controller/DiffusionDiffController.php',
     'DiffusionDiffQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionDiffQueryConduitAPIMethod.php',
     'DiffusionDoorkeeperCommitFeedStoryPublisher' => 'applications/diffusion/doorkeeper/DiffusionDoorkeeperCommitFeedStoryPublisher.php',
     'DiffusionEmptyResultView' => 'applications/diffusion/view/DiffusionEmptyResultView.php',
     'DiffusionExistsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionExistsQueryConduitAPIMethod.php',
     'DiffusionExternalController' => 'applications/diffusion/controller/DiffusionExternalController.php',
     'DiffusionFileContent' => 'applications/diffusion/data/DiffusionFileContent.php',
     'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionFileContentQuery.php',
     'DiffusionFileContentQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionFileContentQueryConduitAPIMethod.php',
     'DiffusionFindSymbolsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionFindSymbolsConduitAPIMethod.php',
     'DiffusionGetCommitsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionGetCommitsConduitAPIMethod.php',
     'DiffusionGetLintMessagesConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionGetLintMessagesConduitAPIMethod.php',
     'DiffusionGetRecentCommitsByPathConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionGetRecentCommitsByPathConduitAPIMethod.php',
     'DiffusionGitBranch' => 'applications/diffusion/data/DiffusionGitBranch.php',
     'DiffusionGitBranchTestCase' => 'applications/diffusion/data/__tests__/DiffusionGitBranchTestCase.php',
     'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php',
     'DiffusionGitFileContentQueryTestCase' => 'applications/diffusion/query/__tests__/DiffusionGitFileContentQueryTestCase.php',
     'DiffusionGitRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php',
     'DiffusionGitRequest' => 'applications/diffusion/request/DiffusionGitRequest.php',
     'DiffusionGitResponse' => 'applications/diffusion/response/DiffusionGitResponse.php',
     'DiffusionHistoryController' => 'applications/diffusion/controller/DiffusionHistoryController.php',
     'DiffusionHistoryQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionHistoryQueryConduitAPIMethod.php',
     'DiffusionHistoryTableView' => 'applications/diffusion/view/DiffusionHistoryTableView.php',
     'DiffusionHovercardEventListener' => 'applications/diffusion/events/DiffusionHovercardEventListener.php',
     'DiffusionInlineCommentController' => 'applications/diffusion/controller/DiffusionInlineCommentController.php',
     'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php',
     'DiffusionLastModifiedController' => 'applications/diffusion/controller/DiffusionLastModifiedController.php',
     'DiffusionLastModifiedQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionLastModifiedQueryConduitAPIMethod.php',
     'DiffusionLintController' => 'applications/diffusion/controller/DiffusionLintController.php',
     'DiffusionLintCountQuery' => 'applications/diffusion/query/DiffusionLintCountQuery.php',
     'DiffusionLintDetailsController' => 'applications/diffusion/controller/DiffusionLintDetailsController.php',
     'DiffusionLintSaveRunner' => 'applications/diffusion/DiffusionLintSaveRunner.php',
     'DiffusionLookSoonConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionLookSoonConduitAPIMethod.php',
     'DiffusionLowLevelCommitFieldsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelCommitFieldsQuery.php',
     'DiffusionLowLevelCommitQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelCommitQuery.php',
     'DiffusionLowLevelGitRefQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelGitRefQuery.php',
     'DiffusionLowLevelMercurialBranchesQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialBranchesQuery.php',
     'DiffusionLowLevelMercurialPathsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelMercurialPathsQuery.php',
     'DiffusionLowLevelParentsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelParentsQuery.php',
     'DiffusionLowLevelQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelQuery.php',
     'DiffusionLowLevelResolveRefsQuery' => 'applications/diffusion/query/lowlevel/DiffusionLowLevelResolveRefsQuery.php',
     'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php',
     'DiffusionMercurialRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php',
     'DiffusionMercurialRequest' => 'applications/diffusion/request/DiffusionMercurialRequest.php',
     'DiffusionMercurialResponse' => 'applications/diffusion/response/DiffusionMercurialResponse.php',
     'DiffusionMercurialWireProtocol' => 'applications/diffusion/protocol/DiffusionMercurialWireProtocol.php',
     'DiffusionMergedCommitsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionMergedCommitsQueryConduitAPIMethod.php',
     'DiffusionMirrorDeleteController' => 'applications/diffusion/controller/DiffusionMirrorDeleteController.php',
     'DiffusionMirrorEditController' => 'applications/diffusion/controller/DiffusionMirrorEditController.php',
     'DiffusionPathChange' => 'applications/diffusion/data/DiffusionPathChange.php',
     'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/DiffusionPathChangeQuery.php',
     'DiffusionPathCompleteController' => 'applications/diffusion/controller/DiffusionPathCompleteController.php',
     'DiffusionPathIDQuery' => 'applications/diffusion/query/pathid/DiffusionPathIDQuery.php',
     'DiffusionPathQuery' => 'applications/diffusion/query/DiffusionPathQuery.php',
     'DiffusionPathQueryTestCase' => 'applications/diffusion/query/pathid/__tests__/DiffusionPathQueryTestCase.php',
     'DiffusionPathTreeController' => 'applications/diffusion/controller/DiffusionPathTreeController.php',
     'DiffusionPathValidateController' => 'applications/diffusion/controller/DiffusionPathValidateController.php',
     'DiffusionPushCapability' => 'applications/diffusion/capability/DiffusionPushCapability.php',
     'DiffusionPushEventViewController' => 'applications/diffusion/controller/DiffusionPushEventViewController.php',
     'DiffusionPushLogController' => 'applications/diffusion/controller/DiffusionPushLogController.php',
     'DiffusionPushLogListController' => 'applications/diffusion/controller/DiffusionPushLogListController.php',
     'DiffusionPushLogListView' => 'applications/diffusion/view/DiffusionPushLogListView.php',
     'DiffusionQuery' => 'applications/diffusion/query/DiffusionQuery.php',
     'DiffusionQueryCommitsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionQueryCommitsConduitAPIMethod.php',
     'DiffusionQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionQueryConduitAPIMethod.php',
     'DiffusionQueryPathsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionQueryPathsConduitAPIMethod.php',
     'DiffusionRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.php',
     'DiffusionRawDiffQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRawDiffQueryConduitAPIMethod.php',
     'DiffusionReadmeQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionReadmeQueryConduitAPIMethod.php',
     'DiffusionRefNotFoundException' => 'applications/diffusion/exception/DiffusionRefNotFoundException.php',
     'DiffusionRefsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRefsQueryConduitAPIMethod.php',
     'DiffusionRenameHistoryQuery' => 'applications/diffusion/query/DiffusionRenameHistoryQuery.php',
     'DiffusionRepositoryController' => 'applications/diffusion/controller/DiffusionRepositoryController.php',
     'DiffusionRepositoryCreateController' => 'applications/diffusion/controller/DiffusionRepositoryCreateController.php',
     'DiffusionRepositoryDatasource' => 'applications/diffusion/typeahead/DiffusionRepositoryDatasource.php',
     'DiffusionRepositoryDefaultController' => 'applications/diffusion/controller/DiffusionRepositoryDefaultController.php',
     'DiffusionRepositoryEditActionsController' => 'applications/diffusion/controller/DiffusionRepositoryEditActionsController.php',
     'DiffusionRepositoryEditActivateController' => 'applications/diffusion/controller/DiffusionRepositoryEditActivateController.php',
     'DiffusionRepositoryEditBasicController' => 'applications/diffusion/controller/DiffusionRepositoryEditBasicController.php',
     'DiffusionRepositoryEditBranchesController' => 'applications/diffusion/controller/DiffusionRepositoryEditBranchesController.php',
     'DiffusionRepositoryEditController' => 'applications/diffusion/controller/DiffusionRepositoryEditController.php',
     'DiffusionRepositoryEditDangerousController' => 'applications/diffusion/controller/DiffusionRepositoryEditDangerousController.php',
     'DiffusionRepositoryEditDeleteController' => 'applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php',
     'DiffusionRepositoryEditEncodingController' => 'applications/diffusion/controller/DiffusionRepositoryEditEncodingController.php',
     'DiffusionRepositoryEditHostingController' => 'applications/diffusion/controller/DiffusionRepositoryEditHostingController.php',
     'DiffusionRepositoryEditLocalController' => 'applications/diffusion/controller/DiffusionRepositoryEditLocalController.php',
     'DiffusionRepositoryEditMainController' => 'applications/diffusion/controller/DiffusionRepositoryEditMainController.php',
     'DiffusionRepositoryEditSubversionController' => 'applications/diffusion/controller/DiffusionRepositoryEditSubversionController.php',
     'DiffusionRepositoryEditUpdateController' => 'applications/diffusion/controller/DiffusionRepositoryEditUpdateController.php',
     'DiffusionRepositoryListController' => 'applications/diffusion/controller/DiffusionRepositoryListController.php',
     'DiffusionRepositoryNewController' => 'applications/diffusion/controller/DiffusionRepositoryNewController.php',
     'DiffusionRepositoryPath' => 'applications/diffusion/data/DiffusionRepositoryPath.php',
     'DiffusionRepositoryRef' => 'applications/diffusion/data/DiffusionRepositoryRef.php',
     'DiffusionRepositoryRemarkupRule' => 'applications/diffusion/remarkup/DiffusionRepositoryRemarkupRule.php',
     'DiffusionRepositoryTag' => 'applications/diffusion/data/DiffusionRepositoryTag.php',
     'DiffusionRequest' => 'applications/diffusion/request/DiffusionRequest.php',
     'DiffusionResolveRefsConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionResolveRefsConduitAPIMethod.php',
     'DiffusionResolveUserQuery' => 'applications/diffusion/query/DiffusionResolveUserQuery.php',
     'DiffusionSSHGitReceivePackWorkflow' => 'applications/diffusion/ssh/DiffusionSSHGitReceivePackWorkflow.php',
     'DiffusionSSHGitUploadPackWorkflow' => 'applications/diffusion/ssh/DiffusionSSHGitUploadPackWorkflow.php',
     'DiffusionSSHGitWorkflow' => 'applications/diffusion/ssh/DiffusionSSHGitWorkflow.php',
     'DiffusionSSHMercurialServeWorkflow' => 'applications/diffusion/ssh/DiffusionSSHMercurialServeWorkflow.php',
     'DiffusionSSHMercurialWireClientProtocolChannel' => 'applications/diffusion/ssh/DiffusionSSHMercurialWireClientProtocolChannel.php',
     'DiffusionSSHMercurialWireTestCase' => 'applications/diffusion/ssh/__tests__/DiffusionSSHMercurialWireTestCase.php',
     'DiffusionSSHMercurialWorkflow' => 'applications/diffusion/ssh/DiffusionSSHMercurialWorkflow.php',
     'DiffusionSSHSubversionServeWorkflow' => 'applications/diffusion/ssh/DiffusionSSHSubversionServeWorkflow.php',
     'DiffusionSSHSubversionWorkflow' => 'applications/diffusion/ssh/DiffusionSSHSubversionWorkflow.php',
     'DiffusionSSHWorkflow' => 'applications/diffusion/ssh/DiffusionSSHWorkflow.php',
     'DiffusionSearchQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionSearchQueryConduitAPIMethod.php',
     'DiffusionServeController' => 'applications/diffusion/controller/DiffusionServeController.php',
     'DiffusionSetPasswordPanel' => 'applications/diffusion/panel/DiffusionSetPasswordPanel.php',
     'DiffusionSetupException' => 'applications/diffusion/exception/DiffusionSetupException.php',
     'DiffusionSubversionWireProtocol' => 'applications/diffusion/protocol/DiffusionSubversionWireProtocol.php',
     'DiffusionSubversionWireProtocolTestCase' => 'applications/diffusion/protocol/__tests__/DiffusionSubversionWireProtocolTestCase.php',
     'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php',
     'DiffusionSvnRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionSvnRawDiffQuery.php',
     'DiffusionSvnRequest' => 'applications/diffusion/request/DiffusionSvnRequest.php',
     'DiffusionSymbolController' => 'applications/diffusion/controller/DiffusionSymbolController.php',
     'DiffusionSymbolDatasource' => 'applications/diffusion/typeahead/DiffusionSymbolDatasource.php',
     'DiffusionSymbolQuery' => 'applications/diffusion/query/DiffusionSymbolQuery.php',
     'DiffusionTagListController' => 'applications/diffusion/controller/DiffusionTagListController.php',
     'DiffusionTagListView' => 'applications/diffusion/view/DiffusionTagListView.php',
     'DiffusionTagsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionTagsQueryConduitAPIMethod.php',
     'DiffusionURITestCase' => 'applications/diffusion/request/__tests__/DiffusionURITestCase.php',
     'DiffusionUpdateCoverageConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionUpdateCoverageConduitAPIMethod.php',
     'DiffusionView' => 'applications/diffusion/view/DiffusionView.php',
     'DivinerArticleAtomizer' => 'applications/diviner/atomizer/DivinerArticleAtomizer.php',
     'DivinerAtom' => 'applications/diviner/atom/DivinerAtom.php',
     'DivinerAtomCache' => 'applications/diviner/cache/DivinerAtomCache.php',
     'DivinerAtomController' => 'applications/diviner/controller/DivinerAtomController.php',
     'DivinerAtomListController' => 'applications/diviner/controller/DivinerAtomListController.php',
     'DivinerAtomPHIDType' => 'applications/diviner/phid/DivinerAtomPHIDType.php',
     'DivinerAtomQuery' => 'applications/diviner/query/DivinerAtomQuery.php',
     'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php',
     'DivinerAtomSearchEngine' => 'applications/diviner/query/DivinerAtomSearchEngine.php',
     'DivinerAtomizeWorkflow' => 'applications/diviner/workflow/DivinerAtomizeWorkflow.php',
     'DivinerAtomizer' => 'applications/diviner/atomizer/DivinerAtomizer.php',
     'DivinerBookController' => 'applications/diviner/controller/DivinerBookController.php',
     'DivinerBookItemView' => 'applications/diviner/view/DivinerBookItemView.php',
     'DivinerBookPHIDType' => 'applications/diviner/phid/DivinerBookPHIDType.php',
     'DivinerBookQuery' => 'applications/diviner/query/DivinerBookQuery.php',
     'DivinerController' => 'applications/diviner/controller/DivinerController.php',
     'DivinerDAO' => 'applications/diviner/storage/DivinerDAO.php',
     'DivinerDefaultRenderer' => 'applications/diviner/renderer/DivinerDefaultRenderer.php',
     'DivinerDiskCache' => 'applications/diviner/cache/DivinerDiskCache.php',
     'DivinerFileAtomizer' => 'applications/diviner/atomizer/DivinerFileAtomizer.php',
     'DivinerFindController' => 'applications/diviner/controller/DivinerFindController.php',
     'DivinerGenerateWorkflow' => 'applications/diviner/workflow/DivinerGenerateWorkflow.php',
     'DivinerLiveAtom' => 'applications/diviner/storage/DivinerLiveAtom.php',
     'DivinerLiveBook' => 'applications/diviner/storage/DivinerLiveBook.php',
     'DivinerLivePublisher' => 'applications/diviner/publisher/DivinerLivePublisher.php',
     'DivinerLiveSymbol' => 'applications/diviner/storage/DivinerLiveSymbol.php',
     'DivinerMainController' => 'applications/diviner/controller/DivinerMainController.php',
     'DivinerPHPAtomizer' => 'applications/diviner/atomizer/DivinerPHPAtomizer.php',
     'DivinerParameterTableView' => 'applications/diviner/view/DivinerParameterTableView.php',
     'DivinerPublishCache' => 'applications/diviner/cache/DivinerPublishCache.php',
     'DivinerPublisher' => 'applications/diviner/publisher/DivinerPublisher.php',
     'DivinerRenderer' => 'applications/diviner/renderer/DivinerRenderer.php',
     'DivinerReturnTableView' => 'applications/diviner/view/DivinerReturnTableView.php',
     'DivinerSectionView' => 'applications/diviner/view/DivinerSectionView.php',
     'DivinerStaticPublisher' => 'applications/diviner/publisher/DivinerStaticPublisher.php',
     'DivinerSymbolRemarkupRule' => 'applications/diviner/markup/DivinerSymbolRemarkupRule.php',
     'DivinerWorkflow' => 'applications/diviner/workflow/DivinerWorkflow.php',
     'DoorkeeperBridge' => 'applications/doorkeeper/bridge/DoorkeeperBridge.php',
     'DoorkeeperBridgeAsana' => 'applications/doorkeeper/bridge/DoorkeeperBridgeAsana.php',
     'DoorkeeperBridgeJIRA' => 'applications/doorkeeper/bridge/DoorkeeperBridgeJIRA.php',
     'DoorkeeperBridgeJIRATestCase' => 'applications/doorkeeper/bridge/__tests__/DoorkeeperBridgeJIRATestCase.php',
     'DoorkeeperDAO' => 'applications/doorkeeper/storage/DoorkeeperDAO.php',
     'DoorkeeperExternalObject' => 'applications/doorkeeper/storage/DoorkeeperExternalObject.php',
     'DoorkeeperExternalObjectQuery' => 'applications/doorkeeper/query/DoorkeeperExternalObjectQuery.php',
     'DoorkeeperFeedStoryPublisher' => 'applications/doorkeeper/engine/DoorkeeperFeedStoryPublisher.php',
     'DoorkeeperFeedWorker' => 'applications/doorkeeper/worker/DoorkeeperFeedWorker.php',
     'DoorkeeperFeedWorkerAsana' => 'applications/doorkeeper/worker/DoorkeeperFeedWorkerAsana.php',
     'DoorkeeperFeedWorkerJIRA' => 'applications/doorkeeper/worker/DoorkeeperFeedWorkerJIRA.php',
     'DoorkeeperImportEngine' => 'applications/doorkeeper/engine/DoorkeeperImportEngine.php',
     'DoorkeeperMissingLinkException' => 'applications/doorkeeper/exception/DoorkeeperMissingLinkException.php',
     'DoorkeeperObjectRef' => 'applications/doorkeeper/engine/DoorkeeperObjectRef.php',
     'DoorkeeperRemarkupRule' => 'applications/doorkeeper/remarkup/DoorkeeperRemarkupRule.php',
     'DoorkeeperRemarkupRuleAsana' => 'applications/doorkeeper/remarkup/DoorkeeperRemarkupRuleAsana.php',
     'DoorkeeperRemarkupRuleJIRA' => 'applications/doorkeeper/remarkup/DoorkeeperRemarkupRuleJIRA.php',
     'DoorkeeperSchemaSpec' => 'applications/doorkeeper/storage/DoorkeeperSchemaSpec.php',
     'DoorkeeperTagView' => 'applications/doorkeeper/view/DoorkeeperTagView.php',
     'DoorkeeperTagsController' => 'applications/doorkeeper/controller/DoorkeeperTagsController.php',
     'DrydockAllocatorWorker' => 'applications/drydock/worker/DrydockAllocatorWorker.php',
     'DrydockApacheWebrootInterface' => 'applications/drydock/interface/webroot/DrydockApacheWebrootInterface.php',
     'DrydockBlueprint' => 'applications/drydock/storage/DrydockBlueprint.php',
     'DrydockBlueprintController' => 'applications/drydock/controller/DrydockBlueprintController.php',
     'DrydockBlueprintCoreCustomField' => 'applications/drydock/customfield/DrydockBlueprintCoreCustomField.php',
     'DrydockBlueprintCreateController' => 'applications/drydock/controller/DrydockBlueprintCreateController.php',
     'DrydockBlueprintCustomField' => 'applications/drydock/customfield/DrydockBlueprintCustomField.php',
     'DrydockBlueprintEditController' => 'applications/drydock/controller/DrydockBlueprintEditController.php',
     'DrydockBlueprintEditor' => 'applications/drydock/editor/DrydockBlueprintEditor.php',
     'DrydockBlueprintImplementation' => 'applications/drydock/blueprint/DrydockBlueprintImplementation.php',
     'DrydockBlueprintListController' => 'applications/drydock/controller/DrydockBlueprintListController.php',
     'DrydockBlueprintPHIDType' => 'applications/drydock/phid/DrydockBlueprintPHIDType.php',
     'DrydockBlueprintQuery' => 'applications/drydock/query/DrydockBlueprintQuery.php',
     'DrydockBlueprintScopeGuard' => 'applications/drydock/util/DrydockBlueprintScopeGuard.php',
     'DrydockBlueprintSearchEngine' => 'applications/drydock/query/DrydockBlueprintSearchEngine.php',
     'DrydockBlueprintTransaction' => 'applications/drydock/storage/DrydockBlueprintTransaction.php',
     'DrydockBlueprintTransactionQuery' => 'applications/drydock/query/DrydockBlueprintTransactionQuery.php',
     'DrydockBlueprintViewController' => 'applications/drydock/controller/DrydockBlueprintViewController.php',
     'DrydockCommandInterface' => 'applications/drydock/interface/command/DrydockCommandInterface.php',
     'DrydockConsoleController' => 'applications/drydock/controller/DrydockConsoleController.php',
     'DrydockConstants' => 'applications/drydock/constants/DrydockConstants.php',
     'DrydockController' => 'applications/drydock/controller/DrydockController.php',
     'DrydockCreateBlueprintsCapability' => 'applications/drydock/capability/DrydockCreateBlueprintsCapability.php',
     'DrydockDAO' => 'applications/drydock/storage/DrydockDAO.php',
     'DrydockDefaultEditCapability' => 'applications/drydock/capability/DrydockDefaultEditCapability.php',
     'DrydockDefaultViewCapability' => 'applications/drydock/capability/DrydockDefaultViewCapability.php',
     'DrydockFilesystemInterface' => 'applications/drydock/interface/filesystem/DrydockFilesystemInterface.php',
     'DrydockInterface' => 'applications/drydock/interface/DrydockInterface.php',
     'DrydockLease' => 'applications/drydock/storage/DrydockLease.php',
     'DrydockLeaseController' => 'applications/drydock/controller/DrydockLeaseController.php',
     'DrydockLeaseListController' => 'applications/drydock/controller/DrydockLeaseListController.php',
     'DrydockLeaseListView' => 'applications/drydock/view/DrydockLeaseListView.php',
     'DrydockLeasePHIDType' => 'applications/drydock/phid/DrydockLeasePHIDType.php',
     'DrydockLeaseQuery' => 'applications/drydock/query/DrydockLeaseQuery.php',
     'DrydockLeaseReleaseController' => 'applications/drydock/controller/DrydockLeaseReleaseController.php',
     'DrydockLeaseSearchEngine' => 'applications/drydock/query/DrydockLeaseSearchEngine.php',
     'DrydockLeaseStatus' => 'applications/drydock/constants/DrydockLeaseStatus.php',
     'DrydockLeaseViewController' => 'applications/drydock/controller/DrydockLeaseViewController.php',
     'DrydockLocalCommandInterface' => 'applications/drydock/interface/command/DrydockLocalCommandInterface.php',
     'DrydockLog' => 'applications/drydock/storage/DrydockLog.php',
     'DrydockLogController' => 'applications/drydock/controller/DrydockLogController.php',
     'DrydockLogListController' => 'applications/drydock/controller/DrydockLogListController.php',
     'DrydockLogListView' => 'applications/drydock/view/DrydockLogListView.php',
     'DrydockLogQuery' => 'applications/drydock/query/DrydockLogQuery.php',
     'DrydockLogSearchEngine' => 'applications/drydock/query/DrydockLogSearchEngine.php',
     'DrydockManagementCloseWorkflow' => 'applications/drydock/management/DrydockManagementCloseWorkflow.php',
     'DrydockManagementCreateResourceWorkflow' => 'applications/drydock/management/DrydockManagementCreateResourceWorkflow.php',
     'DrydockManagementLeaseWorkflow' => 'applications/drydock/management/DrydockManagementLeaseWorkflow.php',
     'DrydockManagementReleaseWorkflow' => 'applications/drydock/management/DrydockManagementReleaseWorkflow.php',
     'DrydockManagementWorkflow' => 'applications/drydock/management/DrydockManagementWorkflow.php',
     'DrydockPreallocatedHostBlueprintImplementation' => 'applications/drydock/blueprint/DrydockPreallocatedHostBlueprintImplementation.php',
     'DrydockQuery' => 'applications/drydock/query/DrydockQuery.php',
     'DrydockResource' => 'applications/drydock/storage/DrydockResource.php',
     'DrydockResourceCloseController' => 'applications/drydock/controller/DrydockResourceCloseController.php',
     'DrydockResourceController' => 'applications/drydock/controller/DrydockResourceController.php',
     'DrydockResourceListController' => 'applications/drydock/controller/DrydockResourceListController.php',
     'DrydockResourceListView' => 'applications/drydock/view/DrydockResourceListView.php',
     'DrydockResourcePHIDType' => 'applications/drydock/phid/DrydockResourcePHIDType.php',
     'DrydockResourceQuery' => 'applications/drydock/query/DrydockResourceQuery.php',
     'DrydockResourceSearchEngine' => 'applications/drydock/query/DrydockResourceSearchEngine.php',
     'DrydockResourceStatus' => 'applications/drydock/constants/DrydockResourceStatus.php',
     'DrydockResourceViewController' => 'applications/drydock/controller/DrydockResourceViewController.php',
     'DrydockSFTPFilesystemInterface' => 'applications/drydock/interface/filesystem/DrydockSFTPFilesystemInterface.php',
     'DrydockSSHCommandInterface' => 'applications/drydock/interface/command/DrydockSSHCommandInterface.php',
     'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/DrydockWebrootInterface.php',
     'DrydockWorkingCopyBlueprintImplementation' => 'applications/drydock/blueprint/DrydockWorkingCopyBlueprintImplementation.php',
     'FeedConduitAPIMethod' => 'applications/feed/conduit/FeedConduitAPIMethod.php',
     'FeedPublishConduitAPIMethod' => 'applications/feed/conduit/FeedPublishConduitAPIMethod.php',
     'FeedPublisherHTTPWorker' => 'applications/feed/worker/FeedPublisherHTTPWorker.php',
     'FeedPublisherWorker' => 'applications/feed/worker/FeedPublisherWorker.php',
     'FeedPushWorker' => 'applications/feed/worker/FeedPushWorker.php',
     'FeedQueryConduitAPIMethod' => 'applications/feed/conduit/FeedQueryConduitAPIMethod.php',
     'FileConduitAPIMethod' => 'applications/files/conduit/FileConduitAPIMethod.php',
     'FileCreateMailReceiver' => 'applications/files/mail/FileCreateMailReceiver.php',
     'FileDownloadConduitAPIMethod' => 'applications/files/conduit/FileDownloadConduitAPIMethod.php',
     'FileInfoConduitAPIMethod' => 'applications/files/conduit/FileInfoConduitAPIMethod.php',
     'FileMailReceiver' => 'applications/files/mail/FileMailReceiver.php',
     'FileReplyHandler' => 'applications/files/mail/FileReplyHandler.php',
     'FileUploadConduitAPIMethod' => 'applications/files/conduit/FileUploadConduitAPIMethod.php',
     'FileUploadHashConduitAPIMethod' => 'applications/files/conduit/FileUploadHashConduitAPIMethod.php',
     'FilesDefaultViewCapability' => 'applications/files/capability/FilesDefaultViewCapability.php',
     'FlagConduitAPIMethod' => 'applications/flag/conduit/FlagConduitAPIMethod.php',
     'FlagDeleteConduitAPIMethod' => 'applications/flag/conduit/FlagDeleteConduitAPIMethod.php',
     'FlagEditConduitAPIMethod' => 'applications/flag/conduit/FlagEditConduitAPIMethod.php',
     'FlagQueryConduitAPIMethod' => 'applications/flag/conduit/FlagQueryConduitAPIMethod.php',
     'FundBacker' => 'applications/fund/storage/FundBacker.php',
     'FundBackerCart' => 'applications/fund/phortune/FundBackerCart.php',
     'FundBackerEditor' => 'applications/fund/editor/FundBackerEditor.php',
     'FundBackerListController' => 'applications/fund/controller/FundBackerListController.php',
     'FundBackerPHIDType' => 'applications/fund/phid/FundBackerPHIDType.php',
     'FundBackerProduct' => 'applications/fund/phortune/FundBackerProduct.php',
     'FundBackerQuery' => 'applications/fund/query/FundBackerQuery.php',
     'FundBackerSearchEngine' => 'applications/fund/query/FundBackerSearchEngine.php',
     'FundBackerTransaction' => 'applications/fund/storage/FundBackerTransaction.php',
     'FundBackerTransactionQuery' => 'applications/fund/query/FundBackerTransactionQuery.php',
     'FundController' => 'applications/fund/controller/FundController.php',
     'FundCreateInitiativesCapability' => 'applications/fund/capability/FundCreateInitiativesCapability.php',
     'FundDAO' => 'applications/fund/storage/FundDAO.php',
     'FundDefaultViewCapability' => 'applications/fund/capability/FundDefaultViewCapability.php',
     'FundInitiative' => 'applications/fund/storage/FundInitiative.php',
     'FundInitiativeBackController' => 'applications/fund/controller/FundInitiativeBackController.php',
     'FundInitiativeCloseController' => 'applications/fund/controller/FundInitiativeCloseController.php',
     'FundInitiativeEditController' => 'applications/fund/controller/FundInitiativeEditController.php',
     'FundInitiativeEditor' => 'applications/fund/editor/FundInitiativeEditor.php',
     'FundInitiativeIndexer' => 'applications/fund/search/FundInitiativeIndexer.php',
     'FundInitiativeListController' => 'applications/fund/controller/FundInitiativeListController.php',
     'FundInitiativePHIDType' => 'applications/fund/phid/FundInitiativePHIDType.php',
     'FundInitiativeQuery' => 'applications/fund/query/FundInitiativeQuery.php',
     'FundInitiativeRemarkupRule' => 'applications/fund/remarkup/FundInitiativeRemarkupRule.php',
     'FundInitiativeReplyHandler' => 'applications/fund/mail/FundInitiativeReplyHandler.php',
     'FundInitiativeSearchEngine' => 'applications/fund/query/FundInitiativeSearchEngine.php',
     'FundInitiativeTransaction' => 'applications/fund/storage/FundInitiativeTransaction.php',
     'FundInitiativeTransactionQuery' => 'applications/fund/query/FundInitiativeTransactionQuery.php',
     'FundInitiativeViewController' => 'applications/fund/controller/FundInitiativeViewController.php',
     'FundSchemaSpec' => 'applications/fund/storage/FundSchemaSpec.php',
     'HarbormasterBuild' => 'applications/harbormaster/storage/build/HarbormasterBuild.php',
     'HarbormasterBuildAbortedException' => 'applications/harbormaster/exception/HarbormasterBuildAbortedException.php',
     'HarbormasterBuildActionController' => 'applications/harbormaster/controller/HarbormasterBuildActionController.php',
     'HarbormasterBuildArtifact' => 'applications/harbormaster/storage/build/HarbormasterBuildArtifact.php',
     'HarbormasterBuildArtifactQuery' => 'applications/harbormaster/query/HarbormasterBuildArtifactQuery.php',
     'HarbormasterBuildCommand' => 'applications/harbormaster/storage/HarbormasterBuildCommand.php',
     'HarbormasterBuildDependencyDatasource' => 'applications/harbormaster/typeahead/HarbormasterBuildDependencyDatasource.php',
     'HarbormasterBuildEngine' => 'applications/harbormaster/engine/HarbormasterBuildEngine.php',
     'HarbormasterBuildFailureException' => 'applications/harbormaster/exception/HarbormasterBuildFailureException.php',
     'HarbormasterBuildGraph' => 'applications/harbormaster/engine/HarbormasterBuildGraph.php',
     'HarbormasterBuildItem' => 'applications/harbormaster/storage/build/HarbormasterBuildItem.php',
     'HarbormasterBuildItemPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildItemPHIDType.php',
     'HarbormasterBuildItemQuery' => 'applications/harbormaster/query/HarbormasterBuildItemQuery.php',
     'HarbormasterBuildLog' => 'applications/harbormaster/storage/build/HarbormasterBuildLog.php',
     'HarbormasterBuildLogPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildLogPHIDType.php',
     'HarbormasterBuildLogQuery' => 'applications/harbormaster/query/HarbormasterBuildLogQuery.php',
     'HarbormasterBuildMessage' => 'applications/harbormaster/storage/HarbormasterBuildMessage.php',
     'HarbormasterBuildMessageQuery' => 'applications/harbormaster/query/HarbormasterBuildMessageQuery.php',
     'HarbormasterBuildPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildPHIDType.php',
     'HarbormasterBuildPlan' => 'applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php',
     'HarbormasterBuildPlanDatasource' => 'applications/harbormaster/typeahead/HarbormasterBuildPlanDatasource.php',
     'HarbormasterBuildPlanEditor' => 'applications/harbormaster/editor/HarbormasterBuildPlanEditor.php',
     'HarbormasterBuildPlanPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildPlanPHIDType.php',
     'HarbormasterBuildPlanQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanQuery.php',
     'HarbormasterBuildPlanSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildPlanSearchEngine.php',
     'HarbormasterBuildPlanTransaction' => 'applications/harbormaster/storage/configuration/HarbormasterBuildPlanTransaction.php',
     'HarbormasterBuildPlanTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildPlanTransactionQuery.php',
     'HarbormasterBuildQuery' => 'applications/harbormaster/query/HarbormasterBuildQuery.php',
     'HarbormasterBuildStep' => 'applications/harbormaster/storage/configuration/HarbormasterBuildStep.php',
     'HarbormasterBuildStepCoreCustomField' => 'applications/harbormaster/customfield/HarbormasterBuildStepCoreCustomField.php',
     'HarbormasterBuildStepCustomField' => 'applications/harbormaster/customfield/HarbormasterBuildStepCustomField.php',
     'HarbormasterBuildStepEditor' => 'applications/harbormaster/editor/HarbormasterBuildStepEditor.php',
     'HarbormasterBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterBuildStepImplementation.php',
     'HarbormasterBuildStepPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildStepPHIDType.php',
     'HarbormasterBuildStepQuery' => 'applications/harbormaster/query/HarbormasterBuildStepQuery.php',
     'HarbormasterBuildStepTransaction' => 'applications/harbormaster/storage/configuration/HarbormasterBuildStepTransaction.php',
     'HarbormasterBuildStepTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildStepTransactionQuery.php',
     'HarbormasterBuildTarget' => 'applications/harbormaster/storage/build/HarbormasterBuildTarget.php',
     'HarbormasterBuildTargetPHIDType' => 'applications/harbormaster/phid/HarbormasterBuildTargetPHIDType.php',
     'HarbormasterBuildTargetQuery' => 'applications/harbormaster/query/HarbormasterBuildTargetQuery.php',
     'HarbormasterBuildTransaction' => 'applications/harbormaster/storage/HarbormasterBuildTransaction.php',
     'HarbormasterBuildTransactionEditor' => 'applications/harbormaster/editor/HarbormasterBuildTransactionEditor.php',
     'HarbormasterBuildTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildTransactionQuery.php',
     'HarbormasterBuildViewController' => 'applications/harbormaster/controller/HarbormasterBuildViewController.php',
     'HarbormasterBuildWorker' => 'applications/harbormaster/worker/HarbormasterBuildWorker.php',
     'HarbormasterBuildable' => 'applications/harbormaster/storage/HarbormasterBuildable.php',
     'HarbormasterBuildableActionController' => 'applications/harbormaster/controller/HarbormasterBuildableActionController.php',
     'HarbormasterBuildableInterface' => 'applications/harbormaster/interface/HarbormasterBuildableInterface.php',
     'HarbormasterBuildableListController' => 'applications/harbormaster/controller/HarbormasterBuildableListController.php',
     'HarbormasterBuildablePHIDType' => 'applications/harbormaster/phid/HarbormasterBuildablePHIDType.php',
     'HarbormasterBuildableQuery' => 'applications/harbormaster/query/HarbormasterBuildableQuery.php',
     'HarbormasterBuildableSearchEngine' => 'applications/harbormaster/query/HarbormasterBuildableSearchEngine.php',
     'HarbormasterBuildableTransaction' => 'applications/harbormaster/storage/HarbormasterBuildableTransaction.php',
     'HarbormasterBuildableTransactionEditor' => 'applications/harbormaster/editor/HarbormasterBuildableTransactionEditor.php',
     'HarbormasterBuildableTransactionQuery' => 'applications/harbormaster/query/HarbormasterBuildableTransactionQuery.php',
     'HarbormasterBuildableViewController' => 'applications/harbormaster/controller/HarbormasterBuildableViewController.php',
     'HarbormasterCommandBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterCommandBuildStepImplementation.php',
     'HarbormasterConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterConduitAPIMethod.php',
     'HarbormasterController' => 'applications/harbormaster/controller/HarbormasterController.php',
     'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php',
     'HarbormasterHTTPRequestBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterHTTPRequestBuildStepImplementation.php',
     'HarbormasterLeaseHostBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterLeaseHostBuildStepImplementation.php',
     'HarbormasterManagePlansCapability' => 'applications/harbormaster/capability/HarbormasterManagePlansCapability.php',
     'HarbormasterManagementBuildWorkflow' => 'applications/harbormaster/management/HarbormasterManagementBuildWorkflow.php',
     'HarbormasterManagementUpdateWorkflow' => 'applications/harbormaster/management/HarbormasterManagementUpdateWorkflow.php',
     'HarbormasterManagementWorkflow' => 'applications/harbormaster/management/HarbormasterManagementWorkflow.php',
     'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php',
     'HarbormasterPlanController' => 'applications/harbormaster/controller/HarbormasterPlanController.php',
     'HarbormasterPlanDisableController' => 'applications/harbormaster/controller/HarbormasterPlanDisableController.php',
     'HarbormasterPlanEditController' => 'applications/harbormaster/controller/HarbormasterPlanEditController.php',
     'HarbormasterPlanListController' => 'applications/harbormaster/controller/HarbormasterPlanListController.php',
     'HarbormasterPlanRunController' => 'applications/harbormaster/controller/HarbormasterPlanRunController.php',
     'HarbormasterPlanViewController' => 'applications/harbormaster/controller/HarbormasterPlanViewController.php',
     'HarbormasterPublishFragmentBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterPublishFragmentBuildStepImplementation.php',
     'HarbormasterQueryBuildablesConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterQueryBuildablesConduitAPIMethod.php',
     'HarbormasterQueryBuildsConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterQueryBuildsConduitAPIMethod.php',
     'HarbormasterRemarkupRule' => 'applications/harbormaster/remarkup/HarbormasterRemarkupRule.php',
     'HarbormasterSchemaSpec' => 'applications/harbormaster/storage/HarbormasterSchemaSpec.php',
     'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
     'HarbormasterSendMessageConduitAPIMethod' => 'applications/harbormaster/conduit/HarbormasterSendMessageConduitAPIMethod.php',
     'HarbormasterSleepBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterSleepBuildStepImplementation.php',
     'HarbormasterStepAddController' => 'applications/harbormaster/controller/HarbormasterStepAddController.php',
     'HarbormasterStepDeleteController' => 'applications/harbormaster/controller/HarbormasterStepDeleteController.php',
     'HarbormasterStepEditController' => 'applications/harbormaster/controller/HarbormasterStepEditController.php',
     'HarbormasterTargetWorker' => 'applications/harbormaster/worker/HarbormasterTargetWorker.php',
     'HarbormasterThrowExceptionBuildStep' => 'applications/harbormaster/step/HarbormasterThrowExceptionBuildStep.php',
     'HarbormasterUIEventListener' => 'applications/harbormaster/event/HarbormasterUIEventListener.php',
     'HarbormasterUploadArtifactBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterUploadArtifactBuildStepImplementation.php',
     'HarbormasterWaitForPreviousBuildStepImplementation' => 'applications/harbormaster/step/HarbormasterWaitForPreviousBuildStepImplementation.php',
     'HarbormasterWorker' => 'applications/harbormaster/worker/HarbormasterWorker.php',
     'HeraldAction' => 'applications/herald/storage/HeraldAction.php',
     'HeraldAdapter' => 'applications/herald/adapter/HeraldAdapter.php',
     'HeraldApplyTranscript' => 'applications/herald/storage/transcript/HeraldApplyTranscript.php',
     'HeraldCommitAdapter' => 'applications/herald/adapter/HeraldCommitAdapter.php',
     'HeraldCondition' => 'applications/herald/storage/HeraldCondition.php',
     'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
     'HeraldController' => 'applications/herald/controller/HeraldController.php',
     'HeraldCustomAction' => 'applications/herald/extension/HeraldCustomAction.php',
     'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
     'HeraldDifferentialAdapter' => 'applications/herald/adapter/HeraldDifferentialAdapter.php',
     'HeraldDifferentialDiffAdapter' => 'applications/herald/adapter/HeraldDifferentialDiffAdapter.php',
     'HeraldDifferentialRevisionAdapter' => 'applications/herald/adapter/HeraldDifferentialRevisionAdapter.php',
     'HeraldDisableController' => 'applications/herald/controller/HeraldDisableController.php',
     'HeraldEditLogQuery' => 'applications/herald/query/HeraldEditLogQuery.php',
     'HeraldEffect' => 'applications/herald/engine/HeraldEffect.php',
     'HeraldEngine' => 'applications/herald/engine/HeraldEngine.php',
     'HeraldInvalidActionException' => 'applications/herald/engine/exception/HeraldInvalidActionException.php',
     'HeraldInvalidConditionException' => 'applications/herald/engine/exception/HeraldInvalidConditionException.php',
     'HeraldInvalidFieldException' => 'applications/herald/engine/exception/HeraldInvalidFieldException.php',
     'HeraldManageGlobalRulesCapability' => 'applications/herald/capability/HeraldManageGlobalRulesCapability.php',
     'HeraldManiphestTaskAdapter' => 'applications/herald/adapter/HeraldManiphestTaskAdapter.php',
     'HeraldNewController' => 'applications/herald/controller/HeraldNewController.php',
     'HeraldObjectTranscript' => 'applications/herald/storage/transcript/HeraldObjectTranscript.php',
     'HeraldPholioMockAdapter' => 'applications/herald/adapter/HeraldPholioMockAdapter.php',
     'HeraldPreCommitAdapter' => 'applications/diffusion/herald/HeraldPreCommitAdapter.php',
     'HeraldPreCommitContentAdapter' => 'applications/diffusion/herald/HeraldPreCommitContentAdapter.php',
     'HeraldPreCommitRefAdapter' => 'applications/diffusion/herald/HeraldPreCommitRefAdapter.php',
     'HeraldRecursiveConditionsException' => 'applications/herald/engine/exception/HeraldRecursiveConditionsException.php',
     'HeraldRemarkupRule' => 'applications/herald/remarkup/HeraldRemarkupRule.php',
     'HeraldRepetitionPolicyConfig' => 'applications/herald/config/HeraldRepetitionPolicyConfig.php',
     'HeraldRule' => 'applications/herald/storage/HeraldRule.php',
     'HeraldRuleController' => 'applications/herald/controller/HeraldRuleController.php',
     'HeraldRuleEdit' => 'applications/herald/storage/HeraldRuleEdit.php',
     'HeraldRuleEditHistoryController' => 'applications/herald/controller/HeraldRuleEditHistoryController.php',
     'HeraldRuleEditHistoryView' => 'applications/herald/view/HeraldRuleEditHistoryView.php',
     'HeraldRuleEditor' => 'applications/herald/editor/HeraldRuleEditor.php',
     'HeraldRuleListController' => 'applications/herald/controller/HeraldRuleListController.php',
     'HeraldRulePHIDType' => 'applications/herald/phid/HeraldRulePHIDType.php',
     'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php',
     'HeraldRuleSearchEngine' => 'applications/herald/query/HeraldRuleSearchEngine.php',
     'HeraldRuleTestCase' => 'applications/herald/storage/__tests__/HeraldRuleTestCase.php',
     'HeraldRuleTransaction' => 'applications/herald/storage/HeraldRuleTransaction.php',
     'HeraldRuleTransactionComment' => 'applications/herald/storage/HeraldRuleTransactionComment.php',
     'HeraldRuleTranscript' => 'applications/herald/storage/transcript/HeraldRuleTranscript.php',
     'HeraldRuleTypeConfig' => 'applications/herald/config/HeraldRuleTypeConfig.php',
     'HeraldRuleViewController' => 'applications/herald/controller/HeraldRuleViewController.php',
     'HeraldSchemaSpec' => 'applications/herald/storage/HeraldSchemaSpec.php',
     'HeraldTestConsoleController' => 'applications/herald/controller/HeraldTestConsoleController.php',
     'HeraldTransactionQuery' => 'applications/herald/query/HeraldTransactionQuery.php',
     'HeraldTranscript' => 'applications/herald/storage/transcript/HeraldTranscript.php',
     'HeraldTranscriptController' => 'applications/herald/controller/HeraldTranscriptController.php',
     'HeraldTranscriptGarbageCollector' => 'applications/herald/garbagecollector/HeraldTranscriptGarbageCollector.php',
     'HeraldTranscriptListController' => 'applications/herald/controller/HeraldTranscriptListController.php',
     'HeraldTranscriptQuery' => 'applications/herald/query/HeraldTranscriptQuery.php',
     'HeraldTranscriptSearchEngine' => 'applications/herald/query/HeraldTranscriptSearchEngine.php',
     'HeraldTranscriptTestCase' => 'applications/herald/storage/__tests__/HeraldTranscriptTestCase.php',
     'Javelin' => 'infrastructure/javelin/Javelin.php',
     'JavelinReactorExample' => 'applications/uiexample/examples/JavelinReactorExample.php',
     'JavelinUIExample' => 'applications/uiexample/examples/JavelinUIExample.php',
     'JavelinViewExample' => 'applications/uiexample/examples/JavelinViewExample.php',
     'JavelinViewExampleServerView' => 'applications/uiexample/examples/JavelinViewExampleServerView.php',
     'LegalpadConstants' => 'applications/legalpad/constants/LegalpadConstants.php',
     'LegalpadController' => 'applications/legalpad/controller/LegalpadController.php',
     'LegalpadCreateDocumentsCapability' => 'applications/legalpad/capability/LegalpadCreateDocumentsCapability.php',
     'LegalpadDAO' => 'applications/legalpad/storage/LegalpadDAO.php',
     'LegalpadDefaultEditCapability' => 'applications/legalpad/capability/LegalpadDefaultEditCapability.php',
     'LegalpadDefaultViewCapability' => 'applications/legalpad/capability/LegalpadDefaultViewCapability.php',
     'LegalpadDocument' => 'applications/legalpad/storage/LegalpadDocument.php',
     'LegalpadDocumentBody' => 'applications/legalpad/storage/LegalpadDocumentBody.php',
     'LegalpadDocumentCommentController' => 'applications/legalpad/controller/LegalpadDocumentCommentController.php',
     'LegalpadDocumentDatasource' => 'applications/legalpad/typeahead/LegalpadDocumentDatasource.php',
     'LegalpadDocumentDoneController' => 'applications/legalpad/controller/LegalpadDocumentDoneController.php',
     'LegalpadDocumentEditController' => 'applications/legalpad/controller/LegalpadDocumentEditController.php',
     'LegalpadDocumentEditor' => 'applications/legalpad/editor/LegalpadDocumentEditor.php',
     'LegalpadDocumentListController' => 'applications/legalpad/controller/LegalpadDocumentListController.php',
     'LegalpadDocumentManageController' => 'applications/legalpad/controller/LegalpadDocumentManageController.php',
     'LegalpadDocumentQuery' => 'applications/legalpad/query/LegalpadDocumentQuery.php',
     'LegalpadDocumentRemarkupRule' => 'applications/legalpad/remarkup/LegalpadDocumentRemarkupRule.php',
     'LegalpadDocumentSearchEngine' => 'applications/legalpad/query/LegalpadDocumentSearchEngine.php',
     'LegalpadDocumentSignController' => 'applications/legalpad/controller/LegalpadDocumentSignController.php',
     'LegalpadDocumentSignature' => 'applications/legalpad/storage/LegalpadDocumentSignature.php',
     'LegalpadDocumentSignatureAddController' => 'applications/legalpad/controller/LegalpadDocumentSignatureAddController.php',
     'LegalpadDocumentSignatureListController' => 'applications/legalpad/controller/LegalpadDocumentSignatureListController.php',
     'LegalpadDocumentSignatureQuery' => 'applications/legalpad/query/LegalpadDocumentSignatureQuery.php',
     'LegalpadDocumentSignatureSearchEngine' => 'applications/legalpad/query/LegalpadDocumentSignatureSearchEngine.php',
     'LegalpadDocumentSignatureVerificationController' => 'applications/legalpad/controller/LegalpadDocumentSignatureVerificationController.php',
     'LegalpadDocumentSignatureViewController' => 'applications/legalpad/controller/LegalpadDocumentSignatureViewController.php',
     'LegalpadMockMailReceiver' => 'applications/legalpad/mail/LegalpadMockMailReceiver.php',
     'LegalpadReplyHandler' => 'applications/legalpad/mail/LegalpadReplyHandler.php',
     'LegalpadSchemaSpec' => 'applications/legalpad/storage/LegalpadSchemaSpec.php',
     'LegalpadTransaction' => 'applications/legalpad/storage/LegalpadTransaction.php',
     'LegalpadTransactionComment' => 'applications/legalpad/storage/LegalpadTransactionComment.php',
     'LegalpadTransactionQuery' => 'applications/legalpad/query/LegalpadTransactionQuery.php',
     'LegalpadTransactionType' => 'applications/legalpad/constants/LegalpadTransactionType.php',
     'LegalpadTransactionView' => 'applications/legalpad/view/LegalpadTransactionView.php',
     'LiskChunkTestCase' => 'infrastructure/storage/lisk/__tests__/LiskChunkTestCase.php',
     'LiskDAO' => 'infrastructure/storage/lisk/LiskDAO.php',
     'LiskDAOSet' => 'infrastructure/storage/lisk/LiskDAOSet.php',
     'LiskDAOTestCase' => 'infrastructure/storage/lisk/__tests__/LiskDAOTestCase.php',
     'LiskEphemeralObjectException' => 'infrastructure/storage/lisk/LiskEphemeralObjectException.php',
     'LiskFixtureTestCase' => 'infrastructure/storage/lisk/__tests__/LiskFixtureTestCase.php',
     'LiskIsolationTestCase' => 'infrastructure/storage/lisk/__tests__/LiskIsolationTestCase.php',
     'LiskIsolationTestDAO' => 'infrastructure/storage/lisk/__tests__/LiskIsolationTestDAO.php',
     'LiskIsolationTestDAOException' => 'infrastructure/storage/lisk/__tests__/LiskIsolationTestDAOException.php',
     'LiskMigrationIterator' => 'infrastructure/storage/lisk/LiskMigrationIterator.php',
     'LiskRawMigrationIterator' => 'infrastructure/storage/lisk/LiskRawMigrationIterator.php',
     'MacroConduitAPIMethod' => 'applications/macro/conduit/MacroConduitAPIMethod.php',
     'MacroCreateMemeConduitAPIMethod' => 'applications/macro/conduit/MacroCreateMemeConduitAPIMethod.php',
     'MacroQueryConduitAPIMethod' => 'applications/macro/conduit/MacroQueryConduitAPIMethod.php',
     'ManiphestActionMenuEventListener' => 'applications/maniphest/event/ManiphestActionMenuEventListener.php',
     'ManiphestBatchEditController' => 'applications/maniphest/controller/ManiphestBatchEditController.php',
     'ManiphestBulkEditCapability' => 'applications/maniphest/capability/ManiphestBulkEditCapability.php',
     'ManiphestConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestConduitAPIMethod.php',
     'ManiphestConfiguredCustomField' => 'applications/maniphest/field/ManiphestConfiguredCustomField.php',
     'ManiphestConstants' => 'applications/maniphest/constants/ManiphestConstants.php',
     'ManiphestController' => 'applications/maniphest/controller/ManiphestController.php',
     'ManiphestCreateMailReceiver' => 'applications/maniphest/mail/ManiphestCreateMailReceiver.php',
     'ManiphestCreateTaskConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestCreateTaskConduitAPIMethod.php',
     'ManiphestCustomField' => 'applications/maniphest/field/ManiphestCustomField.php',
     'ManiphestCustomFieldNumericIndex' => 'applications/maniphest/storage/ManiphestCustomFieldNumericIndex.php',
     'ManiphestCustomFieldStatusParser' => 'applications/maniphest/field/parser/ManiphestCustomFieldStatusParser.php',
     'ManiphestCustomFieldStatusParserTestCase' => 'applications/maniphest/field/parser/__tests__/ManiphestCustomFieldStatusParserTestCase.php',
     'ManiphestCustomFieldStorage' => 'applications/maniphest/storage/ManiphestCustomFieldStorage.php',
     'ManiphestCustomFieldStringIndex' => 'applications/maniphest/storage/ManiphestCustomFieldStringIndex.php',
     'ManiphestDAO' => 'applications/maniphest/storage/ManiphestDAO.php',
     'ManiphestDefaultEditCapability' => 'applications/maniphest/capability/ManiphestDefaultEditCapability.php',
     'ManiphestDefaultViewCapability' => 'applications/maniphest/capability/ManiphestDefaultViewCapability.php',
     'ManiphestEditAssignCapability' => 'applications/maniphest/capability/ManiphestEditAssignCapability.php',
     'ManiphestEditPoliciesCapability' => 'applications/maniphest/capability/ManiphestEditPoliciesCapability.php',
     'ManiphestEditPriorityCapability' => 'applications/maniphest/capability/ManiphestEditPriorityCapability.php',
     'ManiphestEditProjectsCapability' => 'applications/maniphest/capability/ManiphestEditProjectsCapability.php',
     'ManiphestEditStatusCapability' => 'applications/maniphest/capability/ManiphestEditStatusCapability.php',
     'ManiphestExcelDefaultFormat' => 'applications/maniphest/export/ManiphestExcelDefaultFormat.php',
     'ManiphestExcelFormat' => 'applications/maniphest/export/ManiphestExcelFormat.php',
     'ManiphestExportController' => 'applications/maniphest/controller/ManiphestExportController.php',
     'ManiphestFindConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestFindConduitAPIMethod.php',
     'ManiphestGetTaskTransactionsConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestGetTaskTransactionsConduitAPIMethod.php',
     'ManiphestHovercardEventListener' => 'applications/maniphest/event/ManiphestHovercardEventListener.php',
     'ManiphestInfoConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestInfoConduitAPIMethod.php',
     'ManiphestNameIndex' => 'applications/maniphest/storage/ManiphestNameIndex.php',
     'ManiphestNameIndexEventListener' => 'applications/maniphest/event/ManiphestNameIndexEventListener.php',
     'ManiphestQueryConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestQueryConduitAPIMethod.php',
     'ManiphestQueryStatusesConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestQueryStatusesConduitAPIMethod.php',
     'ManiphestRemarkupRule' => 'applications/maniphest/remarkup/ManiphestRemarkupRule.php',
     'ManiphestReplyHandler' => 'applications/maniphest/mail/ManiphestReplyHandler.php',
     'ManiphestReportController' => 'applications/maniphest/controller/ManiphestReportController.php',
     'ManiphestSchemaSpec' => 'applications/maniphest/storage/ManiphestSchemaSpec.php',
     'ManiphestSearchIndexer' => 'applications/maniphest/search/ManiphestSearchIndexer.php',
     'ManiphestStatusConfigOptionType' => 'applications/maniphest/config/ManiphestStatusConfigOptionType.php',
     'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php',
     'ManiphestSubscribeController' => 'applications/maniphest/controller/ManiphestSubscribeController.php',
     'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php',
     'ManiphestTaskDescriptionPreviewController' => 'applications/maniphest/controller/ManiphestTaskDescriptionPreviewController.php',
     'ManiphestTaskDetailController' => 'applications/maniphest/controller/ManiphestTaskDetailController.php',
     'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php',
     'ManiphestTaskHasCommitEdgeType' => 'applications/maniphest/edge/ManiphestTaskHasCommitEdgeType.php',
     'ManiphestTaskHasRevisionEdgeType' => 'applications/maniphest/edge/ManiphestTaskHasRevisionEdgeType.php',
     'ManiphestTaskListController' => 'applications/maniphest/controller/ManiphestTaskListController.php',
     'ManiphestTaskListView' => 'applications/maniphest/view/ManiphestTaskListView.php',
     'ManiphestTaskMailReceiver' => 'applications/maniphest/mail/ManiphestTaskMailReceiver.php',
     'ManiphestTaskOwner' => 'applications/maniphest/constants/ManiphestTaskOwner.php',
     'ManiphestTaskPHIDType' => 'applications/maniphest/phid/ManiphestTaskPHIDType.php',
     'ManiphestTaskPriority' => 'applications/maniphest/constants/ManiphestTaskPriority.php',
     'ManiphestTaskPriorityDatasource' => 'applications/maniphest/typeahead/ManiphestTaskPriorityDatasource.php',
     'ManiphestTaskQuery' => 'applications/maniphest/query/ManiphestTaskQuery.php',
     'ManiphestTaskResultListView' => 'applications/maniphest/view/ManiphestTaskResultListView.php',
     'ManiphestTaskSearchEngine' => 'applications/maniphest/query/ManiphestTaskSearchEngine.php',
     'ManiphestTaskStatus' => 'applications/maniphest/constants/ManiphestTaskStatus.php',
     'ManiphestTaskStatusDatasource' => 'applications/maniphest/typeahead/ManiphestTaskStatusDatasource.php',
     'ManiphestTaskStatusTestCase' => 'applications/maniphest/constants/__tests__/ManiphestTaskStatusTestCase.php',
     'ManiphestTaskSubscriber' => 'applications/maniphest/storage/ManiphestTaskSubscriber.php',
     'ManiphestTransaction' => 'applications/maniphest/storage/ManiphestTransaction.php',
     'ManiphestTransactionComment' => 'applications/maniphest/storage/ManiphestTransactionComment.php',
     'ManiphestTransactionEditor' => 'applications/maniphest/editor/ManiphestTransactionEditor.php',
     'ManiphestTransactionPreviewController' => 'applications/maniphest/controller/ManiphestTransactionPreviewController.php',
     'ManiphestTransactionQuery' => 'applications/maniphest/query/ManiphestTransactionQuery.php',
     'ManiphestTransactionSaveController' => 'applications/maniphest/controller/ManiphestTransactionSaveController.php',
     'ManiphestUpdateConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestUpdateConduitAPIMethod.php',
     'ManiphestView' => 'applications/maniphest/view/ManiphestView.php',
     'MetaMTAConstants' => 'applications/metamta/constants/MetaMTAConstants.php',
     'MetaMTAMailReceivedGarbageCollector' => 'applications/metamta/garbagecollector/MetaMTAMailReceivedGarbageCollector.php',
     'MetaMTAMailSentGarbageCollector' => 'applications/metamta/garbagecollector/MetaMTAMailSentGarbageCollector.php',
     'MetaMTANotificationType' => 'applications/metamta/constants/MetaMTANotificationType.php',
     'MetaMTAReceivedMailStatus' => 'applications/metamta/constants/MetaMTAReceivedMailStatus.php',
     'NuanceConduitAPIMethod' => 'applications/nuance/conduit/NuanceConduitAPIMethod.php',
     'NuanceConstants' => 'applications/nuance/constants/NuanceConstants.php',
     'NuanceController' => 'applications/nuance/controller/NuanceController.php',
     'NuanceCreateItemConduitAPIMethod' => 'applications/nuance/conduit/NuanceCreateItemConduitAPIMethod.php',
     'NuanceDAO' => 'applications/nuance/storage/NuanceDAO.php',
     'NuanceItem' => 'applications/nuance/storage/NuanceItem.php',
     'NuanceItemEditController' => 'applications/nuance/controller/NuanceItemEditController.php',
     'NuanceItemEditor' => 'applications/nuance/editor/NuanceItemEditor.php',
     'NuanceItemPHIDType' => 'applications/nuance/phid/NuanceItemPHIDType.php',
     'NuanceItemQuery' => 'applications/nuance/query/NuanceItemQuery.php',
     'NuanceItemTransaction' => 'applications/nuance/storage/NuanceItemTransaction.php',
     'NuanceItemTransactionComment' => 'applications/nuance/storage/NuanceItemTransactionComment.php',
     'NuanceItemTransactionQuery' => 'applications/nuance/query/NuanceItemTransactionQuery.php',
     'NuanceItemViewController' => 'applications/nuance/controller/NuanceItemViewController.php',
     'NuancePhabricatorFormSourceDefinition' => 'applications/nuance/source/NuancePhabricatorFormSourceDefinition.php',
     'NuanceQuery' => 'applications/nuance/query/NuanceQuery.php',
     'NuanceQueue' => 'applications/nuance/storage/NuanceQueue.php',
     'NuanceQueueEditController' => 'applications/nuance/controller/NuanceQueueEditController.php',
     'NuanceQueueEditor' => 'applications/nuance/editor/NuanceQueueEditor.php',
     'NuanceQueueItem' => 'applications/nuance/storage/NuanceQueueItem.php',
     'NuanceQueuePHIDType' => 'applications/nuance/phid/NuanceQueuePHIDType.php',
     'NuanceQueueQuery' => 'applications/nuance/query/NuanceQueueQuery.php',
     'NuanceQueueTransaction' => 'applications/nuance/storage/NuanceQueueTransaction.php',
     'NuanceQueueTransactionComment' => 'applications/nuance/storage/NuanceQueueTransactionComment.php',
     'NuanceQueueTransactionQuery' => 'applications/nuance/query/NuanceQueueTransactionQuery.php',
     'NuanceQueueViewController' => 'applications/nuance/controller/NuanceQueueViewController.php',
     'NuanceRequestor' => 'applications/nuance/storage/NuanceRequestor.php',
     'NuanceRequestorEditController' => 'applications/nuance/controller/NuanceRequestorEditController.php',
     'NuanceRequestorEditor' => 'applications/nuance/editor/NuanceRequestorEditor.php',
     'NuanceRequestorPHIDType' => 'applications/nuance/phid/NuanceRequestorPHIDType.php',
     'NuanceRequestorQuery' => 'applications/nuance/query/NuanceRequestorQuery.php',
     'NuanceRequestorSource' => 'applications/nuance/storage/NuanceRequestorSource.php',
     'NuanceRequestorTransaction' => 'applications/nuance/storage/NuanceRequestorTransaction.php',
     'NuanceRequestorTransactionComment' => 'applications/nuance/storage/NuanceRequestorTransactionComment.php',
     'NuanceRequestorTransactionQuery' => 'applications/nuance/query/NuanceRequestorTransactionQuery.php',
     'NuanceRequestorViewController' => 'applications/nuance/controller/NuanceRequestorViewController.php',
     'NuanceSchemaSpec' => 'applications/nuance/storage/NuanceSchemaSpec.php',
     'NuanceSource' => 'applications/nuance/storage/NuanceSource.php',
     'NuanceSourceDefaultEditCapability' => 'applications/nuance/capability/NuanceSourceDefaultEditCapability.php',
     'NuanceSourceDefaultViewCapability' => 'applications/nuance/capability/NuanceSourceDefaultViewCapability.php',
     'NuanceSourceDefinition' => 'applications/nuance/source/NuanceSourceDefinition.php',
     'NuanceSourceEditController' => 'applications/nuance/controller/NuanceSourceEditController.php',
     'NuanceSourceEditor' => 'applications/nuance/editor/NuanceSourceEditor.php',
     'NuanceSourceManageCapability' => 'applications/nuance/capability/NuanceSourceManageCapability.php',
     'NuanceSourcePHIDType' => 'applications/nuance/phid/NuanceSourcePHIDType.php',
     'NuanceSourceQuery' => 'applications/nuance/query/NuanceSourceQuery.php',
     'NuanceSourceTransaction' => 'applications/nuance/storage/NuanceSourceTransaction.php',
     'NuanceSourceTransactionComment' => 'applications/nuance/storage/NuanceSourceTransactionComment.php',
     'NuanceSourceTransactionQuery' => 'applications/nuance/query/NuanceSourceTransactionQuery.php',
     'NuanceSourceViewController' => 'applications/nuance/controller/NuanceSourceViewController.php',
     'NuanceTransaction' => 'applications/nuance/storage/NuanceTransaction.php',
     'OwnersConduitAPIMethod' => 'applications/owners/conduit/OwnersConduitAPIMethod.php',
     'OwnersPackageReplyHandler' => 'applications/owners/mail/OwnersPackageReplyHandler.php',
     'OwnersQueryConduitAPIMethod' => 'applications/owners/conduit/OwnersQueryConduitAPIMethod.php',
     'PHIDConduitAPIMethod' => 'applications/phid/conduit/PHIDConduitAPIMethod.php',
     'PHIDInfoConduitAPIMethod' => 'applications/phid/conduit/PHIDInfoConduitAPIMethod.php',
     'PHIDLookupConduitAPIMethod' => 'applications/phid/conduit/PHIDLookupConduitAPIMethod.php',
     'PHIDQueryConduitAPIMethod' => 'applications/phid/conduit/PHIDQueryConduitAPIMethod.php',
     'PHUI' => 'view/phui/PHUI.php',
     'PHUIActionHeaderExample' => 'applications/uiexample/examples/PHUIActionHeaderExample.php',
     'PHUIActionHeaderView' => 'view/phui/PHUIActionHeaderView.php',
     'PHUIBoxExample' => 'applications/uiexample/examples/PHUIBoxExample.php',
     'PHUIBoxView' => 'view/phui/PHUIBoxView.php',
     'PHUIButtonBarExample' => 'applications/uiexample/examples/PHUIButtonBarExample.php',
     'PHUIButtonBarView' => 'view/phui/PHUIButtonBarView.php',
     'PHUIButtonExample' => 'applications/uiexample/examples/PHUIButtonExample.php',
     'PHUIButtonView' => 'view/phui/PHUIButtonView.php',
     'PHUICalendarListView' => 'view/phui/calendar/PHUICalendarListView.php',
     'PHUICalendarMonthView' => 'view/phui/calendar/PHUICalendarMonthView.php',
     'PHUICalendarWidgetView' => 'view/phui/calendar/PHUICalendarWidgetView.php',
     'PHUIColorPalletteExample' => 'applications/uiexample/examples/PHUIColorPalletteExample.php',
     'PHUIDocumentExample' => 'applications/uiexample/examples/PHUIDocumentExample.php',
     'PHUIDocumentView' => 'view/phui/PHUIDocumentView.php',
     'PHUIFeedStoryExample' => 'applications/uiexample/examples/PHUIFeedStoryExample.php',
     'PHUIFeedStoryView' => 'view/phui/PHUIFeedStoryView.php',
     'PHUIFormDividerControl' => 'view/form/control/PHUIFormDividerControl.php',
     'PHUIFormFreeformDateControl' => 'view/form/control/PHUIFormFreeformDateControl.php',
     'PHUIFormInsetView' => 'view/form/PHUIFormInsetView.php',
     'PHUIFormLayoutView' => 'view/form/PHUIFormLayoutView.php',
     'PHUIFormMultiSubmitControl' => 'view/form/control/PHUIFormMultiSubmitControl.php',
     'PHUIFormPageView' => 'view/form/PHUIFormPageView.php',
     'PHUIHandleTagListView' => 'applications/phid/view/PHUIHandleTagListView.php',
     'PHUIHeaderView' => 'view/phui/PHUIHeaderView.php',
     'PHUIIconExample' => 'applications/uiexample/examples/PHUIIconExample.php',
     'PHUIIconView' => 'view/phui/PHUIIconView.php',
     'PHUIImageMaskExample' => 'applications/uiexample/examples/PHUIImageMaskExample.php',
     'PHUIImageMaskView' => 'view/phui/PHUIImageMaskView.php',
     'PHUIInfoPanelExample' => 'applications/uiexample/examples/PHUIInfoPanelExample.php',
     'PHUIInfoPanelView' => 'view/phui/PHUIInfoPanelView.php',
     'PHUIListExample' => 'applications/uiexample/examples/PHUIListExample.php',
     'PHUIListItemView' => 'view/phui/PHUIListItemView.php',
     'PHUIListView' => 'view/phui/PHUIListView.php',
     'PHUIListViewTestCase' => 'view/layout/__tests__/PHUIListViewTestCase.php',
     'PHUIObjectBoxView' => 'view/phui/PHUIObjectBoxView.php',
     'PHUIObjectItemListExample' => 'applications/uiexample/examples/PHUIObjectItemListExample.php',
     'PHUIObjectItemListView' => 'view/phui/PHUIObjectItemListView.php',
     'PHUIObjectItemView' => 'view/phui/PHUIObjectItemView.php',
     'PHUIPagedFormView' => 'view/form/PHUIPagedFormView.php',
     'PHUIPinboardItemView' => 'view/phui/PHUIPinboardItemView.php',
     'PHUIPinboardView' => 'view/phui/PHUIPinboardView.php',
     'PHUIPropertyGroupView' => 'view/phui/PHUIPropertyGroupView.php',
     'PHUIPropertyListExample' => 'applications/uiexample/examples/PHUIPropertyListExample.php',
     'PHUIPropertyListView' => 'view/phui/PHUIPropertyListView.php',
     'PHUIRemarkupPreviewPanel' => 'view/phui/PHUIRemarkupPreviewPanel.php',
     'PHUIStatusItemView' => 'view/phui/PHUIStatusItemView.php',
     'PHUIStatusListView' => 'view/phui/PHUIStatusListView.php',
     'PHUITagExample' => 'applications/uiexample/examples/PHUITagExample.php',
     'PHUITagView' => 'view/phui/PHUITagView.php',
     'PHUITextExample' => 'applications/uiexample/examples/PHUITextExample.php',
     'PHUITextView' => 'view/phui/PHUITextView.php',
     'PHUITimelineEventView' => 'view/phui/PHUITimelineEventView.php',
     'PHUITimelineExample' => 'applications/uiexample/examples/PHUITimelineExample.php',
     'PHUITimelineView' => 'view/phui/PHUITimelineView.php',
     'PHUIWorkboardView' => 'view/phui/PHUIWorkboardView.php',
     'PHUIWorkpanelView' => 'view/phui/PHUIWorkpanelView.php',
     'PackageCreateMail' => 'applications/owners/mail/PackageCreateMail.php',
     'PackageDeleteMail' => 'applications/owners/mail/PackageDeleteMail.php',
     'PackageMail' => 'applications/owners/mail/PackageMail.php',
     'PackageModifyMail' => 'applications/owners/mail/PackageModifyMail.php',
     'PassphraseAbstractKey' => 'applications/passphrase/keys/PassphraseAbstractKey.php',
     'PassphraseConduitAPIMethod' => 'applications/passphrase/conduit/PassphraseConduitAPIMethod.php',
     'PassphraseController' => 'applications/passphrase/controller/PassphraseController.php',
     'PassphraseCredential' => 'applications/passphrase/storage/PassphraseCredential.php',
     'PassphraseCredentialConduitController' => 'applications/passphrase/controller/PassphraseCredentialConduitController.php',
     'PassphraseCredentialControl' => 'applications/passphrase/view/PassphraseCredentialControl.php',
     'PassphraseCredentialCreateController' => 'applications/passphrase/controller/PassphraseCredentialCreateController.php',
     'PassphraseCredentialDestroyController' => 'applications/passphrase/controller/PassphraseCredentialDestroyController.php',
     'PassphraseCredentialEditController' => 'applications/passphrase/controller/PassphraseCredentialEditController.php',
     'PassphraseCredentialListController' => 'applications/passphrase/controller/PassphraseCredentialListController.php',
     'PassphraseCredentialLockController' => 'applications/passphrase/controller/PassphraseCredentialLockController.php',
     'PassphraseCredentialPHIDType' => 'applications/passphrase/phid/PassphraseCredentialPHIDType.php',
     'PassphraseCredentialPublicController' => 'applications/passphrase/controller/PassphraseCredentialPublicController.php',
     'PassphraseCredentialQuery' => 'applications/passphrase/query/PassphraseCredentialQuery.php',
     'PassphraseCredentialRevealController' => 'applications/passphrase/controller/PassphraseCredentialRevealController.php',
     'PassphraseCredentialSearchEngine' => 'applications/passphrase/query/PassphraseCredentialSearchEngine.php',
     'PassphraseCredentialTransaction' => 'applications/passphrase/storage/PassphraseCredentialTransaction.php',
     'PassphraseCredentialTransactionEditor' => 'applications/passphrase/editor/PassphraseCredentialTransactionEditor.php',
     'PassphraseCredentialTransactionQuery' => 'applications/passphrase/query/PassphraseCredentialTransactionQuery.php',
     'PassphraseCredentialType' => 'applications/passphrase/credentialtype/PassphraseCredentialType.php',
     'PassphraseCredentialTypePassword' => 'applications/passphrase/credentialtype/PassphraseCredentialTypePassword.php',
     'PassphraseCredentialTypeSSHGeneratedKey' => 'applications/passphrase/credentialtype/PassphraseCredentialTypeSSHGeneratedKey.php',
     'PassphraseCredentialTypeSSHPrivateKey' => 'applications/passphrase/credentialtype/PassphraseCredentialTypeSSHPrivateKey.php',
     'PassphraseCredentialTypeSSHPrivateKeyFile' => 'applications/passphrase/credentialtype/PassphraseCredentialTypeSSHPrivateKeyFile.php',
     'PassphraseCredentialTypeSSHPrivateKeyText' => 'applications/passphrase/credentialtype/PassphraseCredentialTypeSSHPrivateKeyText.php',
     'PassphraseCredentialViewController' => 'applications/passphrase/controller/PassphraseCredentialViewController.php',
     'PassphraseDAO' => 'applications/passphrase/storage/PassphraseDAO.php',
     'PassphrasePasswordKey' => 'applications/passphrase/keys/PassphrasePasswordKey.php',
     'PassphraseQueryConduitAPIMethod' => 'applications/passphrase/conduit/PassphraseQueryConduitAPIMethod.php',
     'PassphraseRemarkupRule' => 'applications/passphrase/remarkup/PassphraseRemarkupRule.php',
     'PassphraseSSHKey' => 'applications/passphrase/keys/PassphraseSSHKey.php',
     'PassphraseSchemaSpec' => 'applications/passphrase/storage/PassphraseSchemaSpec.php',
     'PassphraseSecret' => 'applications/passphrase/storage/PassphraseSecret.php',
     'PasteConduitAPIMethod' => 'applications/paste/conduit/PasteConduitAPIMethod.php',
     'PasteCreateConduitAPIMethod' => 'applications/paste/conduit/PasteCreateConduitAPIMethod.php',
     'PasteCreateMailReceiver' => 'applications/paste/mail/PasteCreateMailReceiver.php',
     'PasteDefaultViewCapability' => 'applications/paste/capability/PasteDefaultViewCapability.php',
     'PasteEmbedView' => 'applications/paste/view/PasteEmbedView.php',
     'PasteInfoConduitAPIMethod' => 'applications/paste/conduit/PasteInfoConduitAPIMethod.php',
     'PasteMockMailReceiver' => 'applications/paste/mail/PasteMockMailReceiver.php',
     'PasteQueryConduitAPIMethod' => 'applications/paste/conduit/PasteQueryConduitAPIMethod.php',
     'PasteReplyHandler' => 'applications/paste/mail/PasteReplyHandler.php',
     'PeopleBrowseUserDirectoryCapability' => 'applications/people/capability/PeopleBrowseUserDirectoryCapability.php',
     'PeopleUserLogGarbageCollector' => 'applications/people/garbagecollector/PeopleUserLogGarbageCollector.php',
     'Phabricator404Controller' => 'applications/base/controller/Phabricator404Controller.php',
     'PhabricatorAWSConfigOptions' => 'applications/config/option/PhabricatorAWSConfigOptions.php',
     'PhabricatorAccessControlTestCase' => 'applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php',
     'PhabricatorAccessLog' => 'infrastructure/log/PhabricatorAccessLog.php',
     'PhabricatorAccessLogConfigOptions' => 'applications/config/option/PhabricatorAccessLogConfigOptions.php',
     'PhabricatorActionListView' => 'view/layout/PhabricatorActionListView.php',
     'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php',
     'PhabricatorAllCapsTranslation' => 'infrastructure/internationalization/translation/PhabricatorAllCapsTranslation.php',
     'PhabricatorAlmanacApplication' => 'applications/almanac/application/PhabricatorAlmanacApplication.php',
     'PhabricatorAmazonAuthProvider' => 'applications/auth/provider/PhabricatorAmazonAuthProvider.php',
     'PhabricatorAnchorView' => 'view/layout/PhabricatorAnchorView.php',
     'PhabricatorAphlictManagementBuildWorkflow' => 'applications/aphlict/management/PhabricatorAphlictManagementBuildWorkflow.php',
     'PhabricatorAphlictManagementDebugWorkflow' => 'applications/aphlict/management/PhabricatorAphlictManagementDebugWorkflow.php',
     'PhabricatorAphlictManagementRestartWorkflow' => 'applications/aphlict/management/PhabricatorAphlictManagementRestartWorkflow.php',
     'PhabricatorAphlictManagementStartWorkflow' => 'applications/aphlict/management/PhabricatorAphlictManagementStartWorkflow.php',
     'PhabricatorAphlictManagementStatusWorkflow' => 'applications/aphlict/management/PhabricatorAphlictManagementStatusWorkflow.php',
     'PhabricatorAphlictManagementStopWorkflow' => 'applications/aphlict/management/PhabricatorAphlictManagementStopWorkflow.php',
     'PhabricatorAphlictManagementWorkflow' => 'applications/aphlict/management/PhabricatorAphlictManagementWorkflow.php',
     'PhabricatorAphrontBarExample' => 'applications/uiexample/examples/PhabricatorAphrontBarExample.php',
     'PhabricatorAphrontViewTestCase' => 'view/__tests__/PhabricatorAphrontViewTestCase.php',
     'PhabricatorAppSearchEngine' => 'applications/meta/query/PhabricatorAppSearchEngine.php',
     'PhabricatorApplication' => 'applications/base/PhabricatorApplication.php',
     'PhabricatorApplicationApplicationPHIDType' => 'applications/meta/phid/PhabricatorApplicationApplicationPHIDType.php',
     'PhabricatorApplicationConfigOptions' => 'applications/config/option/PhabricatorApplicationConfigOptions.php',
     'PhabricatorApplicationDatasource' => 'applications/meta/typeahead/PhabricatorApplicationDatasource.php',
     'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php',
     'PhabricatorApplicationEditController' => 'applications/meta/controller/PhabricatorApplicationEditController.php',
     'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php',
     'PhabricatorApplicationQuery' => 'applications/meta/query/PhabricatorApplicationQuery.php',
     'PhabricatorApplicationSearchController' => 'applications/search/controller/PhabricatorApplicationSearchController.php',
     'PhabricatorApplicationSearchEngine' => 'applications/search/engine/PhabricatorApplicationSearchEngine.php',
     'PhabricatorApplicationSearchResultsControllerInterface' => 'applications/search/interface/PhabricatorApplicationSearchResultsControllerInterface.php',
     'PhabricatorApplicationStatusView' => 'applications/meta/view/PhabricatorApplicationStatusView.php',
     'PhabricatorApplicationTransaction' => 'applications/transactions/storage/PhabricatorApplicationTransaction.php',
     'PhabricatorApplicationTransactionComment' => 'applications/transactions/storage/PhabricatorApplicationTransactionComment.php',
     'PhabricatorApplicationTransactionCommentEditController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentEditController.php',
     'PhabricatorApplicationTransactionCommentEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionCommentEditor.php',
     'PhabricatorApplicationTransactionCommentHistoryController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentHistoryController.php',
     'PhabricatorApplicationTransactionCommentQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php',
     'PhabricatorApplicationTransactionCommentQuoteController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentQuoteController.php',
     'PhabricatorApplicationTransactionCommentRawController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentRawController.php',
     'PhabricatorApplicationTransactionCommentRemoveController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentRemoveController.php',
     'PhabricatorApplicationTransactionCommentView' => 'applications/transactions/view/PhabricatorApplicationTransactionCommentView.php',
     'PhabricatorApplicationTransactionController' => 'applications/transactions/controller/PhabricatorApplicationTransactionController.php',
     'PhabricatorApplicationTransactionDetailController' => 'applications/transactions/controller/PhabricatorApplicationTransactionDetailController.php',
     'PhabricatorApplicationTransactionEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionEditor.php',
     'PhabricatorApplicationTransactionFeedStory' => 'applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php',
     'PhabricatorApplicationTransactionInterface' => 'applications/transactions/interface/PhabricatorApplicationTransactionInterface.php',
     'PhabricatorApplicationTransactionNoEffectException' => 'applications/transactions/exception/PhabricatorApplicationTransactionNoEffectException.php',
     'PhabricatorApplicationTransactionNoEffectResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionNoEffectResponse.php',
     'PhabricatorApplicationTransactionQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionQuery.php',
     'PhabricatorApplicationTransactionResponse' => 'applications/transactions/response/PhabricatorApplicationTransactionResponse.php',
     'PhabricatorApplicationTransactionShowOlderController' => 'applications/transactions/controller/PhabricatorApplicationTransactionShowOlderController.php',
     'PhabricatorApplicationTransactionStructureException' => 'applications/transactions/exception/PhabricatorApplicationTransactionStructureException.php',
     'PhabricatorApplicationTransactionTextDiffDetailView' => 'applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php',
     'PhabricatorApplicationTransactionTransactionPHIDType' => 'applications/transactions/phid/PhabricatorApplicationTransactionTransactionPHIDType.php',
     'PhabricatorApplicationTransactionValidationError' => 'applications/transactions/error/PhabricatorApplicationTransactionValidationError.php',
     'PhabricatorApplicationTransactionValidationException' => 'applications/transactions/exception/PhabricatorApplicationTransactionValidationException.php',
     'PhabricatorApplicationTransactionValueController' => 'applications/transactions/controller/PhabricatorApplicationTransactionValueController.php',
     'PhabricatorApplicationTransactionView' => 'applications/transactions/view/PhabricatorApplicationTransactionView.php',
     'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php',
     'PhabricatorApplicationsApplication' => 'applications/meta/application/PhabricatorApplicationsApplication.php',
     'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php',
     'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php',
     'PhabricatorAsanaAuthProvider' => 'applications/auth/provider/PhabricatorAsanaAuthProvider.php',
     'PhabricatorAsanaConfigOptions' => 'applications/doorkeeper/option/PhabricatorAsanaConfigOptions.php',
     'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
     'PhabricatorAuditAddCommentController' => 'applications/audit/controller/PhabricatorAuditAddCommentController.php',
     'PhabricatorAuditApplication' => 'applications/audit/application/PhabricatorAuditApplication.php',
     'PhabricatorAuditCommentEditor' => 'applications/audit/editor/PhabricatorAuditCommentEditor.php',
     'PhabricatorAuditCommitStatusConstants' => 'applications/audit/constants/PhabricatorAuditCommitStatusConstants.php',
     'PhabricatorAuditController' => 'applications/audit/controller/PhabricatorAuditController.php',
     'PhabricatorAuditDAO' => 'applications/audit/storage/PhabricatorAuditDAO.php',
     'PhabricatorAuditEditor' => 'applications/audit/editor/PhabricatorAuditEditor.php',
     'PhabricatorAuditInlineComment' => 'applications/audit/storage/PhabricatorAuditInlineComment.php',
     'PhabricatorAuditListController' => 'applications/audit/controller/PhabricatorAuditListController.php',
     'PhabricatorAuditListView' => 'applications/audit/view/PhabricatorAuditListView.php',
     'PhabricatorAuditMailReceiver' => 'applications/audit/mail/PhabricatorAuditMailReceiver.php',
     'PhabricatorAuditManagementDeleteWorkflow' => 'applications/audit/management/PhabricatorAuditManagementDeleteWorkflow.php',
     'PhabricatorAuditManagementWorkflow' => 'applications/audit/management/PhabricatorAuditManagementWorkflow.php',
     'PhabricatorAuditPreviewController' => 'applications/audit/controller/PhabricatorAuditPreviewController.php',
     'PhabricatorAuditReplyHandler' => 'applications/audit/mail/PhabricatorAuditReplyHandler.php',
     'PhabricatorAuditStatusConstants' => 'applications/audit/constants/PhabricatorAuditStatusConstants.php',
     'PhabricatorAuditTransaction' => 'applications/audit/storage/PhabricatorAuditTransaction.php',
     'PhabricatorAuditTransactionComment' => 'applications/audit/storage/PhabricatorAuditTransactionComment.php',
     'PhabricatorAuditTransactionQuery' => 'applications/audit/query/PhabricatorAuditTransactionQuery.php',
     'PhabricatorAuditTransactionView' => 'applications/audit/view/PhabricatorAuditTransactionView.php',
     'PhabricatorAuthAccountView' => 'applications/auth/view/PhabricatorAuthAccountView.php',
     'PhabricatorAuthApplication' => 'applications/auth/application/PhabricatorAuthApplication.php',
     'PhabricatorAuthAuthFactorPHIDType' => 'applications/auth/phid/PhabricatorAuthAuthFactorPHIDType.php',
     'PhabricatorAuthAuthProviderPHIDType' => 'applications/auth/phid/PhabricatorAuthAuthProviderPHIDType.php',
     'PhabricatorAuthConfirmLinkController' => 'applications/auth/controller/PhabricatorAuthConfirmLinkController.php',
     'PhabricatorAuthController' => 'applications/auth/controller/PhabricatorAuthController.php',
     'PhabricatorAuthDAO' => 'applications/auth/storage/PhabricatorAuthDAO.php',
     'PhabricatorAuthDisableController' => 'applications/auth/controller/config/PhabricatorAuthDisableController.php',
     'PhabricatorAuthDowngradeSessionController' => 'applications/auth/controller/PhabricatorAuthDowngradeSessionController.php',
     'PhabricatorAuthEditController' => 'applications/auth/controller/config/PhabricatorAuthEditController.php',
     'PhabricatorAuthFactor' => 'applications/auth/factor/PhabricatorAuthFactor.php',
     'PhabricatorAuthFactorConfig' => 'applications/auth/storage/PhabricatorAuthFactorConfig.php',
     'PhabricatorAuthFactorTOTP' => 'applications/auth/factor/PhabricatorAuthFactorTOTP.php',
     'PhabricatorAuthFactorTOTPTestCase' => 'applications/auth/factor/__tests__/PhabricatorAuthFactorTOTPTestCase.php',
     'PhabricatorAuthFinishController' => 'applications/auth/controller/PhabricatorAuthFinishController.php',
     'PhabricatorAuthHighSecurityRequiredException' => 'applications/auth/exception/PhabricatorAuthHighSecurityRequiredException.php',
     'PhabricatorAuthHighSecurityToken' => 'applications/auth/data/PhabricatorAuthHighSecurityToken.php',
     'PhabricatorAuthLinkController' => 'applications/auth/controller/PhabricatorAuthLinkController.php',
     'PhabricatorAuthListController' => 'applications/auth/controller/config/PhabricatorAuthListController.php',
     'PhabricatorAuthLoginController' => 'applications/auth/controller/PhabricatorAuthLoginController.php',
     'PhabricatorAuthManagementLDAPWorkflow' => 'applications/auth/management/PhabricatorAuthManagementLDAPWorkflow.php',
     'PhabricatorAuthManagementListFactorsWorkflow' => 'applications/auth/management/PhabricatorAuthManagementListFactorsWorkflow.php',
     'PhabricatorAuthManagementRecoverWorkflow' => 'applications/auth/management/PhabricatorAuthManagementRecoverWorkflow.php',
     'PhabricatorAuthManagementRefreshWorkflow' => 'applications/auth/management/PhabricatorAuthManagementRefreshWorkflow.php',
     'PhabricatorAuthManagementStripWorkflow' => 'applications/auth/management/PhabricatorAuthManagementStripWorkflow.php',
     'PhabricatorAuthManagementWorkflow' => 'applications/auth/management/PhabricatorAuthManagementWorkflow.php',
     'PhabricatorAuthNeedsApprovalController' => 'applications/auth/controller/PhabricatorAuthNeedsApprovalController.php',
     'PhabricatorAuthNeedsMultiFactorController' => 'applications/auth/controller/PhabricatorAuthNeedsMultiFactorController.php',
     'PhabricatorAuthNewController' => 'applications/auth/controller/config/PhabricatorAuthNewController.php',
     'PhabricatorAuthOldOAuthRedirectController' => 'applications/auth/controller/PhabricatorAuthOldOAuthRedirectController.php',
     'PhabricatorAuthOneTimeLoginController' => 'applications/auth/controller/PhabricatorAuthOneTimeLoginController.php',
     'PhabricatorAuthProvider' => 'applications/auth/provider/PhabricatorAuthProvider.php',
     'PhabricatorAuthProviderConfig' => 'applications/auth/storage/PhabricatorAuthProviderConfig.php',
     'PhabricatorAuthProviderConfigController' => 'applications/auth/controller/config/PhabricatorAuthProviderConfigController.php',
     'PhabricatorAuthProviderConfigEditor' => 'applications/auth/editor/PhabricatorAuthProviderConfigEditor.php',
     'PhabricatorAuthProviderConfigQuery' => 'applications/auth/query/PhabricatorAuthProviderConfigQuery.php',
     'PhabricatorAuthProviderConfigTransaction' => 'applications/auth/storage/PhabricatorAuthProviderConfigTransaction.php',
     'PhabricatorAuthProviderConfigTransactionQuery' => 'applications/auth/query/PhabricatorAuthProviderConfigTransactionQuery.php',
     'PhabricatorAuthRegisterController' => 'applications/auth/controller/PhabricatorAuthRegisterController.php',
     'PhabricatorAuthRevokeTokenController' => 'applications/auth/controller/PhabricatorAuthRevokeTokenController.php',
     'PhabricatorAuthSSHKey' => 'applications/auth/storage/PhabricatorAuthSSHKey.php',
     'PhabricatorAuthSSHKeyController' => 'applications/auth/controller/PhabricatorAuthSSHKeyController.php',
     'PhabricatorAuthSSHKeyDeleteController' => 'applications/auth/controller/PhabricatorAuthSSHKeyDeleteController.php',
     'PhabricatorAuthSSHKeyEditController' => 'applications/auth/controller/PhabricatorAuthSSHKeyEditController.php',
     'PhabricatorAuthSSHKeyGenerateController' => 'applications/auth/controller/PhabricatorAuthSSHKeyGenerateController.php',
     'PhabricatorAuthSSHKeyQuery' => 'applications/auth/query/PhabricatorAuthSSHKeyQuery.php',
     'PhabricatorAuthSSHKeyTableView' => 'applications/auth/view/PhabricatorAuthSSHKeyTableView.php',
     'PhabricatorAuthSSHPublicKey' => 'applications/auth/sshkey/PhabricatorAuthSSHPublicKey.php',
     'PhabricatorAuthSession' => 'applications/auth/storage/PhabricatorAuthSession.php',
     'PhabricatorAuthSessionEngine' => 'applications/auth/engine/PhabricatorAuthSessionEngine.php',
     'PhabricatorAuthSessionGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthSessionGarbageCollector.php',
     'PhabricatorAuthSessionQuery' => 'applications/auth/query/PhabricatorAuthSessionQuery.php',
     'PhabricatorAuthStartController' => 'applications/auth/controller/PhabricatorAuthStartController.php',
     'PhabricatorAuthTemporaryToken' => 'applications/auth/storage/PhabricatorAuthTemporaryToken.php',
     'PhabricatorAuthTemporaryTokenGarbageCollector' => 'applications/auth/garbagecollector/PhabricatorAuthTemporaryTokenGarbageCollector.php',
     'PhabricatorAuthTemporaryTokenQuery' => 'applications/auth/query/PhabricatorAuthTemporaryTokenQuery.php',
     'PhabricatorAuthTerminateSessionController' => 'applications/auth/controller/PhabricatorAuthTerminateSessionController.php',
     'PhabricatorAuthTryFactorAction' => 'applications/auth/action/PhabricatorAuthTryFactorAction.php',
     'PhabricatorAuthUnlinkController' => 'applications/auth/controller/PhabricatorAuthUnlinkController.php',
     'PhabricatorAuthValidateController' => 'applications/auth/controller/PhabricatorAuthValidateController.php',
     'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php',
     'PhabricatorAutoEventListener' => 'infrastructure/events/PhabricatorAutoEventListener.php',
     'PhabricatorBarePageExample' => 'applications/uiexample/examples/PhabricatorBarePageExample.php',
     'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php',
     'PhabricatorBaseEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php',
     'PhabricatorBaseProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBaseProtocolAdapter.php',
     'PhabricatorBcryptPasswordHasher' => 'infrastructure/util/password/PhabricatorBcryptPasswordHasher.php',
     'PhabricatorBitbucketAuthProvider' => 'applications/auth/provider/PhabricatorBitbucketAuthProvider.php',
     'PhabricatorBot' => 'infrastructure/daemon/bot/PhabricatorBot.php',
     'PhabricatorBotBaseStreamingProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBotBaseStreamingProtocolAdapter.php',
     'PhabricatorBotChannel' => 'infrastructure/daemon/bot/target/PhabricatorBotChannel.php',
     'PhabricatorBotDebugLogHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotDebugLogHandler.php',
     'PhabricatorBotFeedNotificationHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotFeedNotificationHandler.php',
     'PhabricatorBotFlowdockProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBotFlowdockProtocolAdapter.php',
     'PhabricatorBotHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotHandler.php',
     'PhabricatorBotLogHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotLogHandler.php',
     'PhabricatorBotMacroHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotMacroHandler.php',
     'PhabricatorBotMessage' => 'infrastructure/daemon/bot/PhabricatorBotMessage.php',
     'PhabricatorBotObjectNameHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotObjectNameHandler.php',
     'PhabricatorBotSymbolHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotSymbolHandler.php',
     'PhabricatorBotTarget' => 'infrastructure/daemon/bot/target/PhabricatorBotTarget.php',
     'PhabricatorBotUser' => 'infrastructure/daemon/bot/target/PhabricatorBotUser.php',
     'PhabricatorBotWhatsNewHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotWhatsNewHandler.php',
     'PhabricatorBuiltinPatchList' => 'infrastructure/storage/patch/PhabricatorBuiltinPatchList.php',
     'PhabricatorBusyExample' => 'applications/uiexample/examples/PhabricatorBusyExample.php',
     'PhabricatorCacheDAO' => 'applications/cache/storage/PhabricatorCacheDAO.php',
     'PhabricatorCacheGeneralGarbageCollector' => 'applications/cache/garbagecollector/PhabricatorCacheGeneralGarbageCollector.php',
     'PhabricatorCacheManagementPurgeWorkflow' => 'applications/cache/management/PhabricatorCacheManagementPurgeWorkflow.php',
     'PhabricatorCacheManagementWorkflow' => 'applications/cache/management/PhabricatorCacheManagementWorkflow.php',
     'PhabricatorCacheMarkupGarbageCollector' => 'applications/cache/garbagecollector/PhabricatorCacheMarkupGarbageCollector.php',
     'PhabricatorCacheSchemaSpec' => 'applications/cache/storage/PhabricatorCacheSchemaSpec.php',
     'PhabricatorCacheTTLGarbageCollector' => 'applications/cache/garbagecollector/PhabricatorCacheTTLGarbageCollector.php',
     'PhabricatorCaches' => 'applications/cache/PhabricatorCaches.php',
     'PhabricatorCalendarApplication' => 'applications/calendar/application/PhabricatorCalendarApplication.php',
     'PhabricatorCalendarBrowseController' => 'applications/calendar/controller/PhabricatorCalendarBrowseController.php',
     'PhabricatorCalendarController' => 'applications/calendar/controller/PhabricatorCalendarController.php',
     'PhabricatorCalendarDAO' => 'applications/calendar/storage/PhabricatorCalendarDAO.php',
     'PhabricatorCalendarEvent' => 'applications/calendar/storage/PhabricatorCalendarEvent.php',
     'PhabricatorCalendarEventDeleteController' => 'applications/calendar/controller/PhabricatorCalendarEventDeleteController.php',
     'PhabricatorCalendarEventEditController' => 'applications/calendar/controller/PhabricatorCalendarEventEditController.php',
     'PhabricatorCalendarEventInvalidEpochException' => 'applications/calendar/exception/PhabricatorCalendarEventInvalidEpochException.php',
     'PhabricatorCalendarEventListController' => 'applications/calendar/controller/PhabricatorCalendarEventListController.php',
     'PhabricatorCalendarEventPHIDType' => 'applications/calendar/phid/PhabricatorCalendarEventPHIDType.php',
     'PhabricatorCalendarEventQuery' => 'applications/calendar/query/PhabricatorCalendarEventQuery.php',
     'PhabricatorCalendarEventSearchEngine' => 'applications/calendar/query/PhabricatorCalendarEventSearchEngine.php',
     'PhabricatorCalendarEventViewController' => 'applications/calendar/controller/PhabricatorCalendarEventViewController.php',
     'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
     'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
     'PhabricatorCalendarViewController' => 'applications/calendar/controller/PhabricatorCalendarViewController.php',
     'PhabricatorCampfireProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorCampfireProtocolAdapter.php',
     'PhabricatorCelerityApplication' => 'applications/celerity/application/PhabricatorCelerityApplication.php',
     'PhabricatorCelerityTestCase' => '__tests__/PhabricatorCelerityTestCase.php',
     'PhabricatorChangeParserTestCase' => 'applications/repository/worker/__tests__/PhabricatorChangeParserTestCase.php',
     'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php',
     'PhabricatorChatLogApplication' => 'applications/chatlog/application/PhabricatorChatLogApplication.php',
     'PhabricatorChatLogChannel' => 'applications/chatlog/storage/PhabricatorChatLogChannel.php',
     'PhabricatorChatLogChannelListController' => 'applications/chatlog/controller/PhabricatorChatLogChannelListController.php',
     'PhabricatorChatLogChannelLogController' => 'applications/chatlog/controller/PhabricatorChatLogChannelLogController.php',
     'PhabricatorChatLogChannelQuery' => 'applications/chatlog/query/PhabricatorChatLogChannelQuery.php',
     'PhabricatorChatLogConstants' => 'applications/chatlog/constants/PhabricatorChatLogConstants.php',
     'PhabricatorChatLogController' => 'applications/chatlog/controller/PhabricatorChatLogController.php',
     'PhabricatorChatLogDAO' => 'applications/chatlog/storage/PhabricatorChatLogDAO.php',
     'PhabricatorChatLogEvent' => 'applications/chatlog/storage/PhabricatorChatLogEvent.php',
     'PhabricatorChatLogEventType' => 'applications/chatlog/constants/PhabricatorChatLogEventType.php',
     'PhabricatorChatLogQuery' => 'applications/chatlog/query/PhabricatorChatLogQuery.php',
     'PhabricatorCommitBranchesField' => 'applications/repository/customfield/PhabricatorCommitBranchesField.php',
     'PhabricatorCommitCustomField' => 'applications/repository/customfield/PhabricatorCommitCustomField.php',
     'PhabricatorCommitSearchEngine' => 'applications/audit/query/PhabricatorCommitSearchEngine.php',
     'PhabricatorCommitTagsField' => 'applications/repository/customfield/PhabricatorCommitTagsField.php',
     'PhabricatorCommonPasswords' => 'applications/auth/constants/PhabricatorCommonPasswords.php',
     'PhabricatorConduitAPIController' => 'applications/conduit/controller/PhabricatorConduitAPIController.php',
     'PhabricatorConduitApplication' => 'applications/conduit/application/PhabricatorConduitApplication.php',
     'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/PhabricatorConduitCertificateToken.php',
     'PhabricatorConduitConfigOptions' => 'applications/conduit/config/PhabricatorConduitConfigOptions.php',
     'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/PhabricatorConduitConnectionLog.php',
     'PhabricatorConduitConsoleController' => 'applications/conduit/controller/PhabricatorConduitConsoleController.php',
     'PhabricatorConduitController' => 'applications/conduit/controller/PhabricatorConduitController.php',
     'PhabricatorConduitDAO' => 'applications/conduit/storage/PhabricatorConduitDAO.php',
     'PhabricatorConduitListController' => 'applications/conduit/controller/PhabricatorConduitListController.php',
     'PhabricatorConduitLogController' => 'applications/conduit/controller/PhabricatorConduitLogController.php',
     'PhabricatorConduitLogQuery' => 'applications/conduit/query/PhabricatorConduitLogQuery.php',
     'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
     'PhabricatorConduitMethodQuery' => 'applications/conduit/query/PhabricatorConduitMethodQuery.php',
     'PhabricatorConduitSearchEngine' => 'applications/conduit/query/PhabricatorConduitSearchEngine.php',
     'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php',
     'PhabricatorConfigAllController' => 'applications/config/controller/PhabricatorConfigAllController.php',
     'PhabricatorConfigApplication' => 'applications/config/application/PhabricatorConfigApplication.php',
     'PhabricatorConfigColumnSchema' => 'applications/config/schema/PhabricatorConfigColumnSchema.php',
     'PhabricatorConfigConfigPHIDType' => 'applications/config/phid/PhabricatorConfigConfigPHIDType.php',
     'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php',
     'PhabricatorConfigCoreSchemaSpec' => 'applications/config/schema/PhabricatorConfigCoreSchemaSpec.php',
     'PhabricatorConfigDatabaseController' => 'applications/config/controller/PhabricatorConfigDatabaseController.php',
     'PhabricatorConfigDatabaseIssueController' => 'applications/config/controller/PhabricatorConfigDatabaseIssueController.php',
     'PhabricatorConfigDatabaseSchema' => 'applications/config/schema/PhabricatorConfigDatabaseSchema.php',
     'PhabricatorConfigDatabaseSource' => 'infrastructure/env/PhabricatorConfigDatabaseSource.php',
     'PhabricatorConfigDatabaseStatusController' => 'applications/config/controller/PhabricatorConfigDatabaseStatusController.php',
     'PhabricatorConfigDefaultSource' => 'infrastructure/env/PhabricatorConfigDefaultSource.php',
     'PhabricatorConfigDictionarySource' => 'infrastructure/env/PhabricatorConfigDictionarySource.php',
     'PhabricatorConfigEditController' => 'applications/config/controller/PhabricatorConfigEditController.php',
     'PhabricatorConfigEditor' => 'applications/config/editor/PhabricatorConfigEditor.php',
     'PhabricatorConfigEntry' => 'applications/config/storage/PhabricatorConfigEntry.php',
     'PhabricatorConfigEntryDAO' => 'applications/config/storage/PhabricatorConfigEntryDAO.php',
     'PhabricatorConfigEntryQuery' => 'applications/config/query/PhabricatorConfigEntryQuery.php',
     'PhabricatorConfigFileSource' => 'infrastructure/env/PhabricatorConfigFileSource.php',
     'PhabricatorConfigGroupController' => 'applications/config/controller/PhabricatorConfigGroupController.php',
     'PhabricatorConfigIgnoreController' => 'applications/config/controller/PhabricatorConfigIgnoreController.php',
     'PhabricatorConfigIssueListController' => 'applications/config/controller/PhabricatorConfigIssueListController.php',
     'PhabricatorConfigIssueViewController' => 'applications/config/controller/PhabricatorConfigIssueViewController.php',
     'PhabricatorConfigJSON' => 'applications/config/json/PhabricatorConfigJSON.php',
     'PhabricatorConfigJSONOptionType' => 'applications/config/custom/PhabricatorConfigJSONOptionType.php',
     'PhabricatorConfigKeySchema' => 'applications/config/schema/PhabricatorConfigKeySchema.php',
     'PhabricatorConfigListController' => 'applications/config/controller/PhabricatorConfigListController.php',
     'PhabricatorConfigLocalSource' => 'infrastructure/env/PhabricatorConfigLocalSource.php',
     'PhabricatorConfigManagementDeleteWorkflow' => 'applications/config/management/PhabricatorConfigManagementDeleteWorkflow.php',
     'PhabricatorConfigManagementGetWorkflow' => 'applications/config/management/PhabricatorConfigManagementGetWorkflow.php',
     'PhabricatorConfigManagementListWorkflow' => 'applications/config/management/PhabricatorConfigManagementListWorkflow.php',
     'PhabricatorConfigManagementMigrateWorkflow' => 'applications/config/management/PhabricatorConfigManagementMigrateWorkflow.php',
     'PhabricatorConfigManagementSetWorkflow' => 'applications/config/management/PhabricatorConfigManagementSetWorkflow.php',
     'PhabricatorConfigManagementWorkflow' => 'applications/config/management/PhabricatorConfigManagementWorkflow.php',
     'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php',
     'PhabricatorConfigOptionType' => 'applications/config/custom/PhabricatorConfigOptionType.php',
     'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
     'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php',
     'PhabricatorConfigSchemaQuery' => 'applications/config/schema/PhabricatorConfigSchemaQuery.php',
     'PhabricatorConfigSchemaSpec' => 'applications/config/schema/PhabricatorConfigSchemaSpec.php',
     'PhabricatorConfigServerSchema' => 'applications/config/schema/PhabricatorConfigServerSchema.php',
     'PhabricatorConfigSiteSource' => 'infrastructure/env/PhabricatorConfigSiteSource.php',
     'PhabricatorConfigSource' => 'infrastructure/env/PhabricatorConfigSource.php',
     'PhabricatorConfigStackSource' => 'infrastructure/env/PhabricatorConfigStackSource.php',
     'PhabricatorConfigStorageSchema' => 'applications/config/schema/PhabricatorConfigStorageSchema.php',
     'PhabricatorConfigTableSchema' => 'applications/config/schema/PhabricatorConfigTableSchema.php',
     'PhabricatorConfigTransaction' => 'applications/config/storage/PhabricatorConfigTransaction.php',
     'PhabricatorConfigTransactionQuery' => 'applications/config/query/PhabricatorConfigTransactionQuery.php',
     'PhabricatorConfigValidationException' => 'applications/config/exception/PhabricatorConfigValidationException.php',
     'PhabricatorConfigWelcomeController' => 'applications/config/controller/PhabricatorConfigWelcomeController.php',
     'PhabricatorConpherenceApplication' => 'applications/conpherence/application/PhabricatorConpherenceApplication.php',
     'PhabricatorConpherenceThreadPHIDType' => 'applications/conpherence/phid/PhabricatorConpherenceThreadPHIDType.php',
     'PhabricatorConsoleApplication' => 'applications/console/application/PhabricatorConsoleApplication.php',
     'PhabricatorContentSource' => 'applications/metamta/contentsource/PhabricatorContentSource.php',
     'PhabricatorContentSourceView' => 'applications/metamta/contentsource/PhabricatorContentSourceView.php',
     'PhabricatorController' => 'applications/base/controller/PhabricatorController.php',
     'PhabricatorCookies' => 'applications/auth/constants/PhabricatorCookies.php',
     'PhabricatorCoreConfigOptions' => 'applications/config/option/PhabricatorCoreConfigOptions.php',
     'PhabricatorCountdown' => 'applications/countdown/storage/PhabricatorCountdown.php',
     'PhabricatorCountdownApplication' => 'applications/countdown/application/PhabricatorCountdownApplication.php',
     'PhabricatorCountdownController' => 'applications/countdown/controller/PhabricatorCountdownController.php',
     'PhabricatorCountdownCountdownPHIDType' => 'applications/countdown/phid/PhabricatorCountdownCountdownPHIDType.php',
     'PhabricatorCountdownDAO' => 'applications/countdown/storage/PhabricatorCountdownDAO.php',
     'PhabricatorCountdownDefaultViewCapability' => 'applications/countdown/capability/PhabricatorCountdownDefaultViewCapability.php',
     'PhabricatorCountdownDeleteController' => 'applications/countdown/controller/PhabricatorCountdownDeleteController.php',
     'PhabricatorCountdownEditController' => 'applications/countdown/controller/PhabricatorCountdownEditController.php',
     'PhabricatorCountdownListController' => 'applications/countdown/controller/PhabricatorCountdownListController.php',
     'PhabricatorCountdownQuery' => 'applications/countdown/query/PhabricatorCountdownQuery.php',
     'PhabricatorCountdownRemarkupRule' => 'applications/countdown/remarkup/PhabricatorCountdownRemarkupRule.php',
     'PhabricatorCountdownSearchEngine' => 'applications/countdown/query/PhabricatorCountdownSearchEngine.php',
     'PhabricatorCountdownView' => 'applications/countdown/view/PhabricatorCountdownView.php',
     'PhabricatorCountdownViewController' => 'applications/countdown/controller/PhabricatorCountdownViewController.php',
     'PhabricatorCrumbView' => 'view/layout/PhabricatorCrumbView.php',
     'PhabricatorCrumbsView' => 'view/layout/PhabricatorCrumbsView.php',
     'PhabricatorCursorPagedPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php',
     'PhabricatorCustomField' => 'infrastructure/customfield/field/PhabricatorCustomField.php',
     'PhabricatorCustomFieldAttachment' => 'infrastructure/customfield/field/PhabricatorCustomFieldAttachment.php',
     'PhabricatorCustomFieldConfigOptionType' => 'infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php',
     'PhabricatorCustomFieldDataNotAvailableException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldDataNotAvailableException.php',
     'PhabricatorCustomFieldImplementationIncompleteException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php',
     'PhabricatorCustomFieldIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldIndexStorage.php',
     'PhabricatorCustomFieldInterface' => 'infrastructure/customfield/interface/PhabricatorCustomFieldInterface.php',
     'PhabricatorCustomFieldList' => 'infrastructure/customfield/field/PhabricatorCustomFieldList.php',
     'PhabricatorCustomFieldMonogramParser' => 'infrastructure/customfield/parser/PhabricatorCustomFieldMonogramParser.php',
     'PhabricatorCustomFieldNotAttachedException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldNotAttachedException.php',
     'PhabricatorCustomFieldNotProxyException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldNotProxyException.php',
     'PhabricatorCustomFieldNumericIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldNumericIndexStorage.php',
     'PhabricatorCustomFieldStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldStorage.php',
     'PhabricatorCustomFieldStringIndexStorage' => 'infrastructure/customfield/storage/PhabricatorCustomFieldStringIndexStorage.php',
     'PhabricatorDaemon' => 'infrastructure/daemon/PhabricatorDaemon.php',
     'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/PhabricatorDaemonConsoleController.php',
     'PhabricatorDaemonController' => 'applications/daemon/controller/PhabricatorDaemonController.php',
     'PhabricatorDaemonDAO' => 'applications/daemon/storage/PhabricatorDaemonDAO.php',
     'PhabricatorDaemonEventListener' => 'applications/daemon/event/PhabricatorDaemonEventListener.php',
     'PhabricatorDaemonLog' => 'applications/daemon/storage/PhabricatorDaemonLog.php',
     'PhabricatorDaemonLogEvent' => 'applications/daemon/storage/PhabricatorDaemonLogEvent.php',
     'PhabricatorDaemonLogEventGarbageCollector' => 'applications/daemon/garbagecollector/PhabricatorDaemonLogEventGarbageCollector.php',
     'PhabricatorDaemonLogEventViewController' => 'applications/daemon/controller/PhabricatorDaemonLogEventViewController.php',
     'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/PhabricatorDaemonLogEventsView.php',
     'PhabricatorDaemonLogGarbageCollector' => 'applications/daemon/garbagecollector/PhabricatorDaemonLogGarbageCollector.php',
     'PhabricatorDaemonLogListController' => 'applications/daemon/controller/PhabricatorDaemonLogListController.php',
     'PhabricatorDaemonLogListView' => 'applications/daemon/view/PhabricatorDaemonLogListView.php',
     'PhabricatorDaemonLogQuery' => 'applications/daemon/query/PhabricatorDaemonLogQuery.php',
     'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/PhabricatorDaemonLogViewController.php',
     'PhabricatorDaemonManagementDebugWorkflow' => 'applications/daemon/management/PhabricatorDaemonManagementDebugWorkflow.php',
     'PhabricatorDaemonManagementLaunchWorkflow' => 'applications/daemon/management/PhabricatorDaemonManagementLaunchWorkflow.php',
     'PhabricatorDaemonManagementListWorkflow' => 'applications/daemon/management/PhabricatorDaemonManagementListWorkflow.php',
     'PhabricatorDaemonManagementLogWorkflow' => 'applications/daemon/management/PhabricatorDaemonManagementLogWorkflow.php',
     'PhabricatorDaemonManagementRestartWorkflow' => 'applications/daemon/management/PhabricatorDaemonManagementRestartWorkflow.php',
     'PhabricatorDaemonManagementStartWorkflow' => 'applications/daemon/management/PhabricatorDaemonManagementStartWorkflow.php',
     'PhabricatorDaemonManagementStatusWorkflow' => 'applications/daemon/management/PhabricatorDaemonManagementStatusWorkflow.php',
     'PhabricatorDaemonManagementStopWorkflow' => 'applications/daemon/management/PhabricatorDaemonManagementStopWorkflow.php',
     'PhabricatorDaemonManagementWorkflow' => 'applications/daemon/management/PhabricatorDaemonManagementWorkflow.php',
     'PhabricatorDaemonReference' => 'infrastructure/daemon/control/PhabricatorDaemonReference.php',
     'PhabricatorDaemonTaskGarbageCollector' => 'applications/daemon/garbagecollector/PhabricatorDaemonTaskGarbageCollector.php',
     'PhabricatorDaemonsApplication' => 'applications/daemon/application/PhabricatorDaemonsApplication.php',
     'PhabricatorDashboard' => 'applications/dashboard/storage/PhabricatorDashboard.php',
     'PhabricatorDashboardAddPanelController' => 'applications/dashboard/controller/PhabricatorDashboardAddPanelController.php',
     'PhabricatorDashboardApplication' => 'applications/dashboard/application/PhabricatorDashboardApplication.php',
     'PhabricatorDashboardController' => 'applications/dashboard/controller/PhabricatorDashboardController.php',
     'PhabricatorDashboardCopyController' => 'applications/dashboard/controller/PhabricatorDashboardCopyController.php',
     'PhabricatorDashboardDAO' => 'applications/dashboard/storage/PhabricatorDashboardDAO.php',
     'PhabricatorDashboardDashboardPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardDashboardPHIDType.php',
     'PhabricatorDashboardEditController' => 'applications/dashboard/controller/PhabricatorDashboardEditController.php',
     'PhabricatorDashboardHistoryController' => 'applications/dashboard/controller/PhabricatorDashboardHistoryController.php',
     'PhabricatorDashboardInstall' => 'applications/dashboard/storage/PhabricatorDashboardInstall.php',
     'PhabricatorDashboardInstallController' => 'applications/dashboard/controller/PhabricatorDashboardInstallController.php',
     'PhabricatorDashboardLayoutConfig' => 'applications/dashboard/layoutconfig/PhabricatorDashboardLayoutConfig.php',
     'PhabricatorDashboardListController' => 'applications/dashboard/controller/PhabricatorDashboardListController.php',
     'PhabricatorDashboardManageController' => 'applications/dashboard/controller/PhabricatorDashboardManageController.php',
     'PhabricatorDashboardMovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardMovePanelController.php',
     'PhabricatorDashboardPanel' => 'applications/dashboard/storage/PhabricatorDashboardPanel.php',
     'PhabricatorDashboardPanelArchiveController' => 'applications/dashboard/controller/PhabricatorDashboardPanelArchiveController.php',
     'PhabricatorDashboardPanelCoreCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCoreCustomField.php',
     'PhabricatorDashboardPanelCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelCustomField.php',
     'PhabricatorDashboardPanelEditController' => 'applications/dashboard/controller/PhabricatorDashboardPanelEditController.php',
     'PhabricatorDashboardPanelListController' => 'applications/dashboard/controller/PhabricatorDashboardPanelListController.php',
     'PhabricatorDashboardPanelPHIDType' => 'applications/dashboard/phid/PhabricatorDashboardPanelPHIDType.php',
     'PhabricatorDashboardPanelQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelQuery.php',
     'PhabricatorDashboardPanelRenderController' => 'applications/dashboard/controller/PhabricatorDashboardPanelRenderController.php',
     'PhabricatorDashboardPanelRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php',
     'PhabricatorDashboardPanelSearchApplicationCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelSearchApplicationCustomField.php',
     'PhabricatorDashboardPanelSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php',
     'PhabricatorDashboardPanelSearchQueryCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelSearchQueryCustomField.php',
     'PhabricatorDashboardPanelTabsCustomField' => 'applications/dashboard/customfield/PhabricatorDashboardPanelTabsCustomField.php',
     'PhabricatorDashboardPanelTransaction' => 'applications/dashboard/storage/PhabricatorDashboardPanelTransaction.php',
     'PhabricatorDashboardPanelTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php',
     'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php',
     'PhabricatorDashboardPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelType.php',
     'PhabricatorDashboardPanelTypeQuery' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeQuery.php',
     'PhabricatorDashboardPanelTypeTabs' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeTabs.php',
     'PhabricatorDashboardPanelTypeText' => 'applications/dashboard/paneltype/PhabricatorDashboardPanelTypeText.php',
     'PhabricatorDashboardPanelViewController' => 'applications/dashboard/controller/PhabricatorDashboardPanelViewController.php',
     'PhabricatorDashboardQuery' => 'applications/dashboard/query/PhabricatorDashboardQuery.php',
     'PhabricatorDashboardRemarkupRule' => 'applications/dashboard/remarkup/PhabricatorDashboardRemarkupRule.php',
     'PhabricatorDashboardRemovePanelController' => 'applications/dashboard/controller/PhabricatorDashboardRemovePanelController.php',
     'PhabricatorDashboardRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php',
     'PhabricatorDashboardSchemaSpec' => 'applications/dashboard/storage/PhabricatorDashboardSchemaSpec.php',
     'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php',
     'PhabricatorDashboardTransaction' => 'applications/dashboard/storage/PhabricatorDashboardTransaction.php',
     'PhabricatorDashboardTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardTransactionEditor.php',
     'PhabricatorDashboardTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardTransactionQuery.php',
     'PhabricatorDashboardUninstallController' => 'applications/dashboard/controller/PhabricatorDashboardUninstallController.php',
     'PhabricatorDashboardViewController' => 'applications/dashboard/controller/PhabricatorDashboardViewController.php',
     'PhabricatorDataNotAttachedException' => 'infrastructure/storage/lisk/PhabricatorDataNotAttachedException.php',
     'PhabricatorDebugController' => 'applications/system/controller/PhabricatorDebugController.php',
     'PhabricatorDefaultFileStorageEngineSelector' => 'applications/files/engineselector/PhabricatorDefaultFileStorageEngineSelector.php',
     'PhabricatorDefaultSearchEngineSelector' => 'applications/search/selector/PhabricatorDefaultSearchEngineSelector.php',
     'PhabricatorDestructibleInterface' => 'applications/system/interface/PhabricatorDestructibleInterface.php',
     'PhabricatorDestructionEngine' => 'applications/system/engine/PhabricatorDestructionEngine.php',
     'PhabricatorDeveloperConfigOptions' => 'applications/config/option/PhabricatorDeveloperConfigOptions.php',
     'PhabricatorDifferenceEngine' => 'infrastructure/diff/PhabricatorDifferenceEngine.php',
     'PhabricatorDifferentialApplication' => 'applications/differential/application/PhabricatorDifferentialApplication.php',
     'PhabricatorDifferentialConfigOptions' => 'applications/differential/config/PhabricatorDifferentialConfigOptions.php',
     'PhabricatorDifferentialRevisionTestDataGenerator' => 'applications/differential/lipsum/PhabricatorDifferentialRevisionTestDataGenerator.php',
     'PhabricatorDiffusionApplication' => 'applications/diffusion/application/PhabricatorDiffusionApplication.php',
     'PhabricatorDiffusionConfigOptions' => 'applications/diffusion/config/PhabricatorDiffusionConfigOptions.php',
     'PhabricatorDisabledUserController' => 'applications/auth/controller/PhabricatorDisabledUserController.php',
     'PhabricatorDisqusAuthProvider' => 'applications/auth/provider/PhabricatorDisqusAuthProvider.php',
     'PhabricatorDisqusConfigOptions' => 'applications/config/option/PhabricatorDisqusConfigOptions.php',
     'PhabricatorDivinerApplication' => 'applications/diviner/application/PhabricatorDivinerApplication.php',
     'PhabricatorDoorkeeperApplication' => 'applications/doorkeeper/application/PhabricatorDoorkeeperApplication.php',
     'PhabricatorDraft' => 'applications/draft/storage/PhabricatorDraft.php',
     'PhabricatorDraftDAO' => 'applications/draft/storage/PhabricatorDraftDAO.php',
     'PhabricatorDrydockApplication' => 'applications/drydock/application/PhabricatorDrydockApplication.php',
     'PhabricatorEdgeConfig' => 'infrastructure/edges/constants/PhabricatorEdgeConfig.php',
     'PhabricatorEdgeConstants' => 'infrastructure/edges/constants/PhabricatorEdgeConstants.php',
     'PhabricatorEdgeCycleException' => 'infrastructure/edges/exception/PhabricatorEdgeCycleException.php',
     'PhabricatorEdgeEditor' => 'infrastructure/edges/editor/PhabricatorEdgeEditor.php',
     'PhabricatorEdgeGraph' => 'infrastructure/edges/util/PhabricatorEdgeGraph.php',
     'PhabricatorEdgeQuery' => 'infrastructure/edges/query/PhabricatorEdgeQuery.php',
     'PhabricatorEdgeTestCase' => 'infrastructure/edges/__tests__/PhabricatorEdgeTestCase.php',
     'PhabricatorEdgeType' => 'infrastructure/edges/type/PhabricatorEdgeType.php',
     'PhabricatorEditor' => 'infrastructure/PhabricatorEditor.php',
     'PhabricatorEmailLoginController' => 'applications/auth/controller/PhabricatorEmailLoginController.php',
     'PhabricatorEmailVerificationController' => 'applications/auth/controller/PhabricatorEmailVerificationController.php',
     'PhabricatorEmbedFileRemarkupRule' => 'applications/files/markup/PhabricatorEmbedFileRemarkupRule.php',
     'PhabricatorEmojiRemarkupRule' => 'applications/macro/markup/PhabricatorEmojiRemarkupRule.php',
     'PhabricatorEmptyQueryException' => 'infrastructure/query/PhabricatorEmptyQueryException.php',
     'PhabricatorEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorEnglishTranslation.php',
     'PhabricatorEnv' => 'infrastructure/env/PhabricatorEnv.php',
     'PhabricatorEnvTestCase' => 'infrastructure/env/__tests__/PhabricatorEnvTestCase.php',
     'PhabricatorErrorExample' => 'applications/uiexample/examples/PhabricatorErrorExample.php',
     'PhabricatorEvent' => 'infrastructure/events/PhabricatorEvent.php',
     'PhabricatorEventEngine' => 'infrastructure/events/PhabricatorEventEngine.php',
     'PhabricatorEventListener' => 'infrastructure/events/PhabricatorEventListener.php',
     'PhabricatorEventType' => 'infrastructure/events/constant/PhabricatorEventType.php',
     'PhabricatorExampleEventListener' => 'infrastructure/events/PhabricatorExampleEventListener.php',
     'PhabricatorExtendingPhabricatorConfigOptions' => 'applications/config/option/PhabricatorExtendingPhabricatorConfigOptions.php',
     'PhabricatorExternalAccount' => 'applications/people/storage/PhabricatorExternalAccount.php',
     'PhabricatorExternalAccountQuery' => 'applications/auth/query/PhabricatorExternalAccountQuery.php',
     'PhabricatorFacebookAuthProvider' => 'applications/auth/provider/PhabricatorFacebookAuthProvider.php',
     'PhabricatorFactAggregate' => 'applications/fact/storage/PhabricatorFactAggregate.php',
     'PhabricatorFactApplication' => 'applications/fact/application/PhabricatorFactApplication.php',
     'PhabricatorFactChartController' => 'applications/fact/controller/PhabricatorFactChartController.php',
     'PhabricatorFactController' => 'applications/fact/controller/PhabricatorFactController.php',
     'PhabricatorFactCountEngine' => 'applications/fact/engine/PhabricatorFactCountEngine.php',
     'PhabricatorFactCursor' => 'applications/fact/storage/PhabricatorFactCursor.php',
     'PhabricatorFactDAO' => 'applications/fact/storage/PhabricatorFactDAO.php',
     'PhabricatorFactDaemon' => 'applications/fact/daemon/PhabricatorFactDaemon.php',
     'PhabricatorFactEngine' => 'applications/fact/engine/PhabricatorFactEngine.php',
     'PhabricatorFactHomeController' => 'applications/fact/controller/PhabricatorFactHomeController.php',
     'PhabricatorFactLastUpdatedEngine' => 'applications/fact/engine/PhabricatorFactLastUpdatedEngine.php',
     'PhabricatorFactManagementAnalyzeWorkflow' => 'applications/fact/management/PhabricatorFactManagementAnalyzeWorkflow.php',
     'PhabricatorFactManagementCursorsWorkflow' => 'applications/fact/management/PhabricatorFactManagementCursorsWorkflow.php',
     'PhabricatorFactManagementDestroyWorkflow' => 'applications/fact/management/PhabricatorFactManagementDestroyWorkflow.php',
     'PhabricatorFactManagementListWorkflow' => 'applications/fact/management/PhabricatorFactManagementListWorkflow.php',
     'PhabricatorFactManagementStatusWorkflow' => 'applications/fact/management/PhabricatorFactManagementStatusWorkflow.php',
     'PhabricatorFactManagementWorkflow' => 'applications/fact/management/PhabricatorFactManagementWorkflow.php',
     'PhabricatorFactRaw' => 'applications/fact/storage/PhabricatorFactRaw.php',
     'PhabricatorFactSimpleSpec' => 'applications/fact/spec/PhabricatorFactSimpleSpec.php',
     'PhabricatorFactSpec' => 'applications/fact/spec/PhabricatorFactSpec.php',
     'PhabricatorFactUpdateIterator' => 'applications/fact/extract/PhabricatorFactUpdateIterator.php',
     'PhabricatorFeedApplication' => 'applications/feed/application/PhabricatorFeedApplication.php',
     'PhabricatorFeedBuilder' => 'applications/feed/builder/PhabricatorFeedBuilder.php',
     'PhabricatorFeedConfigOptions' => 'applications/feed/config/PhabricatorFeedConfigOptions.php',
     'PhabricatorFeedConstants' => 'applications/feed/constants/PhabricatorFeedConstants.php',
     'PhabricatorFeedController' => 'applications/feed/controller/PhabricatorFeedController.php',
     'PhabricatorFeedDAO' => 'applications/feed/storage/PhabricatorFeedDAO.php',
     'PhabricatorFeedDetailController' => 'applications/feed/controller/PhabricatorFeedDetailController.php',
     'PhabricatorFeedListController' => 'applications/feed/controller/PhabricatorFeedListController.php',
     'PhabricatorFeedManagementRepublishWorkflow' => 'applications/feed/management/PhabricatorFeedManagementRepublishWorkflow.php',
     'PhabricatorFeedManagementWorkflow' => 'applications/feed/management/PhabricatorFeedManagementWorkflow.php',
     'PhabricatorFeedPublicStreamController' => 'applications/feed/controller/PhabricatorFeedPublicStreamController.php',
     'PhabricatorFeedQuery' => 'applications/feed/query/PhabricatorFeedQuery.php',
     'PhabricatorFeedSearchEngine' => 'applications/feed/query/PhabricatorFeedSearchEngine.php',
     'PhabricatorFeedStory' => 'applications/feed/story/PhabricatorFeedStory.php',
     'PhabricatorFeedStoryAggregate' => 'applications/feed/story/PhabricatorFeedStoryAggregate.php',
     'PhabricatorFeedStoryAudit' => 'applications/feed/story/PhabricatorFeedStoryAudit.php',
     'PhabricatorFeedStoryCommit' => 'applications/feed/story/PhabricatorFeedStoryCommit.php',
     'PhabricatorFeedStoryData' => 'applications/feed/storage/PhabricatorFeedStoryData.php',
     'PhabricatorFeedStoryDifferential' => 'applications/feed/story/PhabricatorFeedStoryDifferential.php',
     'PhabricatorFeedStoryDifferentialAggregate' => 'applications/feed/story/PhabricatorFeedStoryDifferentialAggregate.php',
     'PhabricatorFeedStoryManiphestAggregate' => 'applications/feed/story/PhabricatorFeedStoryManiphestAggregate.php',
     'PhabricatorFeedStoryNotification' => 'applications/notification/storage/PhabricatorFeedStoryNotification.php',
     'PhabricatorFeedStoryPhriction' => 'applications/feed/story/PhabricatorFeedStoryPhriction.php',
     'PhabricatorFeedStoryPublisher' => 'applications/feed/PhabricatorFeedStoryPublisher.php',
     'PhabricatorFeedStoryReference' => 'applications/feed/storage/PhabricatorFeedStoryReference.php',
     'PhabricatorFeedStoryStatus' => 'applications/feed/story/PhabricatorFeedStoryStatus.php',
     'PhabricatorFeedStoryTypeConstants' => 'applications/feed/constants/PhabricatorFeedStoryTypeConstants.php',
     'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.php',
     'PhabricatorFileBundleLoader' => 'applications/files/query/PhabricatorFileBundleLoader.php',
     'PhabricatorFileCommentController' => 'applications/files/controller/PhabricatorFileCommentController.php',
     'PhabricatorFileComposeController' => 'applications/files/controller/PhabricatorFileComposeController.php',
     'PhabricatorFileController' => 'applications/files/controller/PhabricatorFileController.php',
     'PhabricatorFileDAO' => 'applications/files/storage/PhabricatorFileDAO.php',
     'PhabricatorFileDataController' => 'applications/files/controller/PhabricatorFileDataController.php',
     'PhabricatorFileDeleteController' => 'applications/files/controller/PhabricatorFileDeleteController.php',
     'PhabricatorFileDropUploadController' => 'applications/files/controller/PhabricatorFileDropUploadController.php',
     'PhabricatorFileEditController' => 'applications/files/controller/PhabricatorFileEditController.php',
     'PhabricatorFileEditor' => 'applications/files/editor/PhabricatorFileEditor.php',
     'PhabricatorFileFilePHIDType' => 'applications/files/phid/PhabricatorFileFilePHIDType.php',
     'PhabricatorFileImageMacro' => 'applications/macro/storage/PhabricatorFileImageMacro.php',
     'PhabricatorFileInfoController' => 'applications/files/controller/PhabricatorFileInfoController.php',
     'PhabricatorFileLinkListView' => 'view/layout/PhabricatorFileLinkListView.php',
     'PhabricatorFileLinkView' => 'view/layout/PhabricatorFileLinkView.php',
     'PhabricatorFileListController' => 'applications/files/controller/PhabricatorFileListController.php',
     'PhabricatorFileQuery' => 'applications/files/query/PhabricatorFileQuery.php',
     'PhabricatorFileSchemaSpec' => 'applications/files/storage/PhabricatorFileSchemaSpec.php',
     'PhabricatorFileSearchEngine' => 'applications/files/query/PhabricatorFileSearchEngine.php',
     'PhabricatorFileStorageBlob' => 'applications/files/storage/PhabricatorFileStorageBlob.php',
     'PhabricatorFileStorageConfigurationException' => 'applications/files/exception/PhabricatorFileStorageConfigurationException.php',
     'PhabricatorFileStorageEngine' => 'applications/files/engine/PhabricatorFileStorageEngine.php',
     'PhabricatorFileStorageEngineSelector' => 'applications/files/engineselector/PhabricatorFileStorageEngineSelector.php',
     'PhabricatorFileTemporaryGarbageCollector' => 'applications/files/garbagecollector/PhabricatorFileTemporaryGarbageCollector.php',
     'PhabricatorFileTestCase' => 'applications/files/storage/__tests__/PhabricatorFileTestCase.php',
     'PhabricatorFileTestDataGenerator' => 'applications/files/lipsum/PhabricatorFileTestDataGenerator.php',
     'PhabricatorFileTransaction' => 'applications/files/storage/PhabricatorFileTransaction.php',
     'PhabricatorFileTransactionComment' => 'applications/files/storage/PhabricatorFileTransactionComment.php',
     'PhabricatorFileTransactionQuery' => 'applications/files/query/PhabricatorFileTransactionQuery.php',
     'PhabricatorFileTransformController' => 'applications/files/controller/PhabricatorFileTransformController.php',
     'PhabricatorFileUploadController' => 'applications/files/controller/PhabricatorFileUploadController.php',
     'PhabricatorFileUploadDialogController' => 'applications/files/controller/PhabricatorFileUploadDialogController.php',
     'PhabricatorFileUploadException' => 'applications/files/exception/PhabricatorFileUploadException.php',
     'PhabricatorFilesApplication' => 'applications/files/application/PhabricatorFilesApplication.php',
     'PhabricatorFilesConfigOptions' => 'applications/files/config/PhabricatorFilesConfigOptions.php',
     'PhabricatorFilesManagementCompactWorkflow' => 'applications/files/management/PhabricatorFilesManagementCompactWorkflow.php',
     'PhabricatorFilesManagementEnginesWorkflow' => 'applications/files/management/PhabricatorFilesManagementEnginesWorkflow.php',
     'PhabricatorFilesManagementMigrateWorkflow' => 'applications/files/management/PhabricatorFilesManagementMigrateWorkflow.php',
     'PhabricatorFilesManagementPurgeWorkflow' => 'applications/files/management/PhabricatorFilesManagementPurgeWorkflow.php',
     'PhabricatorFilesManagementRebuildWorkflow' => 'applications/files/management/PhabricatorFilesManagementRebuildWorkflow.php',
     'PhabricatorFilesManagementWorkflow' => 'applications/files/management/PhabricatorFilesManagementWorkflow.php',
     'PhabricatorFlag' => 'applications/flag/storage/PhabricatorFlag.php',
     'PhabricatorFlagColor' => 'applications/flag/constants/PhabricatorFlagColor.php',
     'PhabricatorFlagConstants' => 'applications/flag/constants/PhabricatorFlagConstants.php',
     'PhabricatorFlagController' => 'applications/flag/controller/PhabricatorFlagController.php',
     'PhabricatorFlagDAO' => 'applications/flag/storage/PhabricatorFlagDAO.php',
     'PhabricatorFlagDeleteController' => 'applications/flag/controller/PhabricatorFlagDeleteController.php',
     'PhabricatorFlagEditController' => 'applications/flag/controller/PhabricatorFlagEditController.php',
     'PhabricatorFlagListController' => 'applications/flag/controller/PhabricatorFlagListController.php',
     'PhabricatorFlagQuery' => 'applications/flag/query/PhabricatorFlagQuery.php',
     'PhabricatorFlagSearchEngine' => 'applications/flag/query/PhabricatorFlagSearchEngine.php',
     'PhabricatorFlagSelectControl' => 'applications/flag/view/PhabricatorFlagSelectControl.php',
     'PhabricatorFlaggableInterface' => 'applications/flag/interface/PhabricatorFlaggableInterface.php',
     'PhabricatorFlagsApplication' => 'applications/flag/application/PhabricatorFlagsApplication.php',
     'PhabricatorFlagsUIEventListener' => 'applications/flag/events/PhabricatorFlagsUIEventListener.php',
     'PhabricatorFormExample' => 'applications/uiexample/examples/PhabricatorFormExample.php',
     'PhabricatorFundApplication' => 'applications/fund/application/PhabricatorFundApplication.php',
     'PhabricatorGarbageCollector' => 'infrastructure/daemon/garbagecollector/PhabricatorGarbageCollector.php',
     'PhabricatorGarbageCollectorConfigOptions' => 'applications/config/option/PhabricatorGarbageCollectorConfigOptions.php',
     'PhabricatorGarbageCollectorDaemon' => 'infrastructure/daemon/garbagecollector/PhabricatorGarbageCollectorDaemon.php',
     'PhabricatorGestureExample' => 'applications/uiexample/examples/PhabricatorGestureExample.php',
     'PhabricatorGitGraphStream' => 'applications/repository/daemon/PhabricatorGitGraphStream.php',
     'PhabricatorGitHubAuthProvider' => 'applications/auth/provider/PhabricatorGitHubAuthProvider.php',
     'PhabricatorGlobalLock' => 'infrastructure/util/PhabricatorGlobalLock.php',
     'PhabricatorGlobalUploadTargetView' => 'applications/files/view/PhabricatorGlobalUploadTargetView.php',
     'PhabricatorGoogleAuthProvider' => 'applications/auth/provider/PhabricatorGoogleAuthProvider.php',
     'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/PhabricatorHandleObjectSelectorDataView.php',
     'PhabricatorHandleQuery' => 'applications/phid/query/PhabricatorHandleQuery.php',
     'PhabricatorHarbormasterApplication' => 'applications/harbormaster/application/PhabricatorHarbormasterApplication.php',
     'PhabricatorHarbormasterConfigOptions' => 'applications/harbormaster/config/PhabricatorHarbormasterConfigOptions.php',
     'PhabricatorHash' => 'infrastructure/util/PhabricatorHash.php',
     'PhabricatorHashTestCase' => 'infrastructure/util/__tests__/PhabricatorHashTestCase.php',
     'PhabricatorHelpApplication' => 'applications/help/application/PhabricatorHelpApplication.php',
     'PhabricatorHelpController' => 'applications/help/controller/PhabricatorHelpController.php',
     'PhabricatorHelpEditorProtocolController' => 'applications/help/controller/PhabricatorHelpEditorProtocolController.php',
     'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php',
     'PhabricatorHeraldApplication' => 'applications/herald/application/PhabricatorHeraldApplication.php',
     'PhabricatorHomeApplication' => 'applications/home/application/PhabricatorHomeApplication.php',
     'PhabricatorHomeController' => 'applications/home/controller/PhabricatorHomeController.php',
     'PhabricatorHomeMainController' => 'applications/home/controller/PhabricatorHomeMainController.php',
     'PhabricatorHomeQuickCreateController' => 'applications/home/controller/PhabricatorHomeQuickCreateController.php',
     'PhabricatorHovercardExample' => 'applications/uiexample/examples/PhabricatorHovercardExample.php',
     'PhabricatorHovercardView' => 'view/widget/hovercard/PhabricatorHovercardView.php',
     'PhabricatorHunksManagementMigrateWorkflow' => 'applications/differential/management/PhabricatorHunksManagementMigrateWorkflow.php',
     'PhabricatorHunksManagementWorkflow' => 'applications/differential/management/PhabricatorHunksManagementWorkflow.php',
     'PhabricatorIRCProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorIRCProtocolAdapter.php',
     'PhabricatorIconRemarkupRule' => 'applications/macro/markup/PhabricatorIconRemarkupRule.php',
     'PhabricatorImageMacroRemarkupRule' => 'applications/macro/markup/PhabricatorImageMacroRemarkupRule.php',
     'PhabricatorImageTransformer' => 'applications/files/PhabricatorImageTransformer.php',
     'PhabricatorInfrastructureTestCase' => '__tests__/PhabricatorInfrastructureTestCase.php',
     'PhabricatorInlineCommentController' => 'infrastructure/diff/PhabricatorInlineCommentController.php',
     'PhabricatorInlineCommentInterface' => 'infrastructure/diff/interface/PhabricatorInlineCommentInterface.php',
     'PhabricatorInlineCommentPreviewController' => 'infrastructure/diff/PhabricatorInlineCommentPreviewController.php',
     'PhabricatorInlineSummaryView' => 'infrastructure/diff/view/PhabricatorInlineSummaryView.php',
     'PhabricatorInternationalizationManagementExtractWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementExtractWorkflow.php',
     'PhabricatorInternationalizationManagementWorkflow' => 'infrastructure/internationalization/management/PhabricatorInternationalizationManagementWorkflow.php',
     'PhabricatorIteratedMD5PasswordHasher' => 'infrastructure/util/password/PhabricatorIteratedMD5PasswordHasher.php',
     'PhabricatorJIRAAuthProvider' => 'applications/auth/provider/PhabricatorJIRAAuthProvider.php',
     'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
     'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php',
     'PhabricatorKeyValueDatabaseCache' => 'applications/cache/PhabricatorKeyValueDatabaseCache.php',
     'PhabricatorLDAPAuthProvider' => 'applications/auth/provider/PhabricatorLDAPAuthProvider.php',
     'PhabricatorLegacyEdgeType' => 'infrastructure/edges/type/PhabricatorLegacyEdgeType.php',
     'PhabricatorLegalpadApplication' => 'applications/legalpad/application/PhabricatorLegalpadApplication.php',
     'PhabricatorLegalpadConfigOptions' => 'applications/legalpad/config/PhabricatorLegalpadConfigOptions.php',
     'PhabricatorLegalpadDocumentPHIDType' => 'applications/legalpad/phid/PhabricatorLegalpadDocumentPHIDType.php',
     'PhabricatorLipsumArtist' => 'applications/lipsum/image/PhabricatorLipsumArtist.php',
     'PhabricatorLipsumGenerateWorkflow' => 'applications/lipsum/management/PhabricatorLipsumGenerateWorkflow.php',
     'PhabricatorLipsumManagementWorkflow' => 'applications/lipsum/management/PhabricatorLipsumManagementWorkflow.php',
     'PhabricatorLipsumMondrianArtist' => 'applications/lipsum/image/PhabricatorLipsumMondrianArtist.php',
     'PhabricatorLiskDAO' => 'infrastructure/storage/lisk/PhabricatorLiskDAO.php',
     'PhabricatorLiskSerializer' => 'infrastructure/storage/lisk/PhabricatorLiskSerializer.php',
     'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php',
     'PhabricatorLocalTimeTestCase' => 'view/__tests__/PhabricatorLocalTimeTestCase.php',
     'PhabricatorLogoutController' => 'applications/auth/controller/PhabricatorLogoutController.php',
     'PhabricatorMacroApplication' => 'applications/macro/application/PhabricatorMacroApplication.php',
     'PhabricatorMacroAudioController' => 'applications/macro/controller/PhabricatorMacroAudioController.php',
     'PhabricatorMacroCommentController' => 'applications/macro/controller/PhabricatorMacroCommentController.php',
     'PhabricatorMacroConfigOptions' => 'applications/macro/config/PhabricatorMacroConfigOptions.php',
     'PhabricatorMacroController' => 'applications/macro/controller/PhabricatorMacroController.php',
     'PhabricatorMacroDatasource' => 'applications/macro/typeahead/PhabricatorMacroDatasource.php',
     'PhabricatorMacroDisableController' => 'applications/macro/controller/PhabricatorMacroDisableController.php',
     'PhabricatorMacroEditController' => 'applications/macro/controller/PhabricatorMacroEditController.php',
     'PhabricatorMacroEditor' => 'applications/macro/editor/PhabricatorMacroEditor.php',
     'PhabricatorMacroListController' => 'applications/macro/controller/PhabricatorMacroListController.php',
     'PhabricatorMacroMacroPHIDType' => 'applications/macro/phid/PhabricatorMacroMacroPHIDType.php',
     'PhabricatorMacroMailReceiver' => 'applications/macro/mail/PhabricatorMacroMailReceiver.php',
     'PhabricatorMacroManageCapability' => 'applications/macro/capability/PhabricatorMacroManageCapability.php',
     'PhabricatorMacroMemeController' => 'applications/macro/controller/PhabricatorMacroMemeController.php',
     'PhabricatorMacroMemeDialogController' => 'applications/macro/controller/PhabricatorMacroMemeDialogController.php',
     'PhabricatorMacroQuery' => 'applications/macro/query/PhabricatorMacroQuery.php',
     'PhabricatorMacroReplyHandler' => 'applications/macro/mail/PhabricatorMacroReplyHandler.php',
     'PhabricatorMacroSearchEngine' => 'applications/macro/query/PhabricatorMacroSearchEngine.php',
     'PhabricatorMacroTransaction' => 'applications/macro/storage/PhabricatorMacroTransaction.php',
     'PhabricatorMacroTransactionComment' => 'applications/macro/storage/PhabricatorMacroTransactionComment.php',
     'PhabricatorMacroTransactionQuery' => 'applications/macro/query/PhabricatorMacroTransactionQuery.php',
     'PhabricatorMacroTransactionType' => 'applications/macro/constants/PhabricatorMacroTransactionType.php',
     'PhabricatorMacroViewController' => 'applications/macro/controller/PhabricatorMacroViewController.php',
     'PhabricatorMail' => 'applications/metamta/PhabricatorMail.php',
     'PhabricatorMailImplementationAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationAdapter.php',
     'PhabricatorMailImplementationAmazonSESAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationAmazonSESAdapter.php',
     'PhabricatorMailImplementationMailgunAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationMailgunAdapter.php',
     'PhabricatorMailImplementationPHPMailerAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php',
     'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php',
     'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php',
     'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php',
     'PhabricatorMailManagementListInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementListInboundWorkflow.php',
     'PhabricatorMailManagementListOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementListOutboundWorkflow.php',
     'PhabricatorMailManagementReceiveTestWorkflow' => 'applications/metamta/management/PhabricatorMailManagementReceiveTestWorkflow.php',
     'PhabricatorMailManagementResendWorkflow' => 'applications/metamta/management/PhabricatorMailManagementResendWorkflow.php',
     'PhabricatorMailManagementSendTestWorkflow' => 'applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php',
     'PhabricatorMailManagementShowInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowInboundWorkflow.php',
     'PhabricatorMailManagementShowOutboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementShowOutboundWorkflow.php',
     'PhabricatorMailManagementWorkflow' => 'applications/metamta/management/PhabricatorMailManagementWorkflow.php',
     'PhabricatorMailReceiver' => 'applications/metamta/receiver/PhabricatorMailReceiver.php',
     'PhabricatorMailReceiverTestCase' => 'applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php',
     'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/PhabricatorMailReplyHandler.php',
     'PhabricatorMailgunConfigOptions' => 'applications/config/option/PhabricatorMailgunConfigOptions.php',
     'PhabricatorMailingListDatasource' => 'applications/mailinglists/typeahead/PhabricatorMailingListDatasource.php',
     'PhabricatorMailingListListPHIDType' => 'applications/mailinglists/phid/PhabricatorMailingListListPHIDType.php',
     'PhabricatorMailingListQuery' => 'applications/mailinglists/query/PhabricatorMailingListQuery.php',
     'PhabricatorMailingListSearchEngine' => 'applications/mailinglists/query/PhabricatorMailingListSearchEngine.php',
     'PhabricatorMailingListsApplication' => 'applications/mailinglists/application/PhabricatorMailingListsApplication.php',
     'PhabricatorMailingListsController' => 'applications/mailinglists/controller/PhabricatorMailingListsController.php',
     'PhabricatorMailingListsEditController' => 'applications/mailinglists/controller/PhabricatorMailingListsEditController.php',
     'PhabricatorMailingListsListController' => 'applications/mailinglists/controller/PhabricatorMailingListsListController.php',
     'PhabricatorMainMenuGroupView' => 'view/page/menu/PhabricatorMainMenuGroupView.php',
     'PhabricatorMainMenuIconView' => 'view/page/menu/PhabricatorMainMenuIconView.php',
     'PhabricatorMainMenuSearchView' => 'view/page/menu/PhabricatorMainMenuSearchView.php',
     'PhabricatorMainMenuView' => 'view/page/menu/PhabricatorMainMenuView.php',
     'PhabricatorManagementWorkflow' => 'infrastructure/management/PhabricatorManagementWorkflow.php',
     'PhabricatorManiphestApplication' => 'applications/maniphest/application/PhabricatorManiphestApplication.php',
     'PhabricatorManiphestConfigOptions' => 'applications/maniphest/config/PhabricatorManiphestConfigOptions.php',
     'PhabricatorManiphestTaskTestDataGenerator' => 'applications/maniphest/lipsum/PhabricatorManiphestTaskTestDataGenerator.php',
     'PhabricatorMarkupCache' => 'applications/cache/storage/PhabricatorMarkupCache.php',
     'PhabricatorMarkupEngine' => 'infrastructure/markup/PhabricatorMarkupEngine.php',
     'PhabricatorMarkupInterface' => 'infrastructure/markup/PhabricatorMarkupInterface.php',
     'PhabricatorMarkupOneOff' => 'infrastructure/markup/PhabricatorMarkupOneOff.php',
     'PhabricatorMarkupPreviewController' => 'infrastructure/markup/PhabricatorMarkupPreviewController.php',
     'PhabricatorMemeRemarkupRule' => 'applications/macro/markup/PhabricatorMemeRemarkupRule.php',
     'PhabricatorMentionRemarkupRule' => 'applications/people/markup/PhabricatorMentionRemarkupRule.php',
     'PhabricatorMentionableInterface' => 'applications/transactions/interface/PhabricatorMentionableInterface.php',
     'PhabricatorMercurialGraphStream' => 'applications/repository/daemon/PhabricatorMercurialGraphStream.php',
     'PhabricatorMetaMTAActor' => 'applications/metamta/query/PhabricatorMetaMTAActor.php',
     'PhabricatorMetaMTAActorQuery' => 'applications/metamta/query/PhabricatorMetaMTAActorQuery.php',
     'PhabricatorMetaMTAApplication' => 'applications/metamta/application/PhabricatorMetaMTAApplication.php',
     'PhabricatorMetaMTAAttachment' => 'applications/metamta/storage/PhabricatorMetaMTAAttachment.php',
     'PhabricatorMetaMTAConfigOptions' => 'applications/config/option/PhabricatorMetaMTAConfigOptions.php',
     'PhabricatorMetaMTAController' => 'applications/metamta/controller/PhabricatorMetaMTAController.php',
     'PhabricatorMetaMTADAO' => 'applications/metamta/storage/PhabricatorMetaMTADAO.php',
     'PhabricatorMetaMTAEmailBodyParser' => 'applications/metamta/parser/PhabricatorMetaMTAEmailBodyParser.php',
     'PhabricatorMetaMTAEmailBodyParserTestCase' => 'applications/metamta/parser/__tests__/PhabricatorMetaMTAEmailBodyParserTestCase.php',
     'PhabricatorMetaMTAErrorMailAction' => 'applications/metamta/action/PhabricatorMetaMTAErrorMailAction.php',
     'PhabricatorMetaMTAMail' => 'applications/metamta/storage/PhabricatorMetaMTAMail.php',
     'PhabricatorMetaMTAMailBody' => 'applications/metamta/view/PhabricatorMetaMTAMailBody.php',
     'PhabricatorMetaMTAMailBodyTestCase' => 'applications/metamta/view/__tests__/PhabricatorMetaMTAMailBodyTestCase.php',
     'PhabricatorMetaMTAMailSection' => 'applications/metamta/view/PhabricatorMetaMTAMailSection.php',
     'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAMailTestCase.php',
     'PhabricatorMetaMTAMailableDatasource' => 'applications/metamta/typeahead/PhabricatorMetaMTAMailableDatasource.php',
     'PhabricatorMetaMTAMailgunReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTAMailgunReceiveController.php',
     'PhabricatorMetaMTAMailingList' => 'applications/mailinglists/storage/PhabricatorMetaMTAMailingList.php',
     'PhabricatorMetaMTAMemberQuery' => 'applications/metamta/query/PhabricatorMetaMTAMemberQuery.php',
     'PhabricatorMetaMTAPermanentFailureException' => 'applications/metamta/exception/PhabricatorMetaMTAPermanentFailureException.php',
     'PhabricatorMetaMTAReceivedMail' => 'applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php',
     'PhabricatorMetaMTAReceivedMailProcessingException' => 'applications/metamta/exception/PhabricatorMetaMTAReceivedMailProcessingException.php',
     'PhabricatorMetaMTAReceivedMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAReceivedMailTestCase.php',
     'PhabricatorMetaMTASchemaSpec' => 'applications/metamta/storage/PhabricatorMetaMTASchemaSpec.php',
     'PhabricatorMetaMTASendGridReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTASendGridReceiveController.php',
     'PhabricatorMetaMTAWorker' => 'applications/metamta/PhabricatorMetaMTAWorker.php',
     'PhabricatorMultiColumnExample' => 'applications/uiexample/examples/PhabricatorMultiColumnExample.php',
     'PhabricatorMustVerifyEmailController' => 'applications/auth/controller/PhabricatorMustVerifyEmailController.php',
     'PhabricatorMySQLConfigOptions' => 'applications/config/option/PhabricatorMySQLConfigOptions.php',
     'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/PhabricatorMySQLFileStorageEngine.php',
     'PhabricatorNamedQuery' => 'applications/search/storage/PhabricatorNamedQuery.php',
     'PhabricatorNamedQueryQuery' => 'applications/search/query/PhabricatorNamedQueryQuery.php',
     'PhabricatorNavigationRemarkupRule' => 'infrastructure/markup/rule/PhabricatorNavigationRemarkupRule.php',
     'PhabricatorNotificationAdHocFeedStory' => 'applications/notification/feed/PhabricatorNotificationAdHocFeedStory.php',
     'PhabricatorNotificationBuilder' => 'applications/notification/builder/PhabricatorNotificationBuilder.php',
     'PhabricatorNotificationClearController' => 'applications/notification/controller/PhabricatorNotificationClearController.php',
     'PhabricatorNotificationClient' => 'applications/notification/client/PhabricatorNotificationClient.php',
     'PhabricatorNotificationConfigOptions' => 'applications/config/option/PhabricatorNotificationConfigOptions.php',
     'PhabricatorNotificationController' => 'applications/notification/controller/PhabricatorNotificationController.php',
     'PhabricatorNotificationIndividualController' => 'applications/notification/controller/PhabricatorNotificationIndividualController.php',
     'PhabricatorNotificationListController' => 'applications/notification/controller/PhabricatorNotificationListController.php',
     'PhabricatorNotificationPanelController' => 'applications/notification/controller/PhabricatorNotificationPanelController.php',
     'PhabricatorNotificationQuery' => 'applications/notification/query/PhabricatorNotificationQuery.php',
     'PhabricatorNotificationSearchEngine' => 'applications/notification/query/PhabricatorNotificationSearchEngine.php',
     'PhabricatorNotificationStatusController' => 'applications/notification/controller/PhabricatorNotificationStatusController.php',
     'PhabricatorNotificationStatusView' => 'applications/notification/view/PhabricatorNotificationStatusView.php',
     'PhabricatorNotificationTestController' => 'applications/notification/controller/PhabricatorNotificationTestController.php',
     'PhabricatorNotificationsApplication' => 'applications/notification/application/PhabricatorNotificationsApplication.php',
     'PhabricatorNuanceApplication' => 'applications/nuance/application/PhabricatorNuanceApplication.php',
     'PhabricatorOAuth1AuthProvider' => 'applications/auth/provider/PhabricatorOAuth1AuthProvider.php',
     'PhabricatorOAuth2AuthProvider' => 'applications/auth/provider/PhabricatorOAuth2AuthProvider.php',
     'PhabricatorOAuthAuthProvider' => 'applications/auth/provider/PhabricatorOAuthAuthProvider.php',
     'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php',
     'PhabricatorOAuthClientAuthorizationQuery' => 'applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php',
     'PhabricatorOAuthClientController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientController.php',
     'PhabricatorOAuthClientDeleteController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientDeleteController.php',
     'PhabricatorOAuthClientEditController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientEditController.php',
     'PhabricatorOAuthClientListController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientListController.php',
     'PhabricatorOAuthClientViewController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientViewController.php',
     'PhabricatorOAuthResponse' => 'applications/oauthserver/PhabricatorOAuthResponse.php',
     'PhabricatorOAuthServer' => 'applications/oauthserver/PhabricatorOAuthServer.php',
     'PhabricatorOAuthServerAccessToken' => 'applications/oauthserver/storage/PhabricatorOAuthServerAccessToken.php',
     'PhabricatorOAuthServerApplication' => 'applications/oauthserver/application/PhabricatorOAuthServerApplication.php',
     'PhabricatorOAuthServerAuthController' => 'applications/oauthserver/controller/PhabricatorOAuthServerAuthController.php',
     'PhabricatorOAuthServerAuthorizationCode' => 'applications/oauthserver/storage/PhabricatorOAuthServerAuthorizationCode.php',
     'PhabricatorOAuthServerAuthorizationsSettingsPanel' => 'applications/oauthserver/panel/PhabricatorOAuthServerAuthorizationsSettingsPanel.php',
     'PhabricatorOAuthServerClient' => 'applications/oauthserver/storage/PhabricatorOAuthServerClient.php',
     'PhabricatorOAuthServerClientAuthorizationPHIDType' => 'applications/oauthserver/phid/PhabricatorOAuthServerClientAuthorizationPHIDType.php',
     'PhabricatorOAuthServerClientPHIDType' => 'applications/oauthserver/phid/PhabricatorOAuthServerClientPHIDType.php',
     'PhabricatorOAuthServerClientQuery' => 'applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php',
     'PhabricatorOAuthServerClientSearchEngine' => 'applications/oauthserver/query/PhabricatorOAuthServerClientSearchEngine.php',
     'PhabricatorOAuthServerController' => 'applications/oauthserver/controller/PhabricatorOAuthServerController.php',
     'PhabricatorOAuthServerCreateClientsCapability' => 'applications/oauthserver/capability/PhabricatorOAuthServerCreateClientsCapability.php',
     'PhabricatorOAuthServerDAO' => 'applications/oauthserver/storage/PhabricatorOAuthServerDAO.php',
     'PhabricatorOAuthServerScope' => 'applications/oauthserver/PhabricatorOAuthServerScope.php',
     'PhabricatorOAuthServerTestCase' => 'applications/oauthserver/__tests__/PhabricatorOAuthServerTestCase.php',
     'PhabricatorOAuthServerTestController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTestController.php',
     'PhabricatorOAuthServerTokenController' => 'applications/oauthserver/controller/PhabricatorOAuthServerTokenController.php',
     'PhabricatorObjectHandle' => 'applications/phid/PhabricatorObjectHandle.php',
     'PhabricatorObjectHandleConstants' => 'applications/phid/handle/const/PhabricatorObjectHandleConstants.php',
     'PhabricatorObjectHandleStatus' => 'applications/phid/handle/const/PhabricatorObjectHandleStatus.php',
     'PhabricatorObjectListQuery' => 'applications/phid/query/PhabricatorObjectListQuery.php',
     'PhabricatorObjectListQueryTestCase' => 'applications/phid/query/__tests__/PhabricatorObjectListQueryTestCase.php',
     'PhabricatorObjectMailReceiver' => 'applications/metamta/receiver/PhabricatorObjectMailReceiver.php',
     'PhabricatorObjectMailReceiverTestCase' => 'applications/metamta/receiver/__tests__/PhabricatorObjectMailReceiverTestCase.php',
     'PhabricatorObjectMentionedByObject' => 'applications/transactions/edges/PhabricatorObjectMentionedByObject.php',
     'PhabricatorObjectMentionsObject' => 'applications/transactions/edges/PhabricatorObjectMentionsObject.php',
     'PhabricatorObjectQuery' => 'applications/phid/query/PhabricatorObjectQuery.php',
     'PhabricatorObjectRemarkupRule' => 'infrastructure/markup/rule/PhabricatorObjectRemarkupRule.php',
     'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php',
     'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php',
     'PhabricatorOwnerPathQuery' => 'applications/owners/query/PhabricatorOwnerPathQuery.php',
     'PhabricatorOwnersApplication' => 'applications/owners/application/PhabricatorOwnersApplication.php',
     'PhabricatorOwnersConfigOptions' => 'applications/owners/config/PhabricatorOwnersConfigOptions.php',
     'PhabricatorOwnersController' => 'applications/owners/controller/PhabricatorOwnersController.php',
     'PhabricatorOwnersDAO' => 'applications/owners/storage/PhabricatorOwnersDAO.php',
     'PhabricatorOwnersDeleteController' => 'applications/owners/controller/PhabricatorOwnersDeleteController.php',
     'PhabricatorOwnersDetailController' => 'applications/owners/controller/PhabricatorOwnersDetailController.php',
     'PhabricatorOwnersEditController' => 'applications/owners/controller/PhabricatorOwnersEditController.php',
     'PhabricatorOwnersListController' => 'applications/owners/controller/PhabricatorOwnersListController.php',
     'PhabricatorOwnersOwner' => 'applications/owners/storage/PhabricatorOwnersOwner.php',
     'PhabricatorOwnersPackage' => 'applications/owners/storage/PhabricatorOwnersPackage.php',
     'PhabricatorOwnersPackageDatasource' => 'applications/owners/typeahead/PhabricatorOwnersPackageDatasource.php',
     'PhabricatorOwnersPackagePHIDType' => 'applications/owners/phid/PhabricatorOwnersPackagePHIDType.php',
     'PhabricatorOwnersPackagePathValidator' => 'applications/repository/worker/commitchangeparser/PhabricatorOwnersPackagePathValidator.php',
     'PhabricatorOwnersPackageQuery' => 'applications/owners/query/PhabricatorOwnersPackageQuery.php',
     'PhabricatorOwnersPackageTestCase' => 'applications/owners/storage/__tests__/PhabricatorOwnersPackageTestCase.php',
     'PhabricatorOwnersPath' => 'applications/owners/storage/PhabricatorOwnersPath.php',
     'PhabricatorPHDConfigOptions' => 'applications/config/option/PhabricatorPHDConfigOptions.php',
     'PhabricatorPHID' => 'applications/phid/storage/PhabricatorPHID.php',
     'PhabricatorPHIDConstants' => 'applications/phid/PhabricatorPHIDConstants.php',
     'PhabricatorPHIDInterface' => 'applications/phid/interface/PhabricatorPHIDInterface.php',
     'PhabricatorPHIDType' => 'applications/phid/type/PhabricatorPHIDType.php',
     'PhabricatorPHPASTApplication' => 'applications/phpast/application/PhabricatorPHPASTApplication.php',
     'PhabricatorPHPMailerConfigOptions' => 'applications/config/option/PhabricatorPHPMailerConfigOptions.php',
     'PhabricatorPagedFormExample' => 'applications/uiexample/examples/PhabricatorPagedFormExample.php',
     'PhabricatorPassphraseApplication' => 'applications/passphrase/application/PhabricatorPassphraseApplication.php',
     'PhabricatorPasswordAuthProvider' => 'applications/auth/provider/PhabricatorPasswordAuthProvider.php',
     'PhabricatorPasswordHasher' => 'infrastructure/util/password/PhabricatorPasswordHasher.php',
     'PhabricatorPasswordHasherTestCase' => 'infrastructure/util/password/__tests__/PhabricatorPasswordHasherTestCase.php',
     'PhabricatorPasswordHasherUnavailableException' => 'infrastructure/util/password/PhabricatorPasswordHasherUnavailableException.php',
     'PhabricatorPaste' => 'applications/paste/storage/PhabricatorPaste.php',
     'PhabricatorPasteApplication' => 'applications/paste/application/PhabricatorPasteApplication.php',
     'PhabricatorPasteCommentController' => 'applications/paste/controller/PhabricatorPasteCommentController.php',
     'PhabricatorPasteConfigOptions' => 'applications/paste/config/PhabricatorPasteConfigOptions.php',
     'PhabricatorPasteController' => 'applications/paste/controller/PhabricatorPasteController.php',
     'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php',
     'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php',
     'PhabricatorPasteEditor' => 'applications/paste/editor/PhabricatorPasteEditor.php',
     'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php',
     'PhabricatorPastePastePHIDType' => 'applications/paste/phid/PhabricatorPastePastePHIDType.php',
     'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php',
     'PhabricatorPasteRemarkupRule' => 'applications/paste/remarkup/PhabricatorPasteRemarkupRule.php',
     'PhabricatorPasteSchemaSpec' => 'applications/paste/storage/PhabricatorPasteSchemaSpec.php',
     'PhabricatorPasteSearchEngine' => 'applications/paste/query/PhabricatorPasteSearchEngine.php',
     'PhabricatorPasteTestDataGenerator' => 'applications/paste/lipsum/PhabricatorPasteTestDataGenerator.php',
     'PhabricatorPasteTransaction' => 'applications/paste/storage/PhabricatorPasteTransaction.php',
     'PhabricatorPasteTransactionComment' => 'applications/paste/storage/PhabricatorPasteTransactionComment.php',
     'PhabricatorPasteTransactionQuery' => 'applications/paste/query/PhabricatorPasteTransactionQuery.php',
     'PhabricatorPasteViewController' => 'applications/paste/controller/PhabricatorPasteViewController.php',
     'PhabricatorPeopleApplication' => 'applications/people/application/PhabricatorPeopleApplication.php',
     'PhabricatorPeopleApproveController' => 'applications/people/controller/PhabricatorPeopleApproveController.php',
     'PhabricatorPeopleCalendarController' => 'applications/people/controller/PhabricatorPeopleCalendarController.php',
     'PhabricatorPeopleController' => 'applications/people/controller/PhabricatorPeopleController.php',
     'PhabricatorPeopleCreateController' => 'applications/people/controller/PhabricatorPeopleCreateController.php',
     'PhabricatorPeopleDatasource' => 'applications/people/typeahead/PhabricatorPeopleDatasource.php',
     'PhabricatorPeopleDeleteController' => 'applications/people/controller/PhabricatorPeopleDeleteController.php',
     'PhabricatorPeopleDisableController' => 'applications/people/controller/PhabricatorPeopleDisableController.php',
     'PhabricatorPeopleEmpowerController' => 'applications/people/controller/PhabricatorPeopleEmpowerController.php',
     'PhabricatorPeopleExternalPHIDType' => 'applications/people/phid/PhabricatorPeopleExternalPHIDType.php',
     'PhabricatorPeopleHovercardEventListener' => 'applications/people/event/PhabricatorPeopleHovercardEventListener.php',
     'PhabricatorPeopleLdapController' => 'applications/people/controller/PhabricatorPeopleLdapController.php',
     'PhabricatorPeopleListController' => 'applications/people/controller/PhabricatorPeopleListController.php',
     'PhabricatorPeopleLogQuery' => 'applications/people/query/PhabricatorPeopleLogQuery.php',
     'PhabricatorPeopleLogSearchEngine' => 'applications/people/query/PhabricatorPeopleLogSearchEngine.php',
     'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php',
     'PhabricatorPeopleNewController' => 'applications/people/controller/PhabricatorPeopleNewController.php',
     'PhabricatorPeopleProfileController' => 'applications/people/controller/PhabricatorPeopleProfileController.php',
     'PhabricatorPeopleProfileEditController' => 'applications/people/controller/PhabricatorPeopleProfileEditController.php',
     'PhabricatorPeopleProfilePictureController' => 'applications/people/controller/PhabricatorPeopleProfilePictureController.php',
     'PhabricatorPeopleQuery' => 'applications/people/query/PhabricatorPeopleQuery.php',
     'PhabricatorPeopleRenameController' => 'applications/people/controller/PhabricatorPeopleRenameController.php',
     'PhabricatorPeopleSearchEngine' => 'applications/people/query/PhabricatorPeopleSearchEngine.php',
     'PhabricatorPeopleTestDataGenerator' => 'applications/people/lipsum/PhabricatorPeopleTestDataGenerator.php',
     'PhabricatorPeopleUserPHIDType' => 'applications/people/phid/PhabricatorPeopleUserPHIDType.php',
     'PhabricatorPeopleWelcomeController' => 'applications/people/controller/PhabricatorPeopleWelcomeController.php',
     'PhabricatorPersonaAuthProvider' => 'applications/auth/provider/PhabricatorPersonaAuthProvider.php',
     'PhabricatorPhameApplication' => 'applications/phame/application/PhabricatorPhameApplication.php',
     'PhabricatorPhameBlogPHIDType' => 'applications/phame/phid/PhabricatorPhameBlogPHIDType.php',
     'PhabricatorPhameConfigOptions' => 'applications/phame/config/PhabricatorPhameConfigOptions.php',
     'PhabricatorPhamePostPHIDType' => 'applications/phame/phid/PhabricatorPhamePostPHIDType.php',
     'PhabricatorPhluxApplication' => 'applications/phlux/application/PhabricatorPhluxApplication.php',
     'PhabricatorPholioApplication' => 'applications/pholio/application/PhabricatorPholioApplication.php',
     'PhabricatorPholioConfigOptions' => 'applications/pholio/config/PhabricatorPholioConfigOptions.php',
     'PhabricatorPholioMockTestDataGenerator' => 'applications/pholio/lipsum/PhabricatorPholioMockTestDataGenerator.php',
     'PhabricatorPhortuneApplication' => 'applications/phortune/application/PhabricatorPhortuneApplication.php',
     'PhabricatorPhragmentApplication' => 'applications/phragment/application/PhabricatorPhragmentApplication.php',
     'PhabricatorPhrequentApplication' => 'applications/phrequent/application/PhabricatorPhrequentApplication.php',
     'PhabricatorPhrequentConfigOptions' => 'applications/phrequent/config/PhabricatorPhrequentConfigOptions.php',
     'PhabricatorPhrictionApplication' => 'applications/phriction/application/PhabricatorPhrictionApplication.php',
     'PhabricatorPhrictionConfigOptions' => 'applications/phriction/config/PhabricatorPhrictionConfigOptions.php',
     'PhabricatorPolicies' => 'applications/policy/constants/PhabricatorPolicies.php',
     'PhabricatorPolicy' => 'applications/policy/storage/PhabricatorPolicy.php',
     'PhabricatorPolicyApplication' => 'applications/policy/application/PhabricatorPolicyApplication.php',
     'PhabricatorPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorPolicyAwareQuery.php',
     'PhabricatorPolicyAwareTestQuery' => 'applications/policy/__tests__/PhabricatorPolicyAwareTestQuery.php',
     'PhabricatorPolicyCanEditCapability' => 'applications/policy/capability/PhabricatorPolicyCanEditCapability.php',
     'PhabricatorPolicyCanJoinCapability' => 'applications/policy/capability/PhabricatorPolicyCanJoinCapability.php',
     'PhabricatorPolicyCanViewCapability' => 'applications/policy/capability/PhabricatorPolicyCanViewCapability.php',
     'PhabricatorPolicyCapability' => 'applications/policy/capability/PhabricatorPolicyCapability.php',
     'PhabricatorPolicyConfigOptions' => 'applications/policy/config/PhabricatorPolicyConfigOptions.php',
     'PhabricatorPolicyConstants' => 'applications/policy/constants/PhabricatorPolicyConstants.php',
     'PhabricatorPolicyController' => 'applications/policy/controller/PhabricatorPolicyController.php',
     'PhabricatorPolicyDAO' => 'applications/policy/storage/PhabricatorPolicyDAO.php',
     'PhabricatorPolicyDataTestCase' => 'applications/policy/__tests__/PhabricatorPolicyDataTestCase.php',
     'PhabricatorPolicyEditController' => 'applications/policy/controller/PhabricatorPolicyEditController.php',
     'PhabricatorPolicyException' => 'applications/policy/exception/PhabricatorPolicyException.php',
     'PhabricatorPolicyExplainController' => 'applications/policy/controller/PhabricatorPolicyExplainController.php',
     'PhabricatorPolicyFilter' => 'applications/policy/filter/PhabricatorPolicyFilter.php',
     'PhabricatorPolicyInterface' => 'applications/policy/interface/PhabricatorPolicyInterface.php',
     'PhabricatorPolicyManagementShowWorkflow' => 'applications/policy/management/PhabricatorPolicyManagementShowWorkflow.php',
     'PhabricatorPolicyManagementUnlockWorkflow' => 'applications/policy/management/PhabricatorPolicyManagementUnlockWorkflow.php',
     'PhabricatorPolicyManagementWorkflow' => 'applications/policy/management/PhabricatorPolicyManagementWorkflow.php',
     'PhabricatorPolicyPHIDTypePolicy' => 'applications/policy/phid/PhabricatorPolicyPHIDTypePolicy.php',
     'PhabricatorPolicyQuery' => 'applications/policy/query/PhabricatorPolicyQuery.php',
     'PhabricatorPolicyRule' => 'applications/policy/rule/PhabricatorPolicyRule.php',
     'PhabricatorPolicyRuleAdministrators' => 'applications/policy/rule/PhabricatorPolicyRuleAdministrators.php',
     'PhabricatorPolicyRuleLegalpadSignature' => 'applications/policy/rule/PhabricatorPolicyRuleLegalpadSignature.php',
     'PhabricatorPolicyRuleLunarPhase' => 'applications/policy/rule/PhabricatorPolicyRuleLunarPhase.php',
     'PhabricatorPolicyRuleProjects' => 'applications/policy/rule/PhabricatorPolicyRuleProjects.php',
     'PhabricatorPolicyRuleUsers' => 'applications/policy/rule/PhabricatorPolicyRuleUsers.php',
     'PhabricatorPolicyTestCase' => 'applications/policy/__tests__/PhabricatorPolicyTestCase.php',
     'PhabricatorPolicyTestObject' => 'applications/policy/__tests__/PhabricatorPolicyTestObject.php',
     'PhabricatorPolicyType' => 'applications/policy/constants/PhabricatorPolicyType.php',
     'PhabricatorPonderApplication' => 'applications/ponder/application/PhabricatorPonderApplication.php',
     'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
     'PhabricatorProjectApplication' => 'applications/project/application/PhabricatorProjectApplication.php',
     'PhabricatorProjectArchiveController' => 'applications/project/controller/PhabricatorProjectArchiveController.php',
     'PhabricatorProjectBoardController' => 'applications/project/controller/PhabricatorProjectBoardController.php',
     'PhabricatorProjectBoardImportController' => 'applications/project/controller/PhabricatorProjectBoardImportController.php',
     'PhabricatorProjectBoardReorderController' => 'applications/project/controller/PhabricatorProjectBoardReorderController.php',
     'PhabricatorProjectBoardViewController' => 'applications/project/controller/PhabricatorProjectBoardViewController.php',
     'PhabricatorProjectColumn' => 'applications/project/storage/PhabricatorProjectColumn.php',
     'PhabricatorProjectColumnDetailController' => 'applications/project/controller/PhabricatorProjectColumnDetailController.php',
     'PhabricatorProjectColumnEditController' => 'applications/project/controller/PhabricatorProjectColumnEditController.php',
     'PhabricatorProjectColumnHideController' => 'applications/project/controller/PhabricatorProjectColumnHideController.php',
     'PhabricatorProjectColumnPHIDType' => 'applications/project/phid/PhabricatorProjectColumnPHIDType.php',
     'PhabricatorProjectColumnPosition' => 'applications/project/storage/PhabricatorProjectColumnPosition.php',
     'PhabricatorProjectColumnPositionQuery' => 'applications/project/query/PhabricatorProjectColumnPositionQuery.php',
     'PhabricatorProjectColumnQuery' => 'applications/project/query/PhabricatorProjectColumnQuery.php',
     'PhabricatorProjectColumnTransaction' => 'applications/project/storage/PhabricatorProjectColumnTransaction.php',
     'PhabricatorProjectColumnTransactionEditor' => 'applications/project/editor/PhabricatorProjectColumnTransactionEditor.php',
     'PhabricatorProjectColumnTransactionQuery' => 'applications/project/query/PhabricatorProjectColumnTransactionQuery.php',
     'PhabricatorProjectConfigOptions' => 'applications/project/config/PhabricatorProjectConfigOptions.php',
     'PhabricatorProjectConfiguredCustomField' => 'applications/project/customfield/PhabricatorProjectConfiguredCustomField.php',
     'PhabricatorProjectConstants' => 'applications/project/constants/PhabricatorProjectConstants.php',
     'PhabricatorProjectController' => 'applications/project/controller/PhabricatorProjectController.php',
     'PhabricatorProjectCustomField' => 'applications/project/customfield/PhabricatorProjectCustomField.php',
     'PhabricatorProjectCustomFieldNumericIndex' => 'applications/project/storage/PhabricatorProjectCustomFieldNumericIndex.php',
     'PhabricatorProjectCustomFieldStorage' => 'applications/project/storage/PhabricatorProjectCustomFieldStorage.php',
     'PhabricatorProjectCustomFieldStringIndex' => 'applications/project/storage/PhabricatorProjectCustomFieldStringIndex.php',
     'PhabricatorProjectDAO' => 'applications/project/storage/PhabricatorProjectDAO.php',
     'PhabricatorProjectDatasource' => 'applications/project/typeahead/PhabricatorProjectDatasource.php',
     'PhabricatorProjectDescriptionField' => 'applications/project/customfield/PhabricatorProjectDescriptionField.php',
     'PhabricatorProjectEditDetailsController' => 'applications/project/controller/PhabricatorProjectEditDetailsController.php',
     'PhabricatorProjectEditIconController' => 'applications/project/controller/PhabricatorProjectEditIconController.php',
     'PhabricatorProjectEditMainController' => 'applications/project/controller/PhabricatorProjectEditMainController.php',
     'PhabricatorProjectEditPictureController' => 'applications/project/controller/PhabricatorProjectEditPictureController.php',
     'PhabricatorProjectEditorTestCase' => 'applications/project/editor/__tests__/PhabricatorProjectEditorTestCase.php',
     'PhabricatorProjectIcon' => 'applications/project/icon/PhabricatorProjectIcon.php',
     'PhabricatorProjectInterface' => 'applications/project/interface/PhabricatorProjectInterface.php',
     'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php',
     'PhabricatorProjectMembersEditController' => 'applications/project/controller/PhabricatorProjectMembersEditController.php',
     'PhabricatorProjectMembersRemoveController' => 'applications/project/controller/PhabricatorProjectMembersRemoveController.php',
     'PhabricatorProjectMoveController' => 'applications/project/controller/PhabricatorProjectMoveController.php',
     'PhabricatorProjectNameCollisionException' => 'applications/project/exception/PhabricatorProjectNameCollisionException.php',
     'PhabricatorProjectObjectHasProjectEdgeType' => 'applications/project/edge/PhabricatorProjectObjectHasProjectEdgeType.php',
     'PhabricatorProjectOrUserDatasource' => 'applications/project/typeahead/PhabricatorProjectOrUserDatasource.php',
     'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php',
     'PhabricatorProjectProjectHasObjectEdgeType' => 'applications/project/edge/PhabricatorProjectProjectHasObjectEdgeType.php',
     'PhabricatorProjectProjectPHIDType' => 'applications/project/phid/PhabricatorProjectProjectPHIDType.php',
     'PhabricatorProjectQuery' => 'applications/project/query/PhabricatorProjectQuery.php',
     'PhabricatorProjectSchemaSpec' => 'applications/project/storage/PhabricatorProjectSchemaSpec.php',
     'PhabricatorProjectSearchEngine' => 'applications/project/query/PhabricatorProjectSearchEngine.php',
     'PhabricatorProjectSearchIndexer' => 'applications/project/search/PhabricatorProjectSearchIndexer.php',
     'PhabricatorProjectSlug' => 'applications/project/storage/PhabricatorProjectSlug.php',
     'PhabricatorProjectStandardCustomField' => 'applications/project/customfield/PhabricatorProjectStandardCustomField.php',
     'PhabricatorProjectStatus' => 'applications/project/constants/PhabricatorProjectStatus.php',
     'PhabricatorProjectTestDataGenerator' => 'applications/project/lipsum/PhabricatorProjectTestDataGenerator.php',
     'PhabricatorProjectTransaction' => 'applications/project/storage/PhabricatorProjectTransaction.php',
     'PhabricatorProjectTransactionEditor' => 'applications/project/editor/PhabricatorProjectTransactionEditor.php',
     'PhabricatorProjectTransactionQuery' => 'applications/project/query/PhabricatorProjectTransactionQuery.php',
     'PhabricatorProjectUIEventListener' => 'applications/project/events/PhabricatorProjectUIEventListener.php',
     'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php',
     'PhabricatorProjectWatchController' => 'applications/project/controller/PhabricatorProjectWatchController.php',
     'PhabricatorProjectWikiExplainController' => 'applications/project/controller/PhabricatorProjectWikiExplainController.php',
     'PhabricatorQuery' => 'infrastructure/query/PhabricatorQuery.php',
     'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
     'PhabricatorRedirectController' => 'applications/base/controller/PhabricatorRedirectController.php',
     'PhabricatorRefreshCSRFController' => 'applications/auth/controller/PhabricatorRefreshCSRFController.php',
     'PhabricatorRegistrationProfile' => 'applications/people/storage/PhabricatorRegistrationProfile.php',
     'PhabricatorReleephApplication' => 'applications/releeph/application/PhabricatorReleephApplication.php',
     'PhabricatorReleephApplicationConfigOptions' => 'applications/releeph/config/PhabricatorReleephApplicationConfigOptions.php',
     'PhabricatorRemarkupControl' => 'view/form/control/PhabricatorRemarkupControl.php',
     'PhabricatorRemarkupCowsayBlockInterpreter' => 'infrastructure/markup/interpreter/PhabricatorRemarkupCowsayBlockInterpreter.php',
     'PhabricatorRemarkupCustomBlockRule' => 'infrastructure/markup/rule/PhabricatorRemarkupCustomBlockRule.php',
     'PhabricatorRemarkupCustomInlineRule' => 'infrastructure/markup/rule/PhabricatorRemarkupCustomInlineRule.php',
     'PhabricatorRemarkupExample' => 'applications/uiexample/examples/PhabricatorRemarkupExample.php',
     'PhabricatorRemarkupFigletBlockInterpreter' => 'infrastructure/markup/interpreter/PhabricatorRemarkupFigletBlockInterpreter.php',
     'PhabricatorRemarkupGraphvizBlockInterpreter' => 'infrastructure/markup/interpreter/PhabricatorRemarkupGraphvizBlockInterpreter.php',
     'PhabricatorRepositoriesApplication' => 'applications/repository/application/PhabricatorRepositoriesApplication.php',
     'PhabricatorRepository' => 'applications/repository/storage/PhabricatorRepository.php',
     'PhabricatorRepositoryArcanistProject' => 'applications/repository/storage/PhabricatorRepositoryArcanistProject.php',
     'PhabricatorRepositoryArcanistProjectDeleteController' => 'applications/repository/controller/PhabricatorRepositoryArcanistProjectDeleteController.php',
     'PhabricatorRepositoryArcanistProjectEditController' => 'applications/repository/controller/PhabricatorRepositoryArcanistProjectEditController.php',
     'PhabricatorRepositoryArcanistProjectPHIDType' => 'applications/repository/phid/PhabricatorRepositoryArcanistProjectPHIDType.php',
     'PhabricatorRepositoryArcanistProjectQuery' => 'applications/repository/query/PhabricatorRepositoryArcanistProjectQuery.php',
     'PhabricatorRepositoryAuditRequest' => 'applications/repository/storage/PhabricatorRepositoryAuditRequest.php',
     'PhabricatorRepositoryBranch' => 'applications/repository/storage/PhabricatorRepositoryBranch.php',
     'PhabricatorRepositoryCommit' => 'applications/repository/storage/PhabricatorRepositoryCommit.php',
     'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryCommitChangeParserWorker.php',
     'PhabricatorRepositoryCommitData' => 'applications/repository/storage/PhabricatorRepositoryCommitData.php',
     'PhabricatorRepositoryCommitHeraldWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php',
     'PhabricatorRepositoryCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryCommitMessageParserWorker.php',
     'PhabricatorRepositoryCommitOwnersWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitOwnersWorker.php',
     'PhabricatorRepositoryCommitPHIDType' => 'applications/repository/phid/PhabricatorRepositoryCommitPHIDType.php',
     'PhabricatorRepositoryCommitParserWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitParserWorker.php',
     'PhabricatorRepositoryCommitRef' => 'applications/repository/engine/PhabricatorRepositoryCommitRef.php',
     'PhabricatorRepositoryCommitSearchIndexer' => 'applications/repository/search/PhabricatorRepositoryCommitSearchIndexer.php',
     'PhabricatorRepositoryConfigOptions' => 'applications/repository/PhabricatorRepositoryConfigOptions.php',
     'PhabricatorRepositoryController' => 'applications/repository/controller/PhabricatorRepositoryController.php',
     'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php',
     'PhabricatorRepositoryDiscoveryEngine' => 'applications/repository/engine/PhabricatorRepositoryDiscoveryEngine.php',
     'PhabricatorRepositoryEditor' => 'applications/repository/editor/PhabricatorRepositoryEditor.php',
     'PhabricatorRepositoryEngine' => 'applications/repository/engine/PhabricatorRepositoryEngine.php',
     'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php',
     'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php',
     'PhabricatorRepositoryGraphCache' => 'applications/repository/graphcache/PhabricatorRepositoryGraphCache.php',
     'PhabricatorRepositoryGraphStream' => 'applications/repository/daemon/PhabricatorRepositoryGraphStream.php',
     'PhabricatorRepositoryListController' => 'applications/repository/controller/PhabricatorRepositoryListController.php',
     'PhabricatorRepositoryManagementCacheWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementCacheWorkflow.php',
     'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php',
     'PhabricatorRepositoryManagementEditWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementEditWorkflow.php',
     'PhabricatorRepositoryManagementImportingWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementImportingWorkflow.php',
     'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
     'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementLookupUsersWorkflow.php',
     'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMarkImportedWorkflow.php',
     'PhabricatorRepositoryManagementMirrorWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMirrorWorkflow.php',
     'PhabricatorRepositoryManagementParentsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php',
     'PhabricatorRepositoryManagementPullWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementPullWorkflow.php',
     'PhabricatorRepositoryManagementRefsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementRefsWorkflow.php',
     'PhabricatorRepositoryManagementUpdateWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementUpdateWorkflow.php',
     'PhabricatorRepositoryManagementWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementWorkflow.php',
     'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryMercurialCommitChangeParserWorker.php',
     'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryMercurialCommitMessageParserWorker.php',
     'PhabricatorRepositoryMirror' => 'applications/repository/storage/PhabricatorRepositoryMirror.php',
     'PhabricatorRepositoryMirrorEngine' => 'applications/repository/engine/PhabricatorRepositoryMirrorEngine.php',
     'PhabricatorRepositoryMirrorPHIDType' => 'applications/repository/phid/PhabricatorRepositoryMirrorPHIDType.php',
     'PhabricatorRepositoryMirrorQuery' => 'applications/repository/query/PhabricatorRepositoryMirrorQuery.php',
     'PhabricatorRepositoryParsedChange' => 'applications/repository/data/PhabricatorRepositoryParsedChange.php',
     'PhabricatorRepositoryPullEngine' => 'applications/repository/engine/PhabricatorRepositoryPullEngine.php',
     'PhabricatorRepositoryPullLocalDaemon' => 'applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php',
     'PhabricatorRepositoryPushEvent' => 'applications/repository/storage/PhabricatorRepositoryPushEvent.php',
     'PhabricatorRepositoryPushEventPHIDType' => 'applications/repository/phid/PhabricatorRepositoryPushEventPHIDType.php',
     'PhabricatorRepositoryPushEventQuery' => 'applications/repository/query/PhabricatorRepositoryPushEventQuery.php',
     'PhabricatorRepositoryPushLog' => 'applications/repository/storage/PhabricatorRepositoryPushLog.php',
     'PhabricatorRepositoryPushLogPHIDType' => 'applications/repository/phid/PhabricatorRepositoryPushLogPHIDType.php',
     'PhabricatorRepositoryPushLogQuery' => 'applications/repository/query/PhabricatorRepositoryPushLogQuery.php',
     'PhabricatorRepositoryPushLogSearchEngine' => 'applications/repository/query/PhabricatorRepositoryPushLogSearchEngine.php',
     'PhabricatorRepositoryPushMailWorker' => 'applications/repository/worker/PhabricatorRepositoryPushMailWorker.php',
     'PhabricatorRepositoryPushReplyHandler' => 'applications/repository/mail/PhabricatorRepositoryPushReplyHandler.php',
     'PhabricatorRepositoryQuery' => 'applications/repository/query/PhabricatorRepositoryQuery.php',
     'PhabricatorRepositoryRefCursor' => 'applications/repository/storage/PhabricatorRepositoryRefCursor.php',
     'PhabricatorRepositoryRefCursorQuery' => 'applications/repository/query/PhabricatorRepositoryRefCursorQuery.php',
     'PhabricatorRepositoryRefEngine' => 'applications/repository/engine/PhabricatorRepositoryRefEngine.php',
     'PhabricatorRepositoryRepositoryPHIDType' => 'applications/repository/phid/PhabricatorRepositoryRepositoryPHIDType.php',
     'PhabricatorRepositorySchemaSpec' => 'applications/repository/storage/PhabricatorRepositorySchemaSpec.php',
     'PhabricatorRepositorySearchEngine' => 'applications/repository/query/PhabricatorRepositorySearchEngine.php',
     'PhabricatorRepositoryStatusMessage' => 'applications/repository/storage/PhabricatorRepositoryStatusMessage.php',
     'PhabricatorRepositorySvnCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositorySvnCommitChangeParserWorker.php',
     'PhabricatorRepositorySvnCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositorySvnCommitMessageParserWorker.php',
     'PhabricatorRepositorySymbol' => 'applications/repository/storage/PhabricatorRepositorySymbol.php',
     'PhabricatorRepositoryTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryTestCase.php',
     'PhabricatorRepositoryTransaction' => 'applications/repository/storage/PhabricatorRepositoryTransaction.php',
     'PhabricatorRepositoryTransactionQuery' => 'applications/repository/query/PhabricatorRepositoryTransactionQuery.php',
     'PhabricatorRepositoryType' => 'applications/repository/constants/PhabricatorRepositoryType.php',
     'PhabricatorRepositoryURINormalizer' => 'applications/repository/data/PhabricatorRepositoryURINormalizer.php',
     'PhabricatorRepositoryURINormalizerTestCase' => 'applications/repository/data/__tests__/PhabricatorRepositoryURINormalizerTestCase.php',
     'PhabricatorRepositoryURITestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryURITestCase.php',
     'PhabricatorRepositoryVCSPassword' => 'applications/repository/storage/PhabricatorRepositoryVCSPassword.php',
     'PhabricatorRobotsController' => 'applications/system/controller/PhabricatorRobotsController.php',
     'PhabricatorS3FileStorageEngine' => 'applications/files/engine/PhabricatorS3FileStorageEngine.php',
     'PhabricatorSMS' => 'infrastructure/sms/storage/PhabricatorSMS.php',
     'PhabricatorSMSConfigOptions' => 'applications/config/option/PhabricatorSMSConfigOptions.php',
     'PhabricatorSMSDAO' => 'infrastructure/sms/storage/PhabricatorSMSDAO.php',
     'PhabricatorSMSDemultiplexWorker' => 'infrastructure/sms/worker/PhabricatorSMSDemultiplexWorker.php',
     'PhabricatorSMSImplementationAdapter' => 'infrastructure/sms/adapter/PhabricatorSMSImplementationAdapter.php',
     'PhabricatorSMSImplementationTestBlackholeAdapter' => 'infrastructure/sms/adapter/PhabricatorSMSImplementationTestBlackholeAdapter.php',
     'PhabricatorSMSImplementationTwilioAdapter' => 'infrastructure/sms/adapter/PhabricatorSMSImplementationTwilioAdapter.php',
     'PhabricatorSMSManagementListOutboundWorkflow' => 'infrastructure/sms/management/PhabricatorSMSManagementListOutboundWorkflow.php',
     'PhabricatorSMSManagementSendTestWorkflow' => 'infrastructure/sms/management/PhabricatorSMSManagementSendTestWorkflow.php',
     'PhabricatorSMSManagementShowOutboundWorkflow' => 'infrastructure/sms/management/PhabricatorSMSManagementShowOutboundWorkflow.php',
     'PhabricatorSMSManagementWorkflow' => 'infrastructure/sms/management/PhabricatorSMSManagementWorkflow.php',
     'PhabricatorSMSSendWorker' => 'infrastructure/sms/worker/PhabricatorSMSSendWorker.php',
     'PhabricatorSMSWorker' => 'infrastructure/sms/worker/PhabricatorSMSWorker.php',
     'PhabricatorSQLPatchList' => 'infrastructure/storage/patch/PhabricatorSQLPatchList.php',
     'PhabricatorSSHKeyGenerator' => 'infrastructure/util/PhabricatorSSHKeyGenerator.php',
     'PhabricatorSSHLog' => 'infrastructure/log/PhabricatorSSHLog.php',
     'PhabricatorSSHPassthruCommand' => 'infrastructure/ssh/PhabricatorSSHPassthruCommand.php',
     'PhabricatorSSHPublicKeyInterface' => 'applications/auth/sshkey/PhabricatorSSHPublicKeyInterface.php',
     'PhabricatorSSHWorkflow' => 'infrastructure/ssh/PhabricatorSSHWorkflow.php',
     'PhabricatorSavedQuery' => 'applications/search/storage/PhabricatorSavedQuery.php',
     'PhabricatorSavedQueryQuery' => 'applications/search/query/PhabricatorSavedQueryQuery.php',
     'PhabricatorScopedEnv' => 'infrastructure/env/PhabricatorScopedEnv.php',
     'PhabricatorSearchAbstractDocument' => 'applications/search/index/PhabricatorSearchAbstractDocument.php',
     'PhabricatorSearchApplication' => 'applications/search/application/PhabricatorSearchApplication.php',
     'PhabricatorSearchApplicationSearchEngine' => 'applications/search/query/PhabricatorSearchApplicationSearchEngine.php',
     'PhabricatorSearchAttachController' => 'applications/search/controller/PhabricatorSearchAttachController.php',
     'PhabricatorSearchBaseController' => 'applications/search/controller/PhabricatorSearchBaseController.php',
     'PhabricatorSearchConfigOptions' => 'applications/search/config/PhabricatorSearchConfigOptions.php',
     'PhabricatorSearchController' => 'applications/search/controller/PhabricatorSearchController.php',
     'PhabricatorSearchDAO' => 'applications/search/storage/PhabricatorSearchDAO.php',
     'PhabricatorSearchDatasource' => 'applications/search/typeahead/PhabricatorSearchDatasource.php',
     'PhabricatorSearchDeleteController' => 'applications/search/controller/PhabricatorSearchDeleteController.php',
     'PhabricatorSearchDocument' => 'applications/search/storage/document/PhabricatorSearchDocument.php',
     'PhabricatorSearchDocumentField' => 'applications/search/storage/document/PhabricatorSearchDocumentField.php',
     'PhabricatorSearchDocumentIndexer' => 'applications/search/index/PhabricatorSearchDocumentIndexer.php',
     'PhabricatorSearchDocumentQuery' => 'applications/search/query/PhabricatorSearchDocumentQuery.php',
     'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/PhabricatorSearchDocumentRelationship.php',
     'PhabricatorSearchEditController' => 'applications/search/controller/PhabricatorSearchEditController.php',
     'PhabricatorSearchEngine' => 'applications/search/engine/PhabricatorSearchEngine.php',
     'PhabricatorSearchEngineElastic' => 'applications/search/engine/PhabricatorSearchEngineElastic.php',
     'PhabricatorSearchEngineMySQL' => 'applications/search/engine/PhabricatorSearchEngineMySQL.php',
     'PhabricatorSearchEngineSelector' => 'applications/search/selector/PhabricatorSearchEngineSelector.php',
     'PhabricatorSearchField' => 'applications/search/constants/PhabricatorSearchField.php',
     'PhabricatorSearchHovercardController' => 'applications/search/controller/PhabricatorSearchHovercardController.php',
     'PhabricatorSearchIndexer' => 'applications/search/index/PhabricatorSearchIndexer.php',
     'PhabricatorSearchManagementIndexWorkflow' => 'applications/search/management/PhabricatorSearchManagementIndexWorkflow.php',
     'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php',
     'PhabricatorSearchOrderController' => 'applications/search/controller/PhabricatorSearchOrderController.php',
     'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php',
     'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php',
     'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php',
     'PhabricatorSearchWorker' => 'applications/search/worker/PhabricatorSearchWorker.php',
     'PhabricatorSecurityConfigOptions' => 'applications/config/option/PhabricatorSecurityConfigOptions.php',
     'PhabricatorSendGridConfigOptions' => 'applications/config/option/PhabricatorSendGridConfigOptions.php',
     'PhabricatorSettingsAddEmailAction' => 'applications/settings/action/PhabricatorSettingsAddEmailAction.php',
     'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php',
     'PhabricatorSettingsApplication' => 'applications/settings/application/PhabricatorSettingsApplication.php',
     'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
     'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
     'PhabricatorSettingsPanelAccount' => 'applications/settings/panel/PhabricatorSettingsPanelAccount.php',
     'PhabricatorSettingsPanelActivity' => 'applications/settings/panel/PhabricatorSettingsPanelActivity.php',
     'PhabricatorSettingsPanelConduit' => 'applications/settings/panel/PhabricatorSettingsPanelConduit.php',
     'PhabricatorSettingsPanelConpherencePreferences' => 'applications/settings/panel/PhabricatorSettingsPanelConpherencePreferences.php',
     'PhabricatorSettingsPanelDeveloperPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDeveloperPreferences.php',
     'PhabricatorSettingsPanelDiffPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDiffPreferences.php',
     'PhabricatorSettingsPanelDisplayPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php',
     'PhabricatorSettingsPanelEmailAddresses' => 'applications/settings/panel/PhabricatorSettingsPanelEmailAddresses.php',
     'PhabricatorSettingsPanelEmailFormat' => 'applications/settings/panel/PhabricatorSettingsPanelEmailFormat.php',
     'PhabricatorSettingsPanelEmailPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelEmailPreferences.php',
     'PhabricatorSettingsPanelExternalAccounts' => 'applications/settings/panel/PhabricatorSettingsPanelExternalAccounts.php',
     'PhabricatorSettingsPanelHomePreferences' => 'applications/settings/panel/PhabricatorSettingsPanelHomePreferences.php',
     'PhabricatorSettingsPanelMultiFactor' => 'applications/settings/panel/PhabricatorSettingsPanelMultiFactor.php',
     'PhabricatorSettingsPanelPassword' => 'applications/settings/panel/PhabricatorSettingsPanelPassword.php',
     'PhabricatorSettingsPanelSSHKeys' => 'applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php',
     'PhabricatorSettingsPanelSearchPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelSearchPreferences.php',
     'PhabricatorSettingsPanelSessions' => 'applications/settings/panel/PhabricatorSettingsPanelSessions.php',
     'PhabricatorSettingsPanelTokens' => 'applications/settings/panel/PhabricatorSettingsPanelTokens.php',
     'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php',
     'PhabricatorSetupCheckAPC' => 'applications/config/check/PhabricatorSetupCheckAPC.php',
     'PhabricatorSetupCheckAphlict' => 'applications/notification/setup/PhabricatorSetupCheckAphlict.php',
     'PhabricatorSetupCheckAuth' => 'applications/config/check/PhabricatorSetupCheckAuth.php',
     'PhabricatorSetupCheckBaseURI' => 'applications/config/check/PhabricatorSetupCheckBaseURI.php',
     'PhabricatorSetupCheckBinaries' => 'applications/config/check/PhabricatorSetupCheckBinaries.php',
     'PhabricatorSetupCheckDaemons' => 'applications/config/check/PhabricatorSetupCheckDaemons.php',
     'PhabricatorSetupCheckDatabase' => 'applications/config/check/PhabricatorSetupCheckDatabase.php',
     'PhabricatorSetupCheckExtensions' => 'applications/config/check/PhabricatorSetupCheckExtensions.php',
     'PhabricatorSetupCheckExtraConfig' => 'applications/config/check/PhabricatorSetupCheckExtraConfig.php',
     'PhabricatorSetupCheckFileinfo' => 'applications/config/check/PhabricatorSetupCheckFileinfo.php',
     'PhabricatorSetupCheckGD' => 'applications/config/check/PhabricatorSetupCheckGD.php',
     'PhabricatorSetupCheckImagemagick' => 'applications/config/check/PhabricatorSetupCheckImagemagick.php',
     'PhabricatorSetupCheckInvalidConfig' => 'applications/config/check/PhabricatorSetupCheckInvalidConfig.php',
     'PhabricatorSetupCheckMail' => 'applications/config/check/PhabricatorSetupCheckMail.php',
     'PhabricatorSetupCheckMySQL' => 'applications/config/check/PhabricatorSetupCheckMySQL.php',
     'PhabricatorSetupCheckPHPConfig' => 'applications/config/check/PhabricatorSetupCheckPHPConfig.php',
     'PhabricatorSetupCheckPath' => 'applications/config/check/PhabricatorSetupCheckPath.php',
     'PhabricatorSetupCheckPygment' => 'applications/config/check/PhabricatorSetupCheckPygment.php',
     'PhabricatorSetupCheckRepositories' => 'applications/config/check/PhabricatorSetupCheckRepositories.php',
     'PhabricatorSetupCheckSecurity' => 'applications/config/check/PhabricatorSetupCheckSecurity.php',
     'PhabricatorSetupCheckStorage' => 'applications/config/check/PhabricatorSetupCheckStorage.php',
     'PhabricatorSetupCheckTimezone' => 'applications/config/check/PhabricatorSetupCheckTimezone.php',
     'PhabricatorSetupIssue' => 'applications/config/issue/PhabricatorSetupIssue.php',
     'PhabricatorSetupIssueExample' => 'applications/uiexample/examples/PhabricatorSetupIssueExample.php',
     'PhabricatorSetupIssueView' => 'applications/config/view/PhabricatorSetupIssueView.php',
     'PhabricatorSlowvoteApplication' => 'applications/slowvote/application/PhabricatorSlowvoteApplication.php',
     'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php',
     'PhabricatorSlowvoteCloseController' => 'applications/slowvote/controller/PhabricatorSlowvoteCloseController.php',
     'PhabricatorSlowvoteCommentController' => 'applications/slowvote/controller/PhabricatorSlowvoteCommentController.php',
     'PhabricatorSlowvoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteController.php',
     'PhabricatorSlowvoteDAO' => 'applications/slowvote/storage/PhabricatorSlowvoteDAO.php',
     'PhabricatorSlowvoteDefaultViewCapability' => 'applications/slowvote/capability/PhabricatorSlowvoteDefaultViewCapability.php',
     'PhabricatorSlowvoteEditController' => 'applications/slowvote/controller/PhabricatorSlowvoteEditController.php',
     'PhabricatorSlowvoteEditor' => 'applications/slowvote/editor/PhabricatorSlowvoteEditor.php',
     'PhabricatorSlowvoteListController' => 'applications/slowvote/controller/PhabricatorSlowvoteListController.php',
     'PhabricatorSlowvoteOption' => 'applications/slowvote/storage/PhabricatorSlowvoteOption.php',
     'PhabricatorSlowvotePoll' => 'applications/slowvote/storage/PhabricatorSlowvotePoll.php',
     'PhabricatorSlowvotePollController' => 'applications/slowvote/controller/PhabricatorSlowvotePollController.php',
     'PhabricatorSlowvotePollPHIDType' => 'applications/slowvote/phid/PhabricatorSlowvotePollPHIDType.php',
     'PhabricatorSlowvoteQuery' => 'applications/slowvote/query/PhabricatorSlowvoteQuery.php',
     'PhabricatorSlowvoteSchemaSpec' => 'applications/slowvote/storage/PhabricatorSlowvoteSchemaSpec.php',
     'PhabricatorSlowvoteSearchEngine' => 'applications/slowvote/query/PhabricatorSlowvoteSearchEngine.php',
     'PhabricatorSlowvoteTransaction' => 'applications/slowvote/storage/PhabricatorSlowvoteTransaction.php',
     'PhabricatorSlowvoteTransactionComment' => 'applications/slowvote/storage/PhabricatorSlowvoteTransactionComment.php',
     'PhabricatorSlowvoteTransactionQuery' => 'applications/slowvote/query/PhabricatorSlowvoteTransactionQuery.php',
     'PhabricatorSlowvoteVoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteVoteController.php',
     'PhabricatorSlug' => 'infrastructure/util/PhabricatorSlug.php',
     'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php',
     'PhabricatorSortTableExample' => 'applications/uiexample/examples/PhabricatorSortTableExample.php',
     'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php',
     'PhabricatorStandardCustomField' => 'infrastructure/customfield/standard/PhabricatorStandardCustomField.php',
     'PhabricatorStandardCustomFieldBool' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldBool.php',
     'PhabricatorStandardCustomFieldCredential' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldCredential.php',
     'PhabricatorStandardCustomFieldDate' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldDate.php',
     'PhabricatorStandardCustomFieldHeader' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldHeader.php',
     'PhabricatorStandardCustomFieldInt' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldInt.php',
     'PhabricatorStandardCustomFieldInterface' => 'infrastructure/customfield/interface/PhabricatorStandardCustomFieldInterface.php',
     'PhabricatorStandardCustomFieldPHIDs' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldPHIDs.php',
     'PhabricatorStandardCustomFieldRemarkup' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldRemarkup.php',
     'PhabricatorStandardCustomFieldSelect' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldSelect.php',
     'PhabricatorStandardCustomFieldText' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php',
     'PhabricatorStandardCustomFieldUsers' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldUsers.php',
     'PhabricatorStandardPageView' => 'view/page/PhabricatorStandardPageView.php',
     'PhabricatorStatusController' => 'applications/system/controller/PhabricatorStatusController.php',
     'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php',
     'PhabricatorStorageManagementAPI' => 'infrastructure/storage/management/PhabricatorStorageManagementAPI.php',
     'PhabricatorStorageManagementAdjustWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementAdjustWorkflow.php',
     'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php',
     'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php',
     'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.php',
     'PhabricatorStorageManagementProbeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementProbeWorkflow.php',
     'PhabricatorStorageManagementQuickstartWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementQuickstartWorkflow.php',
     'PhabricatorStorageManagementStatusWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementStatusWorkflow.php',
     'PhabricatorStorageManagementUpgradeWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementUpgradeWorkflow.php',
     'PhabricatorStorageManagementWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementWorkflow.php',
     'PhabricatorStoragePatch' => 'infrastructure/storage/management/PhabricatorStoragePatch.php',
     'PhabricatorStorageSchemaSpec' => 'infrastructure/storage/schema/PhabricatorStorageSchemaSpec.php',
     'PhabricatorSubscribableInterface' => 'applications/subscriptions/interface/PhabricatorSubscribableInterface.php',
     'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
     'PhabricatorSubscriptionsApplication' => 'applications/subscriptions/application/PhabricatorSubscriptionsApplication.php',
     'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
     'PhabricatorSubscriptionsEditor' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php',
     'PhabricatorSubscriptionsListController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsListController.php',
     'PhabricatorSubscriptionsTransactionController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsTransactionController.php',
     'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php',
     'PhabricatorSupportApplication' => 'applications/support/application/PhabricatorSupportApplication.php',
     'PhabricatorSyntaxHighlighter' => 'infrastructure/markup/PhabricatorSyntaxHighlighter.php',
     'PhabricatorSyntaxHighlightingConfigOptions' => 'applications/config/option/PhabricatorSyntaxHighlightingConfigOptions.php',
     'PhabricatorSystemAction' => 'applications/system/action/PhabricatorSystemAction.php',
     'PhabricatorSystemActionEngine' => 'applications/system/engine/PhabricatorSystemActionEngine.php',
     'PhabricatorSystemActionGarbageCollector' => 'applications/system/garbagecollector/PhabricatorSystemActionGarbageCollector.php',
     'PhabricatorSystemActionLog' => 'applications/system/storage/PhabricatorSystemActionLog.php',
     'PhabricatorSystemActionRateLimitException' => 'applications/system/exception/PhabricatorSystemActionRateLimitException.php',
     'PhabricatorSystemApplication' => 'applications/system/application/PhabricatorSystemApplication.php',
     'PhabricatorSystemDAO' => 'applications/system/storage/PhabricatorSystemDAO.php',
     'PhabricatorSystemDestructionGarbageCollector' => 'applications/system/garbagecollector/PhabricatorSystemDestructionGarbageCollector.php',
     'PhabricatorSystemDestructionLog' => 'applications/system/storage/PhabricatorSystemDestructionLog.php',
     'PhabricatorSystemRemoveDestroyWorkflow' => 'applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php',
     'PhabricatorSystemRemoveLogWorkflow' => 'applications/system/management/PhabricatorSystemRemoveLogWorkflow.php',
     'PhabricatorSystemRemoveWorkflow' => 'applications/system/management/PhabricatorSystemRemoveWorkflow.php',
     'PhabricatorSystemSelectEncodingController' => 'applications/system/controller/PhabricatorSystemSelectEncodingController.php',
     'PhabricatorSystemSelectHighlightController' => 'applications/system/controller/PhabricatorSystemSelectHighlightController.php',
     'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/PhabricatorTaskmasterDaemon.php',
     'PhabricatorTestApplication' => 'applications/base/controller/__tests__/PhabricatorTestApplication.php',
     'PhabricatorTestCase' => 'infrastructure/testing/PhabricatorTestCase.php',
     'PhabricatorTestController' => 'applications/base/controller/__tests__/PhabricatorTestController.php',
     'PhabricatorTestDataGenerator' => 'applications/lipsum/generator/PhabricatorTestDataGenerator.php',
     'PhabricatorTestStorageEngine' => 'applications/files/engine/PhabricatorTestStorageEngine.php',
     'PhabricatorTestWorker' => 'infrastructure/daemon/workers/__tests__/PhabricatorTestWorker.php',
     'PhabricatorTime' => 'infrastructure/time/PhabricatorTime.php',
     'PhabricatorTimeGuard' => 'infrastructure/time/PhabricatorTimeGuard.php',
     'PhabricatorTimeTestCase' => 'infrastructure/time/__tests__/PhabricatorTimeTestCase.php',
     'PhabricatorToken' => 'applications/tokens/storage/PhabricatorToken.php',
     'PhabricatorTokenController' => 'applications/tokens/controller/PhabricatorTokenController.php',
     'PhabricatorTokenCount' => 'applications/tokens/storage/PhabricatorTokenCount.php',
     'PhabricatorTokenCountQuery' => 'applications/tokens/query/PhabricatorTokenCountQuery.php',
     'PhabricatorTokenDAO' => 'applications/tokens/storage/PhabricatorTokenDAO.php',
     'PhabricatorTokenGiveController' => 'applications/tokens/controller/PhabricatorTokenGiveController.php',
     'PhabricatorTokenGiven' => 'applications/tokens/storage/PhabricatorTokenGiven.php',
     'PhabricatorTokenGivenController' => 'applications/tokens/controller/PhabricatorTokenGivenController.php',
     'PhabricatorTokenGivenEditor' => 'applications/tokens/editor/PhabricatorTokenGivenEditor.php',
     'PhabricatorTokenGivenFeedStory' => 'applications/tokens/feed/PhabricatorTokenGivenFeedStory.php',
     'PhabricatorTokenGivenQuery' => 'applications/tokens/query/PhabricatorTokenGivenQuery.php',
     'PhabricatorTokenLeaderController' => 'applications/tokens/controller/PhabricatorTokenLeaderController.php',
     'PhabricatorTokenQuery' => 'applications/tokens/query/PhabricatorTokenQuery.php',
     'PhabricatorTokenReceiverInterface' => 'applications/tokens/interface/PhabricatorTokenReceiverInterface.php',
     'PhabricatorTokenReceiverQuery' => 'applications/tokens/query/PhabricatorTokenReceiverQuery.php',
     'PhabricatorTokenTokenPHIDType' => 'applications/tokens/phid/PhabricatorTokenTokenPHIDType.php',
     'PhabricatorTokenUIEventListener' => 'applications/tokens/event/PhabricatorTokenUIEventListener.php',
     'PhabricatorTokensApplication' => 'applications/tokens/application/PhabricatorTokensApplication.php',
     'PhabricatorTransactionView' => 'view/layout/PhabricatorTransactionView.php',
     'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php',
     'PhabricatorTransactionsApplication' => 'applications/transactions/application/PhabricatorTransactionsApplication.php',
     'PhabricatorTransformedFile' => 'applications/files/storage/PhabricatorTransformedFile.php',
     'PhabricatorTranslation' => 'infrastructure/internationalization/translation/PhabricatorTranslation.php',
     'PhabricatorTranslationsConfigOptions' => 'applications/config/option/PhabricatorTranslationsConfigOptions.php',
     'PhabricatorTrivialTestCase' => 'infrastructure/testing/__tests__/PhabricatorTrivialTestCase.php',
     'PhabricatorTwitchAuthProvider' => 'applications/auth/provider/PhabricatorTwitchAuthProvider.php',
     'PhabricatorTwitterAuthProvider' => 'applications/auth/provider/PhabricatorTwitterAuthProvider.php',
     'PhabricatorTwoColumnExample' => 'applications/uiexample/examples/PhabricatorTwoColumnExample.php',
     'PhabricatorTypeaheadApplication' => 'applications/typeahead/application/PhabricatorTypeaheadApplication.php',
     'PhabricatorTypeaheadCompositeDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadCompositeDatasource.php',
     'PhabricatorTypeaheadDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php',
     'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/PhabricatorTypeaheadDatasourceController.php',
     'PhabricatorTypeaheadModularDatasourceController' => 'applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php',
     'PhabricatorTypeaheadMonogramDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadMonogramDatasource.php',
     'PhabricatorTypeaheadNoOwnerDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadNoOwnerDatasource.php',
     'PhabricatorTypeaheadOwnerDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadOwnerDatasource.php',
     'PhabricatorTypeaheadResult' => 'applications/typeahead/storage/PhabricatorTypeaheadResult.php',
     'PhabricatorTypeaheadRuntimeCompositeDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadRuntimeCompositeDatasource.php',
     'PhabricatorUIConfigOptions' => 'applications/config/option/PhabricatorUIConfigOptions.php',
     'PhabricatorUIExample' => 'applications/uiexample/examples/PhabricatorUIExample.php',
     'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/PhabricatorUIExampleRenderController.php',
     'PhabricatorUIExamplesApplication' => 'applications/uiexample/application/PhabricatorUIExamplesApplication.php',
     'PhabricatorUIListFilterExample' => 'applications/uiexample/examples/PhabricatorUIListFilterExample.php',
     'PhabricatorUINotificationExample' => 'applications/uiexample/examples/PhabricatorUINotificationExample.php',
     'PhabricatorUIPagerExample' => 'applications/uiexample/examples/PhabricatorUIPagerExample.php',
     'PhabricatorUIStatusExample' => 'applications/uiexample/examples/PhabricatorUIStatusExample.php',
     'PhabricatorUITooltipExample' => 'applications/uiexample/examples/PhabricatorUITooltipExample.php',
     'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php',
     'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php',
     'PhabricatorUserBlurbField' => 'applications/people/customfield/PhabricatorUserBlurbField.php',
     'PhabricatorUserConfigOptions' => 'applications/people/config/PhabricatorUserConfigOptions.php',
     'PhabricatorUserConfiguredCustomField' => 'applications/people/customfield/PhabricatorUserConfiguredCustomField.php',
     'PhabricatorUserConfiguredCustomFieldStorage' => 'applications/people/storage/PhabricatorUserConfiguredCustomFieldStorage.php',
     'PhabricatorUserCustomField' => 'applications/people/customfield/PhabricatorUserCustomField.php',
     'PhabricatorUserCustomFieldNumericIndex' => 'applications/people/storage/PhabricatorUserCustomFieldNumericIndex.php',
     'PhabricatorUserCustomFieldStringIndex' => 'applications/people/storage/PhabricatorUserCustomFieldStringIndex.php',
     'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php',
     'PhabricatorUserEditor' => 'applications/people/editor/PhabricatorUserEditor.php',
     'PhabricatorUserEditorTestCase' => 'applications/people/editor/__tests__/PhabricatorUserEditorTestCase.php',
     'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php',
     'PhabricatorUserEmailTestCase' => 'applications/people/storage/__tests__/PhabricatorUserEmailTestCase.php',
     'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php',
     'PhabricatorUserLogView' => 'applications/people/view/PhabricatorUserLogView.php',
     'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
     'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
     'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php',
     'PhabricatorUserRealNameField' => 'applications/people/customfield/PhabricatorUserRealNameField.php',
     'PhabricatorUserRolesField' => 'applications/people/customfield/PhabricatorUserRolesField.php',
     'PhabricatorUserSchemaSpec' => 'applications/people/storage/PhabricatorUserSchemaSpec.php',
     'PhabricatorUserSearchIndexer' => 'applications/people/search/PhabricatorUserSearchIndexer.php',
     'PhabricatorUserSinceField' => 'applications/people/customfield/PhabricatorUserSinceField.php',
     'PhabricatorUserStatusField' => 'applications/people/customfield/PhabricatorUserStatusField.php',
     'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.php',
     'PhabricatorUserTitleField' => 'applications/people/customfield/PhabricatorUserTitleField.php',
     'PhabricatorUserTransaction' => 'applications/people/storage/PhabricatorUserTransaction.php',
     'PhabricatorVCSResponse' => 'applications/repository/response/PhabricatorVCSResponse.php',
     'PhabricatorWordPressAuthProvider' => 'applications/auth/provider/PhabricatorWordPressAuthProvider.php',
     'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php',
     'PhabricatorWorkerActiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerActiveTask.php',
     'PhabricatorWorkerArchiveTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerArchiveTask.php',
     'PhabricatorWorkerDAO' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerDAO.php',
     'PhabricatorWorkerLeaseQuery' => 'infrastructure/daemon/workers/query/PhabricatorWorkerLeaseQuery.php',
     'PhabricatorWorkerManagementFloodWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementFloodWorkflow.php',
     'PhabricatorWorkerManagementWorkflow' => 'infrastructure/daemon/workers/management/PhabricatorWorkerManagementWorkflow.php',
     'PhabricatorWorkerPermanentFailureException' => 'infrastructure/daemon/workers/exception/PhabricatorWorkerPermanentFailureException.php',
     'PhabricatorWorkerTask' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTask.php',
     'PhabricatorWorkerTaskData' => 'infrastructure/daemon/workers/storage/PhabricatorWorkerTaskData.php',
     'PhabricatorWorkerTaskDetailController' => 'applications/daemon/controller/PhabricatorWorkerTaskDetailController.php',
     'PhabricatorWorkerTaskUpdateController' => 'applications/daemon/controller/PhabricatorWorkerTaskUpdateController.php',
     'PhabricatorWorkerTestCase' => 'infrastructure/daemon/workers/__tests__/PhabricatorWorkerTestCase.php',
     'PhabricatorWorkerYieldException' => 'infrastructure/daemon/workers/exception/PhabricatorWorkerYieldException.php',
     'PhabricatorWorkingCopyDiscoveryTestCase' => 'applications/repository/engine/__tests__/PhabricatorWorkingCopyDiscoveryTestCase.php',
     'PhabricatorWorkingCopyPullTestCase' => 'applications/repository/engine/__tests__/PhabricatorWorkingCopyPullTestCase.php',
     'PhabricatorWorkingCopyTestCase' => 'applications/repository/engine/__tests__/PhabricatorWorkingCopyTestCase.php',
     'PhabricatorXHPASTViewController' => 'applications/phpast/controller/PhabricatorXHPASTViewController.php',
     'PhabricatorXHPASTViewDAO' => 'applications/phpast/storage/PhabricatorXHPASTViewDAO.php',
     'PhabricatorXHPASTViewFrameController' => 'applications/phpast/controller/PhabricatorXHPASTViewFrameController.php',
     'PhabricatorXHPASTViewFramesetController' => 'applications/phpast/controller/PhabricatorXHPASTViewFramesetController.php',
     'PhabricatorXHPASTViewInputController' => 'applications/phpast/controller/PhabricatorXHPASTViewInputController.php',
     'PhabricatorXHPASTViewPanelController' => 'applications/phpast/controller/PhabricatorXHPASTViewPanelController.php',
     'PhabricatorXHPASTViewParseTree' => 'applications/phpast/storage/PhabricatorXHPASTViewParseTree.php',
     'PhabricatorXHPASTViewRunController' => 'applications/phpast/controller/PhabricatorXHPASTViewRunController.php',
     'PhabricatorXHPASTViewStreamController' => 'applications/phpast/controller/PhabricatorXHPASTViewStreamController.php',
     'PhabricatorXHPASTViewTreeController' => 'applications/phpast/controller/PhabricatorXHPASTViewTreeController.php',
     'PhabricatorXHProfApplication' => 'applications/xhprof/application/PhabricatorXHProfApplication.php',
     'PhabricatorXHProfController' => 'applications/xhprof/controller/PhabricatorXHProfController.php',
     'PhabricatorXHProfDAO' => 'applications/xhprof/storage/PhabricatorXHProfDAO.php',
     'PhabricatorXHProfProfileController' => 'applications/xhprof/controller/PhabricatorXHProfProfileController.php',
     'PhabricatorXHProfProfileSymbolView' => 'applications/xhprof/view/PhabricatorXHProfProfileSymbolView.php',
     'PhabricatorXHProfProfileTopLevelView' => 'applications/xhprof/view/PhabricatorXHProfProfileTopLevelView.php',
     'PhabricatorXHProfProfileView' => 'applications/xhprof/view/PhabricatorXHProfProfileView.php',
     'PhabricatorXHProfSample' => 'applications/xhprof/storage/PhabricatorXHProfSample.php',
     'PhabricatorXHProfSampleListController' => 'applications/xhprof/controller/PhabricatorXHProfSampleListController.php',
     'PhabricatorYoutubeRemarkupRule' => 'infrastructure/markup/rule/PhabricatorYoutubeRemarkupRule.php',
     'PhameBasicBlogSkin' => 'applications/phame/skins/PhameBasicBlogSkin.php',
     'PhameBasicTemplateBlogSkin' => 'applications/phame/skins/PhameBasicTemplateBlogSkin.php',
     'PhameBlog' => 'applications/phame/storage/PhameBlog.php',
     'PhameBlogDeleteController' => 'applications/phame/controller/blog/PhameBlogDeleteController.php',
     'PhameBlogEditController' => 'applications/phame/controller/blog/PhameBlogEditController.php',
     'PhameBlogFeedController' => 'applications/phame/controller/blog/PhameBlogFeedController.php',
     'PhameBlogListController' => 'applications/phame/controller/blog/PhameBlogListController.php',
     'PhameBlogLiveController' => 'applications/phame/controller/blog/PhameBlogLiveController.php',
     'PhameBlogQuery' => 'applications/phame/query/PhameBlogQuery.php',
     'PhameBlogSkin' => 'applications/phame/skins/PhameBlogSkin.php',
     'PhameBlogViewController' => 'applications/phame/controller/blog/PhameBlogViewController.php',
     'PhameCelerityResources' => 'applications/phame/celerity/PhameCelerityResources.php',
     'PhameConduitAPIMethod' => 'applications/phame/conduit/PhameConduitAPIMethod.php',
     'PhameController' => 'applications/phame/controller/PhameController.php',
     'PhameCreatePostConduitAPIMethod' => 'applications/phame/conduit/PhameCreatePostConduitAPIMethod.php',
     'PhameDAO' => 'applications/phame/storage/PhameDAO.php',
     'PhamePost' => 'applications/phame/storage/PhamePost.php',
     'PhamePostDeleteController' => 'applications/phame/controller/post/PhamePostDeleteController.php',
     'PhamePostEditController' => 'applications/phame/controller/post/PhamePostEditController.php',
     'PhamePostFramedController' => 'applications/phame/controller/post/PhamePostFramedController.php',
     'PhamePostListController' => 'applications/phame/controller/post/PhamePostListController.php',
     'PhamePostNewController' => 'applications/phame/controller/post/PhamePostNewController.php',
     'PhamePostNotLiveController' => 'applications/phame/controller/post/PhamePostNotLiveController.php',
     'PhamePostPreviewController' => 'applications/phame/controller/post/PhamePostPreviewController.php',
     'PhamePostPublishController' => 'applications/phame/controller/post/PhamePostPublishController.php',
     'PhamePostQuery' => 'applications/phame/query/PhamePostQuery.php',
     'PhamePostUnpublishController' => 'applications/phame/controller/post/PhamePostUnpublishController.php',
     'PhamePostView' => 'applications/phame/view/PhamePostView.php',
     'PhamePostViewController' => 'applications/phame/controller/post/PhamePostViewController.php',
     'PhameQueryConduitAPIMethod' => 'applications/phame/conduit/PhameQueryConduitAPIMethod.php',
     'PhameQueryPostsConduitAPIMethod' => 'applications/phame/conduit/PhameQueryPostsConduitAPIMethod.php',
     'PhameResourceController' => 'applications/phame/controller/PhameResourceController.php',
     'PhameSchemaSpec' => 'applications/phame/storage/PhameSchemaSpec.php',
     'PhameSkinSpecification' => 'applications/phame/skins/PhameSkinSpecification.php',
     'PhluxController' => 'applications/phlux/controller/PhluxController.php',
     'PhluxDAO' => 'applications/phlux/storage/PhluxDAO.php',
     'PhluxEditController' => 'applications/phlux/controller/PhluxEditController.php',
     'PhluxListController' => 'applications/phlux/controller/PhluxListController.php',
     'PhluxTransaction' => 'applications/phlux/storage/PhluxTransaction.php',
     'PhluxTransactionQuery' => 'applications/phlux/query/PhluxTransactionQuery.php',
     'PhluxVariable' => 'applications/phlux/storage/PhluxVariable.php',
     'PhluxVariableEditor' => 'applications/phlux/editor/PhluxVariableEditor.php',
     'PhluxVariablePHIDType' => 'applications/phlux/phid/PhluxVariablePHIDType.php',
     'PhluxVariableQuery' => 'applications/phlux/query/PhluxVariableQuery.php',
     'PhluxViewController' => 'applications/phlux/controller/PhluxViewController.php',
     'PholioActionMenuEventListener' => 'applications/pholio/event/PholioActionMenuEventListener.php',
     'PholioConstants' => 'applications/pholio/constants/PholioConstants.php',
     'PholioController' => 'applications/pholio/controller/PholioController.php',
     'PholioDAO' => 'applications/pholio/storage/PholioDAO.php',
     'PholioDefaultEditCapability' => 'applications/pholio/capability/PholioDefaultEditCapability.php',
     'PholioDefaultViewCapability' => 'applications/pholio/capability/PholioDefaultViewCapability.php',
     'PholioImage' => 'applications/pholio/storage/PholioImage.php',
     'PholioImagePHIDType' => 'applications/pholio/phid/PholioImagePHIDType.php',
     'PholioImageQuery' => 'applications/pholio/query/PholioImageQuery.php',
     'PholioImageUploadController' => 'applications/pholio/controller/PholioImageUploadController.php',
     'PholioInlineController' => 'applications/pholio/controller/PholioInlineController.php',
     'PholioInlineListController' => 'applications/pholio/controller/PholioInlineListController.php',
     'PholioInlineThumbController' => 'applications/pholio/controller/PholioInlineThumbController.php',
     'PholioMock' => 'applications/pholio/storage/PholioMock.php',
     'PholioMockCommentController' => 'applications/pholio/controller/PholioMockCommentController.php',
     'PholioMockEditController' => 'applications/pholio/controller/PholioMockEditController.php',
     'PholioMockEditor' => 'applications/pholio/editor/PholioMockEditor.php',
     'PholioMockEmbedView' => 'applications/pholio/view/PholioMockEmbedView.php',
     'PholioMockImagesView' => 'applications/pholio/view/PholioMockImagesView.php',
     'PholioMockListController' => 'applications/pholio/controller/PholioMockListController.php',
     'PholioMockMailReceiver' => 'applications/pholio/mail/PholioMockMailReceiver.php',
     'PholioMockPHIDType' => 'applications/pholio/phid/PholioMockPHIDType.php',
     'PholioMockQuery' => 'applications/pholio/query/PholioMockQuery.php',
     'PholioMockSearchEngine' => 'applications/pholio/query/PholioMockSearchEngine.php',
     'PholioMockThumbGridView' => 'applications/pholio/view/PholioMockThumbGridView.php',
     'PholioMockViewController' => 'applications/pholio/controller/PholioMockViewController.php',
     'PholioRemarkupRule' => 'applications/pholio/remarkup/PholioRemarkupRule.php',
     'PholioReplyHandler' => 'applications/pholio/mail/PholioReplyHandler.php',
     'PholioSchemaSpec' => 'applications/pholio/storage/PholioSchemaSpec.php',
     'PholioSearchIndexer' => 'applications/pholio/search/PholioSearchIndexer.php',
     'PholioTransaction' => 'applications/pholio/storage/PholioTransaction.php',
     'PholioTransactionComment' => 'applications/pholio/storage/PholioTransactionComment.php',
     'PholioTransactionQuery' => 'applications/pholio/query/PholioTransactionQuery.php',
     'PholioTransactionType' => 'applications/pholio/constants/PholioTransactionType.php',
     'PholioTransactionView' => 'applications/pholio/view/PholioTransactionView.php',
     'PholioUploadedImageView' => 'applications/pholio/view/PholioUploadedImageView.php',
     'PhortuneAccount' => 'applications/phortune/storage/PhortuneAccount.php',
     'PhortuneAccountEditController' => 'applications/phortune/controller/PhortuneAccountEditController.php',
     'PhortuneAccountEditor' => 'applications/phortune/editor/PhortuneAccountEditor.php',
     'PhortuneAccountHasMemberEdgeType' => 'applications/phortune/edge/PhortuneAccountHasMemberEdgeType.php',
     'PhortuneAccountListController' => 'applications/phortune/controller/PhortuneAccountListController.php',
     'PhortuneAccountPHIDType' => 'applications/phortune/phid/PhortuneAccountPHIDType.php',
     'PhortuneAccountQuery' => 'applications/phortune/query/PhortuneAccountQuery.php',
     'PhortuneAccountTransaction' => 'applications/phortune/storage/PhortuneAccountTransaction.php',
     'PhortuneAccountTransactionQuery' => 'applications/phortune/query/PhortuneAccountTransactionQuery.php',
     'PhortuneAccountViewController' => 'applications/phortune/controller/PhortuneAccountViewController.php',
     'PhortuneBalancedPaymentProvider' => 'applications/phortune/provider/PhortuneBalancedPaymentProvider.php',
     'PhortuneCart' => 'applications/phortune/storage/PhortuneCart.php',
     'PhortuneCartAcceptController' => 'applications/phortune/controller/PhortuneCartAcceptController.php',
     'PhortuneCartCancelController' => 'applications/phortune/controller/PhortuneCartCancelController.php',
     'PhortuneCartCheckoutController' => 'applications/phortune/controller/PhortuneCartCheckoutController.php',
     'PhortuneCartController' => 'applications/phortune/controller/PhortuneCartController.php',
     'PhortuneCartEditor' => 'applications/phortune/editor/PhortuneCartEditor.php',
     'PhortuneCartImplementation' => 'applications/phortune/cart/PhortuneCartImplementation.php',
     'PhortuneCartListController' => 'applications/phortune/controller/PhortuneCartListController.php',
     'PhortuneCartPHIDType' => 'applications/phortune/phid/PhortuneCartPHIDType.php',
     'PhortuneCartQuery' => 'applications/phortune/query/PhortuneCartQuery.php',
     'PhortuneCartReplyHandler' => 'applications/phortune/mail/PhortuneCartReplyHandler.php',
     'PhortuneCartSearchEngine' => 'applications/phortune/query/PhortuneCartSearchEngine.php',
     'PhortuneCartTransaction' => 'applications/phortune/storage/PhortuneCartTransaction.php',
     'PhortuneCartTransactionQuery' => 'applications/phortune/query/PhortuneCartTransactionQuery.php',
     'PhortuneCartUpdateController' => 'applications/phortune/controller/PhortuneCartUpdateController.php',
     'PhortuneCartViewController' => 'applications/phortune/controller/PhortuneCartViewController.php',
     'PhortuneCharge' => 'applications/phortune/storage/PhortuneCharge.php',
     'PhortuneChargeListController' => 'applications/phortune/controller/PhortuneChargeListController.php',
     'PhortuneChargePHIDType' => 'applications/phortune/phid/PhortuneChargePHIDType.php',
     'PhortuneChargeQuery' => 'applications/phortune/query/PhortuneChargeQuery.php',
     'PhortuneChargeSearchEngine' => 'applications/phortune/query/PhortuneChargeSearchEngine.php',
     'PhortuneChargeTableView' => 'applications/phortune/view/PhortuneChargeTableView.php',
     'PhortuneConstants' => 'applications/phortune/constants/PhortuneConstants.php',
     'PhortuneController' => 'applications/phortune/controller/PhortuneController.php',
     'PhortuneCreditCardForm' => 'applications/phortune/view/PhortuneCreditCardForm.php',
     'PhortuneCurrency' => 'applications/phortune/currency/PhortuneCurrency.php',
     'PhortuneCurrencySerializer' => 'applications/phortune/currency/PhortuneCurrencySerializer.php',
     'PhortuneCurrencyTestCase' => 'applications/phortune/currency/__tests__/PhortuneCurrencyTestCase.php',
     'PhortuneDAO' => 'applications/phortune/storage/PhortuneDAO.php',
     'PhortuneErrCode' => 'applications/phortune/constants/PhortuneErrCode.php',
     'PhortuneLandingController' => 'applications/phortune/controller/PhortuneLandingController.php',
     'PhortuneMemberHasAccountEdgeType' => 'applications/phortune/edge/PhortuneMemberHasAccountEdgeType.php',
     'PhortuneMemberHasMerchantEdgeType' => 'applications/phortune/edge/PhortuneMemberHasMerchantEdgeType.php',
     'PhortuneMerchant' => 'applications/phortune/storage/PhortuneMerchant.php',
     'PhortuneMerchantCapability' => 'applications/phortune/capability/PhortuneMerchantCapability.php',
     'PhortuneMerchantController' => 'applications/phortune/controller/PhortuneMerchantController.php',
     'PhortuneMerchantEditController' => 'applications/phortune/controller/PhortuneMerchantEditController.php',
     'PhortuneMerchantEditor' => 'applications/phortune/editor/PhortuneMerchantEditor.php',
     'PhortuneMerchantHasMemberEdgeType' => 'applications/phortune/edge/PhortuneMerchantHasMemberEdgeType.php',
     'PhortuneMerchantListController' => 'applications/phortune/controller/PhortuneMerchantListController.php',
     'PhortuneMerchantPHIDType' => 'applications/phortune/phid/PhortuneMerchantPHIDType.php',
     'PhortuneMerchantQuery' => 'applications/phortune/query/PhortuneMerchantQuery.php',
     'PhortuneMerchantSearchEngine' => 'applications/phortune/query/PhortuneMerchantSearchEngine.php',
     'PhortuneMerchantTransaction' => 'applications/phortune/storage/PhortuneMerchantTransaction.php',
     'PhortuneMerchantTransactionQuery' => 'applications/phortune/query/PhortuneMerchantTransactionQuery.php',
     'PhortuneMerchantViewController' => 'applications/phortune/controller/PhortuneMerchantViewController.php',
     'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php',
     'PhortuneMultiplePaymentProvidersException' => 'applications/phortune/exception/PhortuneMultiplePaymentProvidersException.php',
     'PhortuneNoPaymentProviderException' => 'applications/phortune/exception/PhortuneNoPaymentProviderException.php',
     'PhortuneNotImplementedException' => 'applications/phortune/exception/PhortuneNotImplementedException.php',
     'PhortuneOrderTableView' => 'applications/phortune/view/PhortuneOrderTableView.php',
     'PhortunePayPalPaymentProvider' => 'applications/phortune/provider/PhortunePayPalPaymentProvider.php',
     'PhortunePaymentMethod' => 'applications/phortune/storage/PhortunePaymentMethod.php',
     'PhortunePaymentMethodCreateController' => 'applications/phortune/controller/PhortunePaymentMethodCreateController.php',
     'PhortunePaymentMethodDisableController' => 'applications/phortune/controller/PhortunePaymentMethodDisableController.php',
     'PhortunePaymentMethodEditController' => 'applications/phortune/controller/PhortunePaymentMethodEditController.php',
     'PhortunePaymentMethodPHIDType' => 'applications/phortune/phid/PhortunePaymentMethodPHIDType.php',
     'PhortunePaymentMethodQuery' => 'applications/phortune/query/PhortunePaymentMethodQuery.php',
     'PhortunePaymentProvider' => 'applications/phortune/provider/PhortunePaymentProvider.php',
     'PhortunePaymentProviderConfig' => 'applications/phortune/storage/PhortunePaymentProviderConfig.php',
     'PhortunePaymentProviderConfigEditor' => 'applications/phortune/editor/PhortunePaymentProviderConfigEditor.php',
     'PhortunePaymentProviderConfigQuery' => 'applications/phortune/query/PhortunePaymentProviderConfigQuery.php',
     'PhortunePaymentProviderConfigTransaction' => 'applications/phortune/storage/PhortunePaymentProviderConfigTransaction.php',
     'PhortunePaymentProviderConfigTransactionQuery' => 'applications/phortune/query/PhortunePaymentProviderConfigTransactionQuery.php',
     'PhortunePaymentProviderPHIDType' => 'applications/phortune/phid/PhortunePaymentProviderPHIDType.php',
     'PhortuneProduct' => 'applications/phortune/storage/PhortuneProduct.php',
     'PhortuneProductImplementation' => 'applications/phortune/product/PhortuneProductImplementation.php',
     'PhortuneProductListController' => 'applications/phortune/controller/PhortuneProductListController.php',
     'PhortuneProductPHIDType' => 'applications/phortune/phid/PhortuneProductPHIDType.php',
     'PhortuneProductQuery' => 'applications/phortune/query/PhortuneProductQuery.php',
     'PhortuneProductViewController' => 'applications/phortune/controller/PhortuneProductViewController.php',
     'PhortuneProviderActionController' => 'applications/phortune/controller/PhortuneProviderActionController.php',
     'PhortuneProviderDisableController' => 'applications/phortune/controller/PhortuneProviderDisableController.php',
     'PhortuneProviderEditController' => 'applications/phortune/controller/PhortuneProviderEditController.php',
     'PhortunePurchase' => 'applications/phortune/storage/PhortunePurchase.php',
     'PhortunePurchasePHIDType' => 'applications/phortune/phid/PhortunePurchasePHIDType.php',
     'PhortunePurchaseQuery' => 'applications/phortune/query/PhortunePurchaseQuery.php',
     'PhortuneSchemaSpec' => 'applications/phortune/storage/PhortuneSchemaSpec.php',
     'PhortuneStripePaymentProvider' => 'applications/phortune/provider/PhortuneStripePaymentProvider.php',
     'PhortuneTestPaymentProvider' => 'applications/phortune/provider/PhortuneTestPaymentProvider.php',
     'PhortuneWePayPaymentProvider' => 'applications/phortune/provider/PhortuneWePayPaymentProvider.php',
     'PhragmentBrowseController' => 'applications/phragment/controller/PhragmentBrowseController.php',
     'PhragmentCanCreateCapability' => 'applications/phragment/capability/PhragmentCanCreateCapability.php',
     'PhragmentConduitAPIMethod' => 'applications/phragment/conduit/PhragmentConduitAPIMethod.php',
     'PhragmentController' => 'applications/phragment/controller/PhragmentController.php',
     'PhragmentCreateController' => 'applications/phragment/controller/PhragmentCreateController.php',
     'PhragmentDAO' => 'applications/phragment/storage/PhragmentDAO.php',
     'PhragmentFragment' => 'applications/phragment/storage/PhragmentFragment.php',
     'PhragmentFragmentPHIDType' => 'applications/phragment/phid/PhragmentFragmentPHIDType.php',
     'PhragmentFragmentQuery' => 'applications/phragment/query/PhragmentFragmentQuery.php',
     'PhragmentFragmentVersion' => 'applications/phragment/storage/PhragmentFragmentVersion.php',
     'PhragmentFragmentVersionPHIDType' => 'applications/phragment/phid/PhragmentFragmentVersionPHIDType.php',
     'PhragmentFragmentVersionQuery' => 'applications/phragment/query/PhragmentFragmentVersionQuery.php',
     'PhragmentGetPatchConduitAPIMethod' => 'applications/phragment/conduit/PhragmentGetPatchConduitAPIMethod.php',
     'PhragmentHistoryController' => 'applications/phragment/controller/PhragmentHistoryController.php',
     'PhragmentPatchController' => 'applications/phragment/controller/PhragmentPatchController.php',
     'PhragmentPatchUtil' => 'applications/phragment/util/PhragmentPatchUtil.php',
     'PhragmentPolicyController' => 'applications/phragment/controller/PhragmentPolicyController.php',
     'PhragmentQueryFragmentsConduitAPIMethod' => 'applications/phragment/conduit/PhragmentQueryFragmentsConduitAPIMethod.php',
     'PhragmentRevertController' => 'applications/phragment/controller/PhragmentRevertController.php',
     'PhragmentSchemaSpec' => 'applications/phragment/storage/PhragmentSchemaSpec.php',
     'PhragmentSnapshot' => 'applications/phragment/storage/PhragmentSnapshot.php',
     'PhragmentSnapshotChild' => 'applications/phragment/storage/PhragmentSnapshotChild.php',
     'PhragmentSnapshotChildQuery' => 'applications/phragment/query/PhragmentSnapshotChildQuery.php',
     'PhragmentSnapshotCreateController' => 'applications/phragment/controller/PhragmentSnapshotCreateController.php',
     'PhragmentSnapshotDeleteController' => 'applications/phragment/controller/PhragmentSnapshotDeleteController.php',
     'PhragmentSnapshotPHIDType' => 'applications/phragment/phid/PhragmentSnapshotPHIDType.php',
     'PhragmentSnapshotPromoteController' => 'applications/phragment/controller/PhragmentSnapshotPromoteController.php',
     'PhragmentSnapshotQuery' => 'applications/phragment/query/PhragmentSnapshotQuery.php',
     'PhragmentSnapshotViewController' => 'applications/phragment/controller/PhragmentSnapshotViewController.php',
     'PhragmentUpdateController' => 'applications/phragment/controller/PhragmentUpdateController.php',
     'PhragmentVersionController' => 'applications/phragment/controller/PhragmentVersionController.php',
     'PhragmentZIPController' => 'applications/phragment/controller/PhragmentZIPController.php',
     'PhrequentConduitAPIMethod' => 'applications/phrequent/conduit/PhrequentConduitAPIMethod.php',
     'PhrequentController' => 'applications/phrequent/controller/PhrequentController.php',
     'PhrequentDAO' => 'applications/phrequent/storage/PhrequentDAO.php',
     'PhrequentListController' => 'applications/phrequent/controller/PhrequentListController.php',
     'PhrequentPopConduitAPIMethod' => 'applications/phrequent/conduit/PhrequentPopConduitAPIMethod.php',
     'PhrequentPushConduitAPIMethod' => 'applications/phrequent/conduit/PhrequentPushConduitAPIMethod.php',
     'PhrequentSearchEngine' => 'applications/phrequent/query/PhrequentSearchEngine.php',
     'PhrequentTimeBlock' => 'applications/phrequent/storage/PhrequentTimeBlock.php',
     'PhrequentTimeBlockTestCase' => 'applications/phrequent/storage/__tests__/PhrequentTimeBlockTestCase.php',
     'PhrequentTimeSlices' => 'applications/phrequent/storage/PhrequentTimeSlices.php',
     'PhrequentTrackController' => 'applications/phrequent/controller/PhrequentTrackController.php',
     'PhrequentTrackableInterface' => 'applications/phrequent/interface/PhrequentTrackableInterface.php',
     'PhrequentTrackingConduitAPIMethod' => 'applications/phrequent/conduit/PhrequentTrackingConduitAPIMethod.php',
     'PhrequentTrackingEditor' => 'applications/phrequent/editor/PhrequentTrackingEditor.php',
     'PhrequentUIEventListener' => 'applications/phrequent/event/PhrequentUIEventListener.php',
     'PhrequentUserTime' => 'applications/phrequent/storage/PhrequentUserTime.php',
     'PhrequentUserTimeQuery' => 'applications/phrequent/query/PhrequentUserTimeQuery.php',
     'PhrictionActionConstants' => 'applications/phriction/constants/PhrictionActionConstants.php',
     'PhrictionChangeType' => 'applications/phriction/constants/PhrictionChangeType.php',
     'PhrictionConduitAPIMethod' => 'applications/phriction/conduit/PhrictionConduitAPIMethod.php',
     'PhrictionConstants' => 'applications/phriction/constants/PhrictionConstants.php',
     'PhrictionContent' => 'applications/phriction/storage/PhrictionContent.php',
     'PhrictionController' => 'applications/phriction/controller/PhrictionController.php',
     'PhrictionCreateConduitAPIMethod' => 'applications/phriction/conduit/PhrictionCreateConduitAPIMethod.php',
     'PhrictionDAO' => 'applications/phriction/storage/PhrictionDAO.php',
     'PhrictionDeleteController' => 'applications/phriction/controller/PhrictionDeleteController.php',
     'PhrictionDiffController' => 'applications/phriction/controller/PhrictionDiffController.php',
     'PhrictionDocument' => 'applications/phriction/storage/PhrictionDocument.php',
     'PhrictionDocumentController' => 'applications/phriction/controller/PhrictionDocumentController.php',
     'PhrictionDocumentHeraldAdapter' => 'applications/phriction/herald/PhrictionDocumentHeraldAdapter.php',
     'PhrictionDocumentPHIDType' => 'applications/phriction/phid/PhrictionDocumentPHIDType.php',
     'PhrictionDocumentPreviewController' => 'applications/phriction/controller/PhrictionDocumentPreviewController.php',
     'PhrictionDocumentQuery' => 'applications/phriction/query/PhrictionDocumentQuery.php',
     'PhrictionDocumentStatus' => 'applications/phriction/constants/PhrictionDocumentStatus.php',
     'PhrictionEditConduitAPIMethod' => 'applications/phriction/conduit/PhrictionEditConduitAPIMethod.php',
     'PhrictionEditController' => 'applications/phriction/controller/PhrictionEditController.php',
     'PhrictionHistoryConduitAPIMethod' => 'applications/phriction/conduit/PhrictionHistoryConduitAPIMethod.php',
     'PhrictionHistoryController' => 'applications/phriction/controller/PhrictionHistoryController.php',
     'PhrictionInfoConduitAPIMethod' => 'applications/phriction/conduit/PhrictionInfoConduitAPIMethod.php',
     'PhrictionListController' => 'applications/phriction/controller/PhrictionListController.php',
     'PhrictionMoveController' => 'applications/phriction/controller/PhrictionMoveController.php',
     'PhrictionNewController' => 'applications/phriction/controller/PhrictionNewController.php',
     'PhrictionRemarkupRule' => 'applications/phriction/markup/PhrictionRemarkupRule.php',
     'PhrictionReplyHandler' => 'applications/phriction/mail/PhrictionReplyHandler.php',
     'PhrictionSchemaSpec' => 'applications/phriction/storage/PhrictionSchemaSpec.php',
     'PhrictionSearchEngine' => 'applications/phriction/query/PhrictionSearchEngine.php',
     'PhrictionSearchIndexer' => 'applications/phriction/search/PhrictionSearchIndexer.php',
     'PhrictionTransaction' => 'applications/phriction/storage/PhrictionTransaction.php',
     'PhrictionTransactionComment' => 'applications/phriction/storage/PhrictionTransactionComment.php',
     'PhrictionTransactionEditor' => 'applications/phriction/editor/PhrictionTransactionEditor.php',
     'PhrictionTransactionQuery' => 'applications/phriction/query/PhrictionTransactionQuery.php',
     'PonderAddAnswerView' => 'applications/ponder/view/PonderAddAnswerView.php',
     'PonderAnswer' => 'applications/ponder/storage/PonderAnswer.php',
     'PonderAnswerCommentController' => 'applications/ponder/controller/PonderAnswerCommentController.php',
     'PonderAnswerEditController' => 'applications/ponder/controller/PonderAnswerEditController.php',
     'PonderAnswerEditor' => 'applications/ponder/editor/PonderAnswerEditor.php',
     'PonderAnswerHistoryController' => 'applications/ponder/controller/PonderAnswerHistoryController.php',
     'PonderAnswerPHIDType' => 'applications/ponder/phid/PonderAnswerPHIDType.php',
     'PonderAnswerQuery' => 'applications/ponder/query/PonderAnswerQuery.php',
     'PonderAnswerSaveController' => 'applications/ponder/controller/PonderAnswerSaveController.php',
     'PonderAnswerTransaction' => 'applications/ponder/storage/PonderAnswerTransaction.php',
     'PonderAnswerTransactionComment' => 'applications/ponder/storage/PonderAnswerTransactionComment.php',
     'PonderAnswerTransactionQuery' => 'applications/ponder/query/PonderAnswerTransactionQuery.php',
     'PonderConstants' => 'applications/ponder/constants/PonderConstants.php',
     'PonderController' => 'applications/ponder/controller/PonderController.php',
     'PonderDAO' => 'applications/ponder/storage/PonderDAO.php',
     'PonderEditor' => 'applications/ponder/editor/PonderEditor.php',
     'PonderQuestion' => 'applications/ponder/storage/PonderQuestion.php',
     'PonderQuestionCommentController' => 'applications/ponder/controller/PonderQuestionCommentController.php',
     'PonderQuestionEditController' => 'applications/ponder/controller/PonderQuestionEditController.php',
     'PonderQuestionEditor' => 'applications/ponder/editor/PonderQuestionEditor.php',
     'PonderQuestionHistoryController' => 'applications/ponder/controller/PonderQuestionHistoryController.php',
     'PonderQuestionListController' => 'applications/ponder/controller/PonderQuestionListController.php',
     'PonderQuestionMailReceiver' => 'applications/ponder/mail/PonderQuestionMailReceiver.php',
     'PonderQuestionPHIDType' => 'applications/ponder/phid/PonderQuestionPHIDType.php',
     'PonderQuestionQuery' => 'applications/ponder/query/PonderQuestionQuery.php',
     'PonderQuestionReplyHandler' => 'applications/ponder/mail/PonderQuestionReplyHandler.php',
     'PonderQuestionSearchEngine' => 'applications/ponder/query/PonderQuestionSearchEngine.php',
     'PonderQuestionStatus' => 'applications/ponder/constants/PonderQuestionStatus.php',
     'PonderQuestionStatusController' => 'applications/ponder/controller/PonderQuestionStatusController.php',
     'PonderQuestionTransaction' => 'applications/ponder/storage/PonderQuestionTransaction.php',
     'PonderQuestionTransactionComment' => 'applications/ponder/storage/PonderQuestionTransactionComment.php',
     'PonderQuestionTransactionQuery' => 'applications/ponder/query/PonderQuestionTransactionQuery.php',
     'PonderQuestionViewController' => 'applications/ponder/controller/PonderQuestionViewController.php',
     'PonderRemarkupRule' => 'applications/ponder/remarkup/PonderRemarkupRule.php',
     'PonderSchemaSpec' => 'applications/ponder/storage/PonderSchemaSpec.php',
     'PonderSearchIndexer' => 'applications/ponder/search/PonderSearchIndexer.php',
     'PonderTransactionFeedStory' => 'applications/ponder/feed/PonderTransactionFeedStory.php',
     'PonderVotableInterface' => 'applications/ponder/storage/PonderVotableInterface.php',
     'PonderVotableView' => 'applications/ponder/view/PonderVotableView.php',
     'PonderVote' => 'applications/ponder/constants/PonderVote.php',
     'PonderVoteEditor' => 'applications/ponder/editor/PonderVoteEditor.php',
     'PonderVoteSaveController' => 'applications/ponder/controller/PonderVoteSaveController.php',
     'ProjectBoardTaskCard' => 'applications/project/view/ProjectBoardTaskCard.php',
     'ProjectCanLockProjectsCapability' => 'applications/project/capability/ProjectCanLockProjectsCapability.php',
     'ProjectConduitAPIMethod' => 'applications/project/conduit/ProjectConduitAPIMethod.php',
     'ProjectCreateConduitAPIMethod' => 'applications/project/conduit/ProjectCreateConduitAPIMethod.php',
     'ProjectCreateProjectsCapability' => 'applications/project/capability/ProjectCreateProjectsCapability.php',
     'ProjectDefaultEditCapability' => 'applications/project/capability/ProjectDefaultEditCapability.php',
     'ProjectDefaultJoinCapability' => 'applications/project/capability/ProjectDefaultJoinCapability.php',
     'ProjectDefaultViewCapability' => 'applications/project/capability/ProjectDefaultViewCapability.php',
     'ProjectQueryConduitAPIMethod' => 'applications/project/conduit/ProjectQueryConduitAPIMethod.php',
     'ProjectRemarkupRule' => 'applications/project/remarkup/ProjectRemarkupRule.php',
     'ProjectRemarkupRuleTestCase' => 'applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php',
     'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php',
     'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php',
     'ReleephBranch' => 'applications/releeph/storage/ReleephBranch.php',
     'ReleephBranchAccessController' => 'applications/releeph/controller/branch/ReleephBranchAccessController.php',
     'ReleephBranchCommitFieldSpecification' => 'applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php',
     'ReleephBranchController' => 'applications/releeph/controller/branch/ReleephBranchController.php',
     'ReleephBranchCreateController' => 'applications/releeph/controller/branch/ReleephBranchCreateController.php',
     'ReleephBranchEditController' => 'applications/releeph/controller/branch/ReleephBranchEditController.php',
     'ReleephBranchEditor' => 'applications/releeph/editor/ReleephBranchEditor.php',
     'ReleephBranchHistoryController' => 'applications/releeph/controller/branch/ReleephBranchHistoryController.php',
     'ReleephBranchNamePreviewController' => 'applications/releeph/controller/branch/ReleephBranchNamePreviewController.php',
     'ReleephBranchPHIDType' => 'applications/releeph/phid/ReleephBranchPHIDType.php',
     'ReleephBranchPreviewView' => 'applications/releeph/view/branch/ReleephBranchPreviewView.php',
     'ReleephBranchQuery' => 'applications/releeph/query/ReleephBranchQuery.php',
     'ReleephBranchSearchEngine' => 'applications/releeph/query/ReleephBranchSearchEngine.php',
     'ReleephBranchTemplate' => 'applications/releeph/view/branch/ReleephBranchTemplate.php',
     'ReleephBranchTransaction' => 'applications/releeph/storage/ReleephBranchTransaction.php',
     'ReleephBranchTransactionQuery' => 'applications/releeph/query/ReleephBranchTransactionQuery.php',
     'ReleephBranchViewController' => 'applications/releeph/controller/branch/ReleephBranchViewController.php',
     'ReleephCommitFinder' => 'applications/releeph/commitfinder/ReleephCommitFinder.php',
     'ReleephCommitFinderException' => 'applications/releeph/commitfinder/ReleephCommitFinderException.php',
     'ReleephCommitMessageFieldSpecification' => 'applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php',
     'ReleephConduitAPIMethod' => 'applications/releeph/conduit/ReleephConduitAPIMethod.php',
     'ReleephController' => 'applications/releeph/controller/ReleephController.php',
     'ReleephDAO' => 'applications/releeph/storage/ReleephDAO.php',
     'ReleephDefaultFieldSelector' => 'applications/releeph/field/selector/ReleephDefaultFieldSelector.php',
     'ReleephDependsOnFieldSpecification' => 'applications/releeph/field/specification/ReleephDependsOnFieldSpecification.php',
     'ReleephDiffChurnFieldSpecification' => 'applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php',
     'ReleephDiffMessageFieldSpecification' => 'applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php',
     'ReleephDiffSizeFieldSpecification' => 'applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php',
     'ReleephFieldParseException' => 'applications/releeph/field/exception/ReleephFieldParseException.php',
     'ReleephFieldSelector' => 'applications/releeph/field/selector/ReleephFieldSelector.php',
     'ReleephFieldSpecification' => 'applications/releeph/field/specification/ReleephFieldSpecification.php',
     'ReleephGetBranchesConduitAPIMethod' => 'applications/releeph/conduit/ReleephGetBranchesConduitAPIMethod.php',
     'ReleephIntentFieldSpecification' => 'applications/releeph/field/specification/ReleephIntentFieldSpecification.php',
     'ReleephLevelFieldSpecification' => 'applications/releeph/field/specification/ReleephLevelFieldSpecification.php',
     'ReleephOriginalCommitFieldSpecification' => 'applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php',
     'ReleephProductActionController' => 'applications/releeph/controller/product/ReleephProductActionController.php',
     'ReleephProductController' => 'applications/releeph/controller/product/ReleephProductController.php',
     'ReleephProductCreateController' => 'applications/releeph/controller/product/ReleephProductCreateController.php',
     'ReleephProductEditController' => 'applications/releeph/controller/product/ReleephProductEditController.php',
     'ReleephProductEditor' => 'applications/releeph/editor/ReleephProductEditor.php',
     'ReleephProductHistoryController' => 'applications/releeph/controller/product/ReleephProductHistoryController.php',
     'ReleephProductListController' => 'applications/releeph/controller/product/ReleephProductListController.php',
     'ReleephProductPHIDType' => 'applications/releeph/phid/ReleephProductPHIDType.php',
     'ReleephProductQuery' => 'applications/releeph/query/ReleephProductQuery.php',
     'ReleephProductSearchEngine' => 'applications/releeph/query/ReleephProductSearchEngine.php',
     'ReleephProductTransaction' => 'applications/releeph/storage/ReleephProductTransaction.php',
     'ReleephProductTransactionQuery' => 'applications/releeph/query/ReleephProductTransactionQuery.php',
     'ReleephProductViewController' => 'applications/releeph/controller/product/ReleephProductViewController.php',
     'ReleephProject' => 'applications/releeph/storage/ReleephProject.php',
     'ReleephProjectInfoConduitAPIMethod' => 'applications/releeph/conduit/ReleephProjectInfoConduitAPIMethod.php',
     'ReleephQueryBranchesConduitAPIMethod' => 'applications/releeph/conduit/ReleephQueryBranchesConduitAPIMethod.php',
     'ReleephQueryProductsConduitAPIMethod' => 'applications/releeph/conduit/ReleephQueryProductsConduitAPIMethod.php',
     'ReleephQueryRequestsConduitAPIMethod' => 'applications/releeph/conduit/ReleephQueryRequestsConduitAPIMethod.php',
     'ReleephReasonFieldSpecification' => 'applications/releeph/field/specification/ReleephReasonFieldSpecification.php',
     'ReleephRequest' => 'applications/releeph/storage/ReleephRequest.php',
     'ReleephRequestActionController' => 'applications/releeph/controller/request/ReleephRequestActionController.php',
     'ReleephRequestCommentController' => 'applications/releeph/controller/request/ReleephRequestCommentController.php',
     'ReleephRequestConduitAPIMethod' => 'applications/releeph/conduit/ReleephRequestConduitAPIMethod.php',
     'ReleephRequestController' => 'applications/releeph/controller/request/ReleephRequestController.php',
     'ReleephRequestDifferentialCreateController' => 'applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php',
     'ReleephRequestEditController' => 'applications/releeph/controller/request/ReleephRequestEditController.php',
     'ReleephRequestMailReceiver' => 'applications/releeph/mail/ReleephRequestMailReceiver.php',
     'ReleephRequestPHIDType' => 'applications/releeph/phid/ReleephRequestPHIDType.php',
     'ReleephRequestQuery' => 'applications/releeph/query/ReleephRequestQuery.php',
     'ReleephRequestReplyHandler' => 'applications/releeph/mail/ReleephRequestReplyHandler.php',
     'ReleephRequestSearchEngine' => 'applications/releeph/query/ReleephRequestSearchEngine.php',
     'ReleephRequestStatus' => 'applications/releeph/constants/ReleephRequestStatus.php',
     'ReleephRequestTransaction' => 'applications/releeph/storage/ReleephRequestTransaction.php',
     'ReleephRequestTransactionComment' => 'applications/releeph/storage/ReleephRequestTransactionComment.php',
     'ReleephRequestTransactionQuery' => 'applications/releeph/query/ReleephRequestTransactionQuery.php',
     'ReleephRequestTransactionalEditor' => 'applications/releeph/editor/ReleephRequestTransactionalEditor.php',
     'ReleephRequestTypeaheadControl' => 'applications/releeph/view/request/ReleephRequestTypeaheadControl.php',
     'ReleephRequestTypeaheadController' => 'applications/releeph/controller/request/ReleephRequestTypeaheadController.php',
     'ReleephRequestView' => 'applications/releeph/view/ReleephRequestView.php',
     'ReleephRequestViewController' => 'applications/releeph/controller/request/ReleephRequestViewController.php',
     'ReleephRequestorFieldSpecification' => 'applications/releeph/field/specification/ReleephRequestorFieldSpecification.php',
     'ReleephRevisionFieldSpecification' => 'applications/releeph/field/specification/ReleephRevisionFieldSpecification.php',
     'ReleephSeverityFieldSpecification' => 'applications/releeph/field/specification/ReleephSeverityFieldSpecification.php',
     'ReleephSummaryFieldSpecification' => 'applications/releeph/field/specification/ReleephSummaryFieldSpecification.php',
     'ReleephWorkCanPushConduitAPIMethod' => 'applications/releeph/conduit/work/ReleephWorkCanPushConduitAPIMethod.php',
     'ReleephWorkGetAuthorInfoConduitAPIMethod' => 'applications/releeph/conduit/work/ReleephWorkGetAuthorInfoConduitAPIMethod.php',
     'ReleephWorkGetBranchCommitMessageConduitAPIMethod' => 'applications/releeph/conduit/work/ReleephWorkGetBranchCommitMessageConduitAPIMethod.php',
     'ReleephWorkGetBranchConduitAPIMethod' => 'applications/releeph/conduit/work/ReleephWorkGetBranchConduitAPIMethod.php',
     'ReleephWorkGetCommitMessageConduitAPIMethod' => 'applications/releeph/conduit/work/ReleephWorkGetCommitMessageConduitAPIMethod.php',
     'ReleephWorkNextRequestConduitAPIMethod' => 'applications/releeph/conduit/work/ReleephWorkNextRequestConduitAPIMethod.php',
     'ReleephWorkRecordConduitAPIMethod' => 'applications/releeph/conduit/work/ReleephWorkRecordConduitAPIMethod.php',
     'ReleephWorkRecordPickStatusConduitAPIMethod' => 'applications/releeph/conduit/work/ReleephWorkRecordPickStatusConduitAPIMethod.php',
     'RemarkupProcessConduitAPIMethod' => 'applications/remarkup/conduit/RemarkupProcessConduitAPIMethod.php',
     'RepositoryConduitAPIMethod' => 'applications/repository/conduit/RepositoryConduitAPIMethod.php',
     'RepositoryCreateConduitAPIMethod' => 'applications/repository/conduit/RepositoryCreateConduitAPIMethod.php',
     'RepositoryQueryConduitAPIMethod' => 'applications/repository/conduit/RepositoryQueryConduitAPIMethod.php',
     'ShellLogView' => 'applications/harbormaster/view/ShellLogView.php',
     'SlowvoteConduitAPIMethod' => 'applications/slowvote/conduit/SlowvoteConduitAPIMethod.php',
     'SlowvoteEmbedView' => 'applications/slowvote/view/SlowvoteEmbedView.php',
     'SlowvoteInfoConduitAPIMethod' => 'applications/slowvote/conduit/SlowvoteInfoConduitAPIMethod.php',
     'SlowvoteRemarkupRule' => 'applications/slowvote/remarkup/SlowvoteRemarkupRule.php',
     'SubscriptionListDialogBuilder' => 'applications/subscriptions/view/SubscriptionListDialogBuilder.php',
     'SubscriptionListStringBuilder' => 'applications/subscriptions/view/SubscriptionListStringBuilder.php',
     'TokenConduitAPIMethod' => 'applications/tokens/conduit/TokenConduitAPIMethod.php',
     'TokenGiveConduitAPIMethod' => 'applications/tokens/conduit/TokenGiveConduitAPIMethod.php',
     'TokenGivenConduitAPIMethod' => 'applications/tokens/conduit/TokenGivenConduitAPIMethod.php',
     'TokenQueryConduitAPIMethod' => 'applications/tokens/conduit/TokenQueryConduitAPIMethod.php',
     'UserAddStatusConduitAPIMethod' => 'applications/people/conduit/UserAddStatusConduitAPIMethod.php',
     'UserConduitAPIMethod' => 'applications/people/conduit/UserConduitAPIMethod.php',
     'UserDisableConduitAPIMethod' => 'applications/people/conduit/UserDisableConduitAPIMethod.php',
     'UserEnableConduitAPIMethod' => 'applications/people/conduit/UserEnableConduitAPIMethod.php',
     'UserFindConduitAPIMethod' => 'applications/people/conduit/UserFindConduitAPIMethod.php',
     'UserInfoConduitAPIMethod' => 'applications/people/conduit/UserInfoConduitAPIMethod.php',
     'UserQueryConduitAPIMethod' => 'applications/people/conduit/UserQueryConduitAPIMethod.php',
     'UserRemoveStatusConduitAPIMethod' => 'applications/people/conduit/UserRemoveStatusConduitAPIMethod.php',
     'UserWhoAmIConduitAPIMethod' => 'applications/people/conduit/UserWhoAmIConduitAPIMethod.php',
   ),
   'function' => array(
     '_phabricator_time_format' => 'view/viewutils.php',
     'celerity_generate_unique_node_id' => 'applications/celerity/api.php',
     'celerity_get_resource_uri' => 'applications/celerity/api.php',
     'implode_selected_handle_links' => 'applications/phid/handle/view/render.php',
     'javelin_tag' => 'infrastructure/javelin/markup.php',
     'phabricator_date' => 'view/viewutils.php',
     'phabricator_datetime' => 'view/viewutils.php',
     'phabricator_form' => 'infrastructure/javelin/markup.php',
     'phabricator_format_local_time' => 'view/viewutils.php',
     'phabricator_on_relative_date' => 'view/viewutils.php',
     'phabricator_relative_date' => 'view/viewutils.php',
     'phabricator_time' => 'view/viewutils.php',
     'phid_get_subtype' => 'applications/phid/utils.php',
     'phid_get_type' => 'applications/phid/utils.php',
     'phid_group_by_type' => 'applications/phid/utils.php',
     'require_celerity_resource' => 'applications/celerity/api.php',
   ),
   'xmap' => array(
     'AlmanacAddress' => 'Phobject',
     'AlmanacBinding' => array(
       'AlmanacDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorCustomFieldInterface',
       'PhabricatorApplicationTransactionInterface',
       'AlmanacPropertyInterface',
     ),
     'AlmanacBindingEditController' => 'AlmanacServiceController',
     'AlmanacBindingEditor' => 'PhabricatorApplicationTransactionEditor',
     'AlmanacBindingPHIDType' => 'PhabricatorPHIDType',
     'AlmanacBindingQuery' => 'AlmanacQuery',
     'AlmanacBindingTableView' => 'AphrontView',
     'AlmanacBindingTransaction' => 'PhabricatorApplicationTransaction',
     'AlmanacBindingTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'AlmanacBindingViewController' => 'AlmanacServiceController',
     'AlmanacConduitAPIMethod' => 'ConduitAPIMethod',
     'AlmanacConsoleController' => 'AlmanacController',
     'AlmanacController' => 'PhabricatorController',
     'AlmanacCoreCustomField' => array(
       'AlmanacCustomField',
       'PhabricatorStandardCustomFieldInterface',
     ),
     'AlmanacCreateDevicesCapability' => 'PhabricatorPolicyCapability',
     'AlmanacCreateNetworksCapability' => 'PhabricatorPolicyCapability',
     'AlmanacCreateServicesCapability' => 'PhabricatorPolicyCapability',
     'AlmanacCustomField' => 'PhabricatorCustomField',
     'AlmanacDAO' => 'PhabricatorLiskDAO',
     'AlmanacDevice' => array(
       'AlmanacDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorCustomFieldInterface',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorProjectInterface',
       'PhabricatorSSHPublicKeyInterface',
       'AlmanacPropertyInterface',
     ),
     'AlmanacDeviceController' => 'AlmanacController',
     'AlmanacDeviceEditController' => 'AlmanacDeviceController',
     'AlmanacDeviceEditor' => 'PhabricatorApplicationTransactionEditor',
     'AlmanacDeviceListController' => 'AlmanacDeviceController',
     'AlmanacDevicePHIDType' => 'PhabricatorPHIDType',
     'AlmanacDeviceQuery' => 'AlmanacQuery',
     'AlmanacDeviceSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'AlmanacDeviceTransaction' => 'PhabricatorApplicationTransaction',
     'AlmanacDeviceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'AlmanacDeviceViewController' => 'AlmanacDeviceController',
     'AlmanacInterface' => array(
       'AlmanacDAO',
       'PhabricatorPolicyInterface',
     ),
     'AlmanacInterfaceDatasource' => 'PhabricatorTypeaheadDatasource',
     'AlmanacInterfaceEditController' => 'AlmanacDeviceController',
     'AlmanacInterfacePHIDType' => 'PhabricatorPHIDType',
     'AlmanacInterfaceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'AlmanacInterfaceTableView' => 'AphrontView',
     'AlmanacManagementTrustKeyWorkflow' => 'AlmanacManagementWorkflow',
     'AlmanacManagementUntrustKeyWorkflow' => 'AlmanacManagementWorkflow',
     'AlmanacManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'AlmanacNames' => 'Phobject',
     'AlmanacNamesTestCase' => 'PhabricatorTestCase',
     'AlmanacNetwork' => array(
       'AlmanacDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'AlmanacNetworkController' => 'AlmanacController',
     'AlmanacNetworkEditController' => 'AlmanacNetworkController',
     'AlmanacNetworkEditor' => 'PhabricatorApplicationTransactionEditor',
     'AlmanacNetworkListController' => 'AlmanacNetworkController',
     'AlmanacNetworkPHIDType' => 'PhabricatorPHIDType',
     'AlmanacNetworkQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'AlmanacNetworkSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'AlmanacNetworkTransaction' => 'PhabricatorApplicationTransaction',
     'AlmanacNetworkTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'AlmanacNetworkViewController' => 'AlmanacNetworkController',
     'AlmanacProperty' => array(
       'PhabricatorCustomFieldStorage',
       'PhabricatorPolicyInterface',
     ),
     'AlmanacPropertyController' => 'AlmanacController',
     'AlmanacPropertyEditController' => 'AlmanacDeviceController',
     'AlmanacPropertyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'AlmanacQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'AlmanacQueryServicesConduitAPIMethod' => 'AlmanacConduitAPIMethod',
     'AlmanacSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'AlmanacService' => array(
       'AlmanacDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorCustomFieldInterface',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorProjectInterface',
       'AlmanacPropertyInterface',
     ),
     'AlmanacServiceController' => 'AlmanacController',
     'AlmanacServiceEditController' => 'AlmanacServiceController',
     'AlmanacServiceEditor' => 'PhabricatorApplicationTransactionEditor',
     'AlmanacServiceListController' => 'AlmanacServiceController',
     'AlmanacServicePHIDType' => 'PhabricatorPHIDType',
     'AlmanacServiceQuery' => 'AlmanacQuery',
     'AlmanacServiceSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'AlmanacServiceTransaction' => 'PhabricatorApplicationTransaction',
     'AlmanacServiceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'AlmanacServiceViewController' => 'AlmanacServiceController',
     'Aphront304Response' => 'AphrontResponse',
     'Aphront400Response' => 'AphrontResponse',
     'Aphront403Response' => 'AphrontHTMLResponse',
     'Aphront404Response' => 'AphrontHTMLResponse',
     'AphrontAbstractAttachedFileView' => 'AphrontView',
     'AphrontAjaxResponse' => 'AphrontResponse',
     'AphrontBarView' => 'AphrontView',
     'AphrontCSRFException' => 'AphrontException',
     'AphrontCalendarEventView' => 'AphrontView',
     'AphrontContextBarView' => 'AphrontView',
     'AphrontController' => 'Phobject',
     'AphrontCursorPagerView' => 'AphrontView',
     'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
     'AphrontDialogResponse' => 'AphrontResponse',
     'AphrontDialogView' => 'AphrontView',
     'AphrontErrorView' => 'AphrontView',
     'AphrontException' => 'Exception',
     'AphrontFileResponse' => 'AphrontResponse',
     'AphrontFormCheckboxControl' => 'AphrontFormControl',
     'AphrontFormChooseButtonControl' => 'AphrontFormControl',
     'AphrontFormControl' => 'AphrontView',
     'AphrontFormCropControl' => 'AphrontFormControl',
     'AphrontFormDateControl' => 'AphrontFormControl',
     'AphrontFormDividerControl' => 'AphrontFormControl',
     'AphrontFormFileControl' => 'AphrontFormControl',
     'AphrontFormImageControl' => 'AphrontFormControl',
     'AphrontFormMarkupControl' => 'AphrontFormControl',
     'AphrontFormPasswordControl' => 'AphrontFormControl',
     'AphrontFormPolicyControl' => 'AphrontFormControl',
     'AphrontFormRadioButtonControl' => 'AphrontFormControl',
     'AphrontFormRecaptchaControl' => 'AphrontFormControl',
     'AphrontFormSectionControl' => 'AphrontFormControl',
     'AphrontFormSelectControl' => 'AphrontFormControl',
     'AphrontFormStaticControl' => 'AphrontFormControl',
     'AphrontFormSubmitControl' => 'AphrontFormControl',
     'AphrontFormTextAreaControl' => 'AphrontFormControl',
     'AphrontFormTextControl' => 'AphrontFormControl',
     'AphrontFormTextWithSubmitControl' => 'AphrontFormControl',
     'AphrontFormToggleButtonsControl' => 'AphrontFormControl',
     'AphrontFormTokenizerControl' => 'AphrontFormControl',
     'AphrontFormTypeaheadControl' => 'AphrontFormControl',
     'AphrontFormView' => 'AphrontView',
     'AphrontGlyphBarView' => 'AphrontBarView',
     'AphrontHTMLResponse' => 'AphrontResponse',
     'AphrontHTTPSinkTestCase' => 'PhabricatorTestCase',
     'AphrontIsolatedDatabaseConnectionTestCase' => 'PhabricatorTestCase',
     'AphrontIsolatedHTTPSink' => 'AphrontHTTPSink',
     'AphrontJSONResponse' => 'AphrontResponse',
     'AphrontJavelinView' => 'AphrontView',
     'AphrontKeyboardShortcutsAvailableView' => 'AphrontView',
     'AphrontListFilterView' => 'AphrontView',
     'AphrontMiniPanelView' => 'AphrontView',
     'AphrontMoreView' => 'AphrontView',
     'AphrontMultiColumnView' => 'AphrontView',
     'AphrontMySQLDatabaseConnectionTestCase' => 'PhabricatorTestCase',
     'AphrontNullView' => 'AphrontView',
     'AphrontPHPHTTPSink' => 'AphrontHTTPSink',
     'AphrontPageView' => 'AphrontView',
     'AphrontPagerView' => 'AphrontView',
     'AphrontPanelView' => 'AphrontView',
     'AphrontPlainTextResponse' => 'AphrontResponse',
     'AphrontProgressBarView' => 'AphrontBarView',
     'AphrontProxyResponse' => 'AphrontResponse',
     'AphrontRedirectResponse' => 'AphrontResponse',
     'AphrontRedirectResponseTestCase' => 'PhabricatorTestCase',
     'AphrontReloadResponse' => 'AphrontRedirectResponse',
     'AphrontRequestTestCase' => 'PhabricatorTestCase',
     'AphrontSideNavFilterView' => 'AphrontView',
     'AphrontStackTraceView' => 'AphrontView',
     'AphrontTableView' => 'AphrontView',
     'AphrontTagView' => 'AphrontView',
     'AphrontTokenizerTemplateView' => 'AphrontView',
     'AphrontTwoColumnView' => 'AphrontView',
     'AphrontTypeaheadTemplateView' => 'AphrontView',
     'AphrontUsageException' => 'AphrontException',
     'AphrontView' => array(
       'Phobject',
       'PhutilSafeHTMLProducerInterface',
     ),
     'AphrontWebpageResponse' => 'AphrontHTMLResponse',
     'ArcanistConduitAPIMethod' => 'ConduitAPIMethod',
     'ArcanistProjectInfoConduitAPIMethod' => 'ArcanistConduitAPIMethod',
     'AuditActionMenuEventListener' => 'PhabricatorEventListener',
     'AuditConduitAPIMethod' => 'ConduitAPIMethod',
     'AuditQueryConduitAPIMethod' => 'AuditConduitAPIMethod',
     'CalendarColors' => 'CalendarConstants',
     'CalendarTimeUtilTestCase' => 'PhabricatorTestCase',
     'CelerityManagementMapWorkflow' => 'CelerityManagementWorkflow',
     'CelerityManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'CelerityPhabricatorResourceController' => 'CelerityResourceController',
     'CelerityPhabricatorResources' => 'CelerityResourcesOnDisk',
     'CelerityPhysicalResources' => 'CelerityResources',
     'CelerityResourceController' => 'PhabricatorController',
     'CelerityResourceGraph' => 'AbstractDirectedGraph',
     'CelerityResourceTransformerTestCase' => 'PhabricatorTestCase',
     'CelerityResourcesOnDisk' => 'CelerityPhysicalResources',
     'ChatLogConduitAPIMethod' => 'ConduitAPIMethod',
     'ChatLogQueryConduitAPIMethod' => 'ChatLogConduitAPIMethod',
     'ChatLogRecordConduitAPIMethod' => 'ChatLogConduitAPIMethod',
     'ConduitAPIMethod' => array(
       'Phobject',
       'PhabricatorPolicyInterface',
     ),
     'ConduitApplicationNotInstalledException' => 'ConduitMethodNotFoundException',
     'ConduitCallTestCase' => 'PhabricatorTestCase',
     'ConduitConnectConduitAPIMethod' => 'ConduitAPIMethod',
     'ConduitConnectionGarbageCollector' => 'PhabricatorGarbageCollector',
     'ConduitException' => 'Exception',
     'ConduitGetCertificateConduitAPIMethod' => 'ConduitAPIMethod',
     'ConduitLogGarbageCollector' => 'PhabricatorGarbageCollector',
     'ConduitMethodDoesNotExistException' => 'ConduitMethodNotFoundException',
     'ConduitMethodNotFoundException' => 'ConduitException',
     'ConduitPingConduitAPIMethod' => 'ConduitAPIMethod',
     'ConduitQueryConduitAPIMethod' => 'ConduitAPIMethod',
     'ConduitSSHWorkflow' => 'PhabricatorSSHWorkflow',
     'ConpherenceActionMenuEventListener' => 'PhabricatorEventListener',
     'ConpherenceConduitAPIMethod' => 'ConduitAPIMethod',
     'ConpherenceConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'ConpherenceController' => 'PhabricatorController',
     'ConpherenceCreateThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
     'ConpherenceCreateThreadMailReceiver' => 'PhabricatorMailReceiver',
     'ConpherenceDAO' => 'PhabricatorLiskDAO',
     'ConpherenceEditor' => 'PhabricatorApplicationTransactionEditor',
     'ConpherenceFileWidgetView' => 'ConpherenceWidgetView',
     'ConpherenceHovercardEventListener' => 'PhabricatorEventListener',
     'ConpherenceLayoutView' => 'AphrontView',
     'ConpherenceListController' => 'ConpherenceController',
     'ConpherenceMenuItemView' => 'AphrontTagView',
     'ConpherenceNewController' => 'ConpherenceController',
     'ConpherenceNotificationPanelController' => 'ConpherenceController',
     'ConpherenceParticipant' => 'ConpherenceDAO',
     'ConpherenceParticipantCountQuery' => 'PhabricatorOffsetPagedQuery',
     'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery',
     'ConpherenceParticipationStatus' => 'ConpherenceConstants',
     'ConpherencePeopleWidgetView' => 'ConpherenceWidgetView',
     'ConpherenceQueryThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
     'ConpherenceQueryTransactionConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
     'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler',
     'ConpherenceSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'ConpherenceSettings' => 'ConpherenceConstants',
     'ConpherenceThread' => array(
       'ConpherenceDAO',
       'PhabricatorPolicyInterface',
     ),
     'ConpherenceThreadListView' => 'AphrontView',
     'ConpherenceThreadMailReceiver' => 'PhabricatorObjectMailReceiver',
     'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'ConpherenceTransaction' => 'PhabricatorApplicationTransaction',
     'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'ConpherenceTransactionType' => 'ConpherenceConstants',
     'ConpherenceTransactionView' => 'AphrontView',
     'ConpherenceUpdateActions' => 'ConpherenceConstants',
     'ConpherenceUpdateController' => 'ConpherenceController',
     'ConpherenceUpdateThreadConduitAPIMethod' => 'ConpherenceConduitAPIMethod',
     'ConpherenceViewController' => 'ConpherenceController',
     'ConpherenceWidgetController' => 'ConpherenceController',
     'ConpherenceWidgetView' => 'AphrontView',
     'DarkConsoleController' => 'PhabricatorController',
     'DarkConsoleDataController' => 'PhabricatorController',
     'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
     'DarkConsoleEventPlugin' => 'DarkConsolePlugin',
     'DarkConsoleEventPluginAPI' => 'PhabricatorEventListener',
     'DarkConsoleRequestPlugin' => 'DarkConsolePlugin',
     'DarkConsoleServicesPlugin' => 'DarkConsolePlugin',
     'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin',
     'DefaultDatabaseConfigurationProvider' => 'DatabaseConfigurationProvider',
     'DifferentialActionMenuEventListener' => 'PhabricatorEventListener',
     'DifferentialAddCommentView' => 'AphrontView',
     'DifferentialAffectedPath' => 'DifferentialDAO',
     'DifferentialApplyPatchField' => 'DifferentialCustomField',
     'DifferentialArcanistProjectField' => 'DifferentialCustomField',
     'DifferentialAsanaRepresentationField' => 'DifferentialCustomField',
     'DifferentialAuditorsField' => 'DifferentialStoredCustomField',
     'DifferentialAuthorField' => 'DifferentialCustomField',
     'DifferentialBlameRevisionField' => 'DifferentialStoredCustomField',
     'DifferentialBranchField' => 'DifferentialCustomField',
     'DifferentialChangesSinceLastUpdateField' => 'DifferentialCustomField',
     'DifferentialChangeset' => array(
       'DifferentialDAO',
       'PhabricatorPolicyInterface',
     ),
     'DifferentialChangesetDetailView' => 'AphrontView',
     'DifferentialChangesetHTMLRenderer' => 'DifferentialChangesetRenderer',
     'DifferentialChangesetListView' => 'AphrontView',
     'DifferentialChangesetOneUpRenderer' => 'DifferentialChangesetHTMLRenderer',
     'DifferentialChangesetOneUpTestRenderer' => 'DifferentialChangesetTestRenderer',
     'DifferentialChangesetParserTestCase' => 'PhabricatorTestCase',
     'DifferentialChangesetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DifferentialChangesetTestRenderer' => 'DifferentialChangesetRenderer',
     'DifferentialChangesetTwoUpRenderer' => 'DifferentialChangesetHTMLRenderer',
     'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer',
     'DifferentialChangesetViewController' => 'DifferentialController',
     'DifferentialCloseConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialCommentPreviewController' => 'DifferentialController',
     'DifferentialCommentSaveController' => 'DifferentialController',
     'DifferentialCommitMessageParserTestCase' => 'PhabricatorTestCase',
     'DifferentialCommitsField' => 'DifferentialCustomField',
     'DifferentialConduitAPIMethod' => 'ConduitAPIMethod',
     'DifferentialConflictsField' => 'DifferentialCustomField',
     'DifferentialController' => 'PhabricatorController',
     'DifferentialCoreCustomField' => 'DifferentialCustomField',
     'DifferentialCreateCommentConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialCreateDiffConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialCreateInlineConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialCreateRawDiffConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialCreateRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialCustomField' => 'PhabricatorCustomField',
     'DifferentialCustomFieldDependsOnParser' => 'PhabricatorCustomFieldMonogramParser',
     'DifferentialCustomFieldDependsOnParserTestCase' => 'PhabricatorTestCase',
     'DifferentialCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
     'DifferentialCustomFieldRevertsParser' => 'PhabricatorCustomFieldMonogramParser',
     'DifferentialCustomFieldRevertsParserTestCase' => 'PhabricatorTestCase',
     'DifferentialCustomFieldStorage' => 'PhabricatorCustomFieldStorage',
     'DifferentialCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
     'DifferentialDAO' => 'PhabricatorLiskDAO',
     'DifferentialDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'DifferentialDependenciesField' => 'DifferentialCustomField',
     'DifferentialDependsOnField' => 'DifferentialCustomField',
     'DifferentialDiff' => array(
       'DifferentialDAO',
       'PhabricatorPolicyInterface',
       'HarbormasterBuildableInterface',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorDestructibleInterface',
     ),
     'DifferentialDiffCreateController' => 'DifferentialController',
     'DifferentialDiffCreationRejectException' => 'Exception',
     'DifferentialDiffEditor' => 'PhabricatorApplicationTransactionEditor',
     'DifferentialDiffPHIDType' => 'PhabricatorPHIDType',
     'DifferentialDiffProperty' => 'DifferentialDAO',
     'DifferentialDiffQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DifferentialDiffTableOfContentsView' => 'AphrontView',
     'DifferentialDiffTestCase' => 'ArcanistPhutilTestCase',
     'DifferentialDiffTransaction' => 'PhabricatorApplicationTransaction',
     'DifferentialDiffViewController' => 'DifferentialController',
     'DifferentialDoorkeeperRevisionFeedStoryPublisher' => 'DoorkeeperFeedStoryPublisher',
     'DifferentialDraft' => 'DifferentialDAO',
     'DifferentialEditPolicyField' => 'DifferentialCoreCustomField',
     'DifferentialFieldParseException' => 'Exception',
     'DifferentialFieldValidationException' => 'Exception',
     'DifferentialFindConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialFinishPostponedLintersConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialGetAllDiffsConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialGetCommitMessageConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialGetCommitPathsConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialGetDiffConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialGetRawDiffConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialGetRevisionCommentsConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialGetRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialGitSVNIDField' => 'DifferentialCustomField',
     'DifferentialHostField' => 'DifferentialCustomField',
     'DifferentialHovercardEventListener' => 'PhabricatorEventListener',
     'DifferentialHunk' => array(
       'DifferentialDAO',
       'PhabricatorPolicyInterface',
     ),
     'DifferentialHunkLegacy' => 'DifferentialHunk',
     'DifferentialHunkModern' => 'DifferentialHunk',
     'DifferentialHunkParserTestCase' => 'PhabricatorTestCase',
     'DifferentialHunkQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DifferentialHunkTestCase' => 'ArcanistPhutilTestCase',
     'DifferentialInlineComment' => 'PhabricatorInlineCommentInterface',
     'DifferentialInlineCommentEditController' => 'PhabricatorInlineCommentController',
     'DifferentialInlineCommentEditView' => 'AphrontView',
     'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
     'DifferentialInlineCommentQuery' => 'PhabricatorOffsetPagedQuery',
     'DifferentialInlineCommentView' => 'AphrontView',
     'DifferentialJIRAIssuesField' => 'DifferentialStoredCustomField',
     'DifferentialLandingActionMenuEventListener' => 'PhabricatorEventListener',
     'DifferentialLandingToGitHub' => 'DifferentialLandingStrategy',
     'DifferentialLandingToHostedGit' => 'DifferentialLandingStrategy',
     'DifferentialLandingToHostedMercurial' => 'DifferentialLandingStrategy',
     'DifferentialLintField' => 'DifferentialCustomField',
     'DifferentialLocalCommitsView' => 'AphrontView',
     'DifferentialMail' => 'PhabricatorMail',
     'DifferentialManiphestTasksField' => 'DifferentialCoreCustomField',
     'DifferentialParseCacheGarbageCollector' => 'PhabricatorGarbageCollector',
     'DifferentialParseCommitMessageConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialParseRenderTestCase' => 'PhabricatorTestCase',
     'DifferentialPathField' => 'DifferentialCustomField',
     'DifferentialPrimaryPaneView' => 'AphrontView',
     'DifferentialProjectReviewersField' => 'DifferentialCustomField',
     'DifferentialProjectsField' => 'DifferentialCoreCustomField',
     'DifferentialQueryConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialQueryDiffsConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler',
     'DifferentialRepositoryField' => 'DifferentialCoreCustomField',
     'DifferentialRepositoryLookup' => 'Phobject',
     'DifferentialRequiredSignaturesField' => 'DifferentialCoreCustomField',
     'DifferentialResultsTableView' => 'AphrontView',
     'DifferentialRevertPlanField' => 'DifferentialStoredCustomField',
     'DifferentialReviewedByField' => 'DifferentialCoreCustomField',
     'DifferentialReviewersField' => 'DifferentialCoreCustomField',
     'DifferentialReviewersView' => 'AphrontView',
     'DifferentialRevision' => array(
       'DifferentialDAO',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorFlaggableInterface',
       'PhrequentTrackableInterface',
       'HarbormasterBuildableInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorCustomFieldInterface',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorMentionableInterface',
       'PhabricatorDestructibleInterface',
       'PhabricatorProjectInterface',
     ),
     'DifferentialRevisionCloseDetailsController' => 'DifferentialController',
     'DifferentialRevisionDetailView' => 'AphrontView',
     'DifferentialRevisionEditController' => 'DifferentialController',
     'DifferentialRevisionHasTaskEdgeType' => 'PhabricatorEdgeType',
     'DifferentialRevisionIDField' => 'DifferentialCustomField',
     'DifferentialRevisionLandController' => 'DifferentialController',
     'DifferentialRevisionListController' => 'DifferentialController',
     'DifferentialRevisionListView' => 'AphrontView',
     'DifferentialRevisionMailReceiver' => 'PhabricatorObjectMailReceiver',
     'DifferentialRevisionPHIDType' => 'PhabricatorPHIDType',
     'DifferentialRevisionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DifferentialRevisionSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
     'DifferentialRevisionViewController' => 'DifferentialController',
     'DifferentialSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'DifferentialSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'DifferentialSetDiffPropertyConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialStoredCustomField' => 'DifferentialCustomField',
     'DifferentialSubscribersField' => 'DifferentialCoreCustomField',
     'DifferentialSummaryField' => 'DifferentialCoreCustomField',
     'DifferentialTestPlanField' => 'DifferentialCoreCustomField',
     'DifferentialTitleField' => 'DifferentialCoreCustomField',
     'DifferentialTransaction' => 'PhabricatorApplicationTransaction',
     'DifferentialTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'DifferentialTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'DifferentialTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'DifferentialTransactionView' => 'PhabricatorApplicationTransactionView',
     'DifferentialUnitField' => 'DifferentialCustomField',
     'DifferentialUpdateRevisionConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialUpdateUnitResultsConduitAPIMethod' => 'DifferentialConduitAPIMethod',
     'DifferentialViewPolicyField' => 'DifferentialCoreCustomField',
     'DiffusionArcanistProjectDatasource' => 'PhabricatorTypeaheadDatasource',
     'DiffusionAuditorDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'DiffusionBranchQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionBranchTableController' => 'DiffusionController',
     'DiffusionBranchTableView' => 'DiffusionView',
     'DiffusionBrowseController' => 'DiffusionController',
     'DiffusionBrowseDirectoryController' => 'DiffusionBrowseController',
     'DiffusionBrowseFileController' => 'DiffusionBrowseController',
     'DiffusionBrowseMainController' => 'DiffusionBrowseController',
     'DiffusionBrowseQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionBrowseSearchController' => 'DiffusionBrowseController',
     'DiffusionBrowseTableView' => 'DiffusionView',
     'DiffusionChangeController' => 'DiffusionController',
     'DiffusionCommitBranchesController' => 'DiffusionController',
     'DiffusionCommitChangeTableView' => 'DiffusionView',
     'DiffusionCommitController' => 'DiffusionController',
     'DiffusionCommitEditController' => 'DiffusionController',
     'DiffusionCommitHasTaskEdgeType' => 'PhabricatorEdgeType',
     'DiffusionCommitHash' => 'Phobject',
     'DiffusionCommitHookEngine' => 'Phobject',
     'DiffusionCommitHookRejectException' => 'Exception',
     'DiffusionCommitParentsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionCommitQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DiffusionCommitRef' => 'Phobject',
     'DiffusionCommitRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'DiffusionCommitRemarkupRuleTestCase' => 'PhabricatorTestCase',
     'DiffusionCommitTagsController' => 'DiffusionController',
     'DiffusionConduitAPIMethod' => 'ConduitAPIMethod',
     'DiffusionController' => 'PhabricatorController',
     'DiffusionCreateCommentConduitAPIMethod' => 'DiffusionConduitAPIMethod',
     'DiffusionCreateRepositoriesCapability' => 'PhabricatorPolicyCapability',
     'DiffusionDefaultEditCapability' => 'PhabricatorPolicyCapability',
     'DiffusionDefaultPushCapability' => 'PhabricatorPolicyCapability',
     'DiffusionDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'DiffusionDiffController' => 'DiffusionController',
     'DiffusionDiffQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionDoorkeeperCommitFeedStoryPublisher' => 'DoorkeeperFeedStoryPublisher',
     'DiffusionEmptyResultView' => 'DiffusionView',
     'DiffusionExistsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionExternalController' => 'DiffusionController',
     'DiffusionFileContentQuery' => 'DiffusionQuery',
     'DiffusionFileContentQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionFindSymbolsConduitAPIMethod' => 'DiffusionConduitAPIMethod',
     'DiffusionGetCommitsConduitAPIMethod' => 'DiffusionConduitAPIMethod',
     'DiffusionGetLintMessagesConduitAPIMethod' => 'DiffusionConduitAPIMethod',
     'DiffusionGetRecentCommitsByPathConduitAPIMethod' => 'DiffusionConduitAPIMethod',
     'DiffusionGitBranchTestCase' => 'PhabricatorTestCase',
     'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
     'DiffusionGitFileContentQueryTestCase' => 'PhabricatorTestCase',
     'DiffusionGitRawDiffQuery' => 'DiffusionRawDiffQuery',
     'DiffusionGitRequest' => 'DiffusionRequest',
     'DiffusionGitResponse' => 'AphrontResponse',
     'DiffusionHistoryController' => 'DiffusionController',
     'DiffusionHistoryQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionHistoryTableView' => 'DiffusionView',
     'DiffusionHovercardEventListener' => 'PhabricatorEventListener',
     'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
     'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
     'DiffusionLastModifiedController' => 'DiffusionController',
     'DiffusionLastModifiedQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionLintController' => 'DiffusionController',
     'DiffusionLintCountQuery' => 'PhabricatorQuery',
     'DiffusionLintDetailsController' => 'DiffusionController',
     'DiffusionLookSoonConduitAPIMethod' => 'DiffusionConduitAPIMethod',
     'DiffusionLowLevelCommitFieldsQuery' => 'DiffusionLowLevelQuery',
     'DiffusionLowLevelCommitQuery' => 'DiffusionLowLevelQuery',
     'DiffusionLowLevelGitRefQuery' => 'DiffusionLowLevelQuery',
     'DiffusionLowLevelMercurialBranchesQuery' => 'DiffusionLowLevelQuery',
     'DiffusionLowLevelMercurialPathsQuery' => 'DiffusionLowLevelQuery',
     'DiffusionLowLevelParentsQuery' => 'DiffusionLowLevelQuery',
     'DiffusionLowLevelQuery' => 'Phobject',
     'DiffusionLowLevelResolveRefsQuery' => 'DiffusionLowLevelQuery',
     'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery',
     'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery',
     'DiffusionMercurialRequest' => 'DiffusionRequest',
     'DiffusionMercurialResponse' => 'AphrontResponse',
     'DiffusionMergedCommitsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionMirrorDeleteController' => 'DiffusionController',
     'DiffusionMirrorEditController' => 'DiffusionController',
     'DiffusionPathCompleteController' => 'DiffusionController',
     'DiffusionPathQueryTestCase' => 'PhabricatorTestCase',
     'DiffusionPathTreeController' => 'DiffusionController',
     'DiffusionPathValidateController' => 'DiffusionController',
     'DiffusionPushCapability' => 'PhabricatorPolicyCapability',
     'DiffusionPushEventViewController' => 'DiffusionPushLogController',
     'DiffusionPushLogController' => 'DiffusionController',
     'DiffusionPushLogListController' => 'DiffusionPushLogController',
     'DiffusionPushLogListView' => 'AphrontView',
     'DiffusionQuery' => 'PhabricatorQuery',
     'DiffusionQueryCommitsConduitAPIMethod' => 'DiffusionConduitAPIMethod',
     'DiffusionQueryConduitAPIMethod' => 'DiffusionConduitAPIMethod',
     'DiffusionQueryPathsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionRawDiffQuery' => 'DiffusionQuery',
     'DiffusionRawDiffQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionReadmeQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionRefNotFoundException' => 'Exception',
     'DiffusionRefsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionRepositoryController' => 'DiffusionController',
     'DiffusionRepositoryCreateController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryDatasource' => 'PhabricatorTypeaheadDatasource',
     'DiffusionRepositoryDefaultController' => 'DiffusionController',
     'DiffusionRepositoryEditActionsController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditActivateController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditBasicController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditBranchesController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditController' => 'DiffusionController',
     'DiffusionRepositoryEditDangerousController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditDeleteController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditEncodingController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditHostingController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditLocalController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditMainController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditSubversionController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryEditUpdateController' => 'DiffusionRepositoryEditController',
     'DiffusionRepositoryListController' => 'DiffusionController',
     'DiffusionRepositoryNewController' => 'DiffusionController',
     'DiffusionRepositoryRef' => 'Phobject',
     'DiffusionRepositoryRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'DiffusionResolveRefsConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionResolveUserQuery' => 'Phobject',
     'DiffusionSSHGitReceivePackWorkflow' => 'DiffusionSSHGitWorkflow',
     'DiffusionSSHGitUploadPackWorkflow' => 'DiffusionSSHGitWorkflow',
     'DiffusionSSHGitWorkflow' => 'DiffusionSSHWorkflow',
     'DiffusionSSHMercurialServeWorkflow' => 'DiffusionSSHMercurialWorkflow',
     'DiffusionSSHMercurialWireClientProtocolChannel' => 'PhutilProtocolChannel',
     'DiffusionSSHMercurialWireTestCase' => 'PhabricatorTestCase',
     'DiffusionSSHMercurialWorkflow' => 'DiffusionSSHWorkflow',
     'DiffusionSSHSubversionServeWorkflow' => 'DiffusionSSHSubversionWorkflow',
     'DiffusionSSHSubversionWorkflow' => 'DiffusionSSHWorkflow',
     'DiffusionSSHWorkflow' => 'PhabricatorSSHWorkflow',
     'DiffusionSearchQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionServeController' => 'DiffusionController',
     'DiffusionSetPasswordPanel' => 'PhabricatorSettingsPanel',
     'DiffusionSetupException' => 'AphrontUsageException',
     'DiffusionSubversionWireProtocol' => 'Phobject',
     'DiffusionSubversionWireProtocolTestCase' => 'PhabricatorTestCase',
     'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
     'DiffusionSvnRawDiffQuery' => 'DiffusionRawDiffQuery',
     'DiffusionSvnRequest' => 'DiffusionRequest',
     'DiffusionSymbolController' => 'DiffusionController',
     'DiffusionSymbolDatasource' => 'PhabricatorTypeaheadDatasource',
     'DiffusionSymbolQuery' => 'PhabricatorOffsetPagedQuery',
     'DiffusionTagListController' => 'DiffusionController',
     'DiffusionTagListView' => 'DiffusionView',
     'DiffusionTagsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
     'DiffusionURITestCase' => 'ArcanistPhutilTestCase',
     'DiffusionUpdateCoverageConduitAPIMethod' => 'DiffusionConduitAPIMethod',
     'DiffusionView' => 'AphrontView',
     'DivinerArticleAtomizer' => 'DivinerAtomizer',
     'DivinerAtomCache' => 'DivinerDiskCache',
     'DivinerAtomController' => 'DivinerController',
     'DivinerAtomListController' => 'DivinerController',
     'DivinerAtomPHIDType' => 'PhabricatorPHIDType',
     'DivinerAtomQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DivinerAtomSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'DivinerAtomizeWorkflow' => 'DivinerWorkflow',
     'DivinerBookController' => 'DivinerController',
     'DivinerBookItemView' => 'AphrontTagView',
     'DivinerBookPHIDType' => 'PhabricatorPHIDType',
     'DivinerBookQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DivinerController' => 'PhabricatorController',
     'DivinerDAO' => 'PhabricatorLiskDAO',
     'DivinerDefaultRenderer' => 'DivinerRenderer',
     'DivinerFileAtomizer' => 'DivinerAtomizer',
     'DivinerFindController' => 'DivinerController',
     'DivinerGenerateWorkflow' => 'DivinerWorkflow',
     'DivinerLiveAtom' => 'DivinerDAO',
     'DivinerLiveBook' => array(
       'DivinerDAO',
       'PhabricatorPolicyInterface',
     ),
     'DivinerLivePublisher' => 'DivinerPublisher',
     'DivinerLiveSymbol' => array(
       'DivinerDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorMarkupInterface',
     ),
     'DivinerMainController' => 'DivinerController',
     'DivinerPHPAtomizer' => 'DivinerAtomizer',
     'DivinerParameterTableView' => 'AphrontTagView',
     'DivinerPublishCache' => 'DivinerDiskCache',
     'DivinerReturnTableView' => 'AphrontTagView',
     'DivinerSectionView' => 'AphrontTagView',
     'DivinerStaticPublisher' => 'DivinerPublisher',
     'DivinerSymbolRemarkupRule' => 'PhutilRemarkupRule',
     'DivinerWorkflow' => 'PhabricatorManagementWorkflow',
     'DoorkeeperBridge' => 'Phobject',
     'DoorkeeperBridgeAsana' => 'DoorkeeperBridge',
     'DoorkeeperBridgeJIRA' => 'DoorkeeperBridge',
     'DoorkeeperBridgeJIRATestCase' => 'PhabricatorTestCase',
     'DoorkeeperDAO' => 'PhabricatorLiskDAO',
     'DoorkeeperExternalObject' => array(
       'DoorkeeperDAO',
       'PhabricatorPolicyInterface',
     ),
     'DoorkeeperExternalObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DoorkeeperFeedWorker' => 'FeedPushWorker',
     'DoorkeeperFeedWorkerAsana' => 'DoorkeeperFeedWorker',
     'DoorkeeperFeedWorkerJIRA' => 'DoorkeeperFeedWorker',
     'DoorkeeperImportEngine' => 'Phobject',
     'DoorkeeperMissingLinkException' => 'Exception',
     'DoorkeeperObjectRef' => 'Phobject',
     'DoorkeeperRemarkupRule' => 'PhutilRemarkupRule',
     'DoorkeeperRemarkupRuleAsana' => 'DoorkeeperRemarkupRule',
     'DoorkeeperRemarkupRuleJIRA' => 'DoorkeeperRemarkupRule',
     'DoorkeeperSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'DoorkeeperTagView' => 'AphrontView',
     'DoorkeeperTagsController' => 'PhabricatorController',
     'DrydockAllocatorWorker' => 'PhabricatorWorker',
     'DrydockApacheWebrootInterface' => 'DrydockWebrootInterface',
     'DrydockBlueprint' => array(
       'DrydockDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorCustomFieldInterface',
     ),
     'DrydockBlueprintController' => 'DrydockController',
     'DrydockBlueprintCoreCustomField' => array(
       'DrydockBlueprintCustomField',
       'PhabricatorStandardCustomFieldInterface',
     ),
     'DrydockBlueprintCreateController' => 'DrydockBlueprintController',
     'DrydockBlueprintCustomField' => 'PhabricatorCustomField',
     'DrydockBlueprintEditController' => 'DrydockBlueprintController',
     'DrydockBlueprintEditor' => 'PhabricatorApplicationTransactionEditor',
     'DrydockBlueprintListController' => 'DrydockBlueprintController',
     'DrydockBlueprintPHIDType' => 'PhabricatorPHIDType',
     'DrydockBlueprintQuery' => 'DrydockQuery',
     'DrydockBlueprintSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'DrydockBlueprintTransaction' => 'PhabricatorApplicationTransaction',
     'DrydockBlueprintTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'DrydockBlueprintViewController' => 'DrydockBlueprintController',
     'DrydockCommandInterface' => 'DrydockInterface',
     'DrydockConsoleController' => 'DrydockController',
     'DrydockController' => 'PhabricatorController',
     'DrydockCreateBlueprintsCapability' => 'PhabricatorPolicyCapability',
     'DrydockDAO' => 'PhabricatorLiskDAO',
     'DrydockDefaultEditCapability' => 'PhabricatorPolicyCapability',
     'DrydockDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'DrydockFilesystemInterface' => 'DrydockInterface',
     'DrydockLease' => array(
       'DrydockDAO',
       'PhabricatorPolicyInterface',
     ),
     'DrydockLeaseController' => 'DrydockController',
     'DrydockLeaseListController' => 'DrydockLeaseController',
     'DrydockLeaseListView' => 'AphrontView',
     'DrydockLeasePHIDType' => 'PhabricatorPHIDType',
     'DrydockLeaseQuery' => 'DrydockQuery',
     'DrydockLeaseReleaseController' => 'DrydockLeaseController',
     'DrydockLeaseSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'DrydockLeaseStatus' => 'DrydockConstants',
     'DrydockLeaseViewController' => 'DrydockLeaseController',
     'DrydockLocalCommandInterface' => 'DrydockCommandInterface',
     'DrydockLog' => array(
       'DrydockDAO',
       'PhabricatorPolicyInterface',
     ),
     'DrydockLogController' => 'DrydockController',
     'DrydockLogListController' => 'DrydockLogController',
     'DrydockLogListView' => 'AphrontView',
     'DrydockLogQuery' => 'DrydockQuery',
     'DrydockLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'DrydockManagementCloseWorkflow' => 'DrydockManagementWorkflow',
     'DrydockManagementCreateResourceWorkflow' => 'DrydockManagementWorkflow',
     'DrydockManagementLeaseWorkflow' => 'DrydockManagementWorkflow',
     'DrydockManagementReleaseWorkflow' => 'DrydockManagementWorkflow',
     'DrydockManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'DrydockPreallocatedHostBlueprintImplementation' => 'DrydockBlueprintImplementation',
     'DrydockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DrydockResource' => array(
       'DrydockDAO',
       'PhabricatorPolicyInterface',
     ),
     'DrydockResourceCloseController' => 'DrydockResourceController',
     'DrydockResourceController' => 'DrydockController',
     'DrydockResourceListController' => 'DrydockResourceController',
     'DrydockResourceListView' => 'AphrontView',
     'DrydockResourcePHIDType' => 'PhabricatorPHIDType',
     'DrydockResourceQuery' => 'DrydockQuery',
     'DrydockResourceSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'DrydockResourceStatus' => 'DrydockConstants',
     'DrydockResourceViewController' => 'DrydockResourceController',
     'DrydockSFTPFilesystemInterface' => 'DrydockFilesystemInterface',
     'DrydockSSHCommandInterface' => 'DrydockCommandInterface',
     'DrydockWebrootInterface' => 'DrydockInterface',
     'DrydockWorkingCopyBlueprintImplementation' => 'DrydockBlueprintImplementation',
     'FeedConduitAPIMethod' => 'ConduitAPIMethod',
     'FeedPublishConduitAPIMethod' => 'FeedConduitAPIMethod',
     'FeedPublisherHTTPWorker' => 'FeedPushWorker',
     'FeedPublisherWorker' => 'FeedPushWorker',
     'FeedPushWorker' => 'PhabricatorWorker',
     'FeedQueryConduitAPIMethod' => 'FeedConduitAPIMethod',
     'FileConduitAPIMethod' => 'ConduitAPIMethod',
     'FileCreateMailReceiver' => 'PhabricatorMailReceiver',
     'FileDownloadConduitAPIMethod' => 'FileConduitAPIMethod',
     'FileInfoConduitAPIMethod' => 'FileConduitAPIMethod',
     'FileMailReceiver' => 'PhabricatorObjectMailReceiver',
     'FileReplyHandler' => 'PhabricatorMailReplyHandler',
     'FileUploadConduitAPIMethod' => 'FileConduitAPIMethod',
     'FileUploadHashConduitAPIMethod' => 'FileConduitAPIMethod',
     'FilesDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'FlagConduitAPIMethod' => 'ConduitAPIMethod',
     'FlagDeleteConduitAPIMethod' => 'FlagConduitAPIMethod',
     'FlagEditConduitAPIMethod' => 'FlagConduitAPIMethod',
     'FlagQueryConduitAPIMethod' => 'FlagConduitAPIMethod',
     'FundBacker' => array(
       'FundDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorApplicationTransactionInterface',
     ),
     'FundBackerCart' => 'PhortuneCartImplementation',
     'FundBackerEditor' => 'PhabricatorApplicationTransactionEditor',
     'FundBackerListController' => 'FundController',
     'FundBackerPHIDType' => 'PhabricatorPHIDType',
     'FundBackerProduct' => 'PhortuneProductImplementation',
     'FundBackerQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'FundBackerSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'FundBackerTransaction' => 'PhabricatorApplicationTransaction',
     'FundBackerTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'FundController' => 'PhabricatorController',
     'FundCreateInitiativesCapability' => 'PhabricatorPolicyCapability',
     'FundDAO' => 'PhabricatorLiskDAO',
     'FundDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'FundInitiative' => array(
       'FundDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorProjectInterface',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorMentionableInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorDestructibleInterface',
     ),
     'FundInitiativeBackController' => 'FundController',
     'FundInitiativeCloseController' => 'FundController',
     'FundInitiativeEditController' => 'FundController',
     'FundInitiativeEditor' => 'PhabricatorApplicationTransactionEditor',
     'FundInitiativeIndexer' => 'PhabricatorSearchDocumentIndexer',
     'FundInitiativeListController' => 'FundController',
     'FundInitiativePHIDType' => 'PhabricatorPHIDType',
     'FundInitiativeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'FundInitiativeRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'FundInitiativeReplyHandler' => 'PhabricatorMailReplyHandler',
     'FundInitiativeSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'FundInitiativeTransaction' => 'PhabricatorApplicationTransaction',
     'FundInitiativeTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'FundInitiativeViewController' => 'FundController',
     'FundSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'HarbormasterBuild' => array(
       'HarbormasterDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'HarbormasterBuildAbortedException' => 'Exception',
     'HarbormasterBuildActionController' => 'HarbormasterController',
     'HarbormasterBuildArtifact' => array(
       'HarbormasterDAO',
       'PhabricatorPolicyInterface',
     ),
     'HarbormasterBuildArtifactQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HarbormasterBuildCommand' => 'HarbormasterDAO',
     'HarbormasterBuildDependencyDatasource' => 'PhabricatorTypeaheadDatasource',
     'HarbormasterBuildEngine' => 'Phobject',
     'HarbormasterBuildFailureException' => 'Exception',
     'HarbormasterBuildGraph' => 'AbstractDirectedGraph',
     'HarbormasterBuildItem' => 'HarbormasterDAO',
     'HarbormasterBuildItemPHIDType' => 'PhabricatorPHIDType',
     'HarbormasterBuildItemQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HarbormasterBuildLog' => array(
       'HarbormasterDAO',
       'PhabricatorPolicyInterface',
     ),
     'HarbormasterBuildLogPHIDType' => 'PhabricatorPHIDType',
     'HarbormasterBuildLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HarbormasterBuildMessage' => array(
       'HarbormasterDAO',
       'PhabricatorPolicyInterface',
     ),
     'HarbormasterBuildMessageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HarbormasterBuildPHIDType' => 'PhabricatorPHIDType',
     'HarbormasterBuildPlan' => array(
       'HarbormasterDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorSubscribableInterface',
     ),
     'HarbormasterBuildPlanDatasource' => 'PhabricatorTypeaheadDatasource',
     'HarbormasterBuildPlanEditor' => 'PhabricatorApplicationTransactionEditor',
     'HarbormasterBuildPlanPHIDType' => 'PhabricatorPHIDType',
     'HarbormasterBuildPlanQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HarbormasterBuildPlanSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'HarbormasterBuildPlanTransaction' => 'PhabricatorApplicationTransaction',
     'HarbormasterBuildPlanTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'HarbormasterBuildQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HarbormasterBuildStep' => array(
       'HarbormasterDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorCustomFieldInterface',
     ),
     'HarbormasterBuildStepCoreCustomField' => array(
       'HarbormasterBuildStepCustomField',
       'PhabricatorStandardCustomFieldInterface',
     ),
     'HarbormasterBuildStepCustomField' => 'PhabricatorCustomField',
     'HarbormasterBuildStepEditor' => 'PhabricatorApplicationTransactionEditor',
     'HarbormasterBuildStepPHIDType' => 'PhabricatorPHIDType',
     'HarbormasterBuildStepQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HarbormasterBuildStepTransaction' => 'PhabricatorApplicationTransaction',
     'HarbormasterBuildStepTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'HarbormasterBuildTarget' => array(
       'HarbormasterDAO',
       'PhabricatorPolicyInterface',
     ),
     'HarbormasterBuildTargetPHIDType' => 'PhabricatorPHIDType',
     'HarbormasterBuildTargetQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HarbormasterBuildTransaction' => 'PhabricatorApplicationTransaction',
     'HarbormasterBuildTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'HarbormasterBuildTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'HarbormasterBuildViewController' => 'HarbormasterController',
     'HarbormasterBuildWorker' => 'HarbormasterWorker',
     'HarbormasterBuildable' => array(
       'HarbormasterDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'HarbormasterBuildableInterface',
     ),
     'HarbormasterBuildableActionController' => 'HarbormasterController',
     'HarbormasterBuildableListController' => 'HarbormasterController',
     'HarbormasterBuildablePHIDType' => 'PhabricatorPHIDType',
     'HarbormasterBuildableQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HarbormasterBuildableSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'HarbormasterBuildableTransaction' => 'PhabricatorApplicationTransaction',
     'HarbormasterBuildableTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'HarbormasterBuildableTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'HarbormasterBuildableViewController' => 'HarbormasterController',
     'HarbormasterCommandBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
     'HarbormasterConduitAPIMethod' => 'ConduitAPIMethod',
     'HarbormasterController' => 'PhabricatorController',
     'HarbormasterDAO' => 'PhabricatorLiskDAO',
     'HarbormasterHTTPRequestBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
     'HarbormasterLeaseHostBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
     'HarbormasterManagePlansCapability' => 'PhabricatorPolicyCapability',
     'HarbormasterManagementBuildWorkflow' => 'HarbormasterManagementWorkflow',
     'HarbormasterManagementUpdateWorkflow' => 'HarbormasterManagementWorkflow',
     'HarbormasterManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'HarbormasterObject' => 'HarbormasterDAO',
     'HarbormasterPlanController' => 'HarbormasterController',
     'HarbormasterPlanDisableController' => 'HarbormasterPlanController',
     'HarbormasterPlanEditController' => 'HarbormasterPlanController',
     'HarbormasterPlanListController' => 'HarbormasterPlanController',
     'HarbormasterPlanRunController' => 'HarbormasterController',
     'HarbormasterPlanViewController' => 'HarbormasterPlanController',
     'HarbormasterPublishFragmentBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
     'HarbormasterQueryBuildablesConduitAPIMethod' => 'HarbormasterConduitAPIMethod',
     'HarbormasterQueryBuildsConduitAPIMethod' => 'HarbormasterConduitAPIMethod',
     'HarbormasterRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'HarbormasterSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'HarbormasterScratchTable' => 'HarbormasterDAO',
     'HarbormasterSendMessageConduitAPIMethod' => 'HarbormasterConduitAPIMethod',
     'HarbormasterSleepBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
     'HarbormasterStepAddController' => 'HarbormasterController',
     'HarbormasterStepDeleteController' => 'HarbormasterController',
     'HarbormasterStepEditController' => 'HarbormasterController',
     'HarbormasterTargetWorker' => 'HarbormasterWorker',
     'HarbormasterThrowExceptionBuildStep' => 'HarbormasterBuildStepImplementation',
     'HarbormasterUIEventListener' => 'PhabricatorEventListener',
     'HarbormasterUploadArtifactBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
     'HarbormasterWaitForPreviousBuildStepImplementation' => 'HarbormasterBuildStepImplementation',
     'HarbormasterWorker' => 'PhabricatorWorker',
     'HeraldAction' => 'HeraldDAO',
     'HeraldApplyTranscript' => 'Phobject',
     'HeraldCommitAdapter' => 'HeraldAdapter',
     'HeraldCondition' => 'HeraldDAO',
     'HeraldController' => 'PhabricatorController',
     'HeraldDAO' => 'PhabricatorLiskDAO',
     'HeraldDifferentialAdapter' => 'HeraldAdapter',
     'HeraldDifferentialDiffAdapter' => 'HeraldDifferentialAdapter',
     'HeraldDifferentialRevisionAdapter' => 'HeraldDifferentialAdapter',
     'HeraldDisableController' => 'HeraldController',
     'HeraldEditLogQuery' => 'PhabricatorOffsetPagedQuery',
     'HeraldInvalidActionException' => 'Exception',
     'HeraldInvalidConditionException' => 'Exception',
     'HeraldInvalidFieldException' => 'Exception',
     'HeraldManageGlobalRulesCapability' => 'PhabricatorPolicyCapability',
     'HeraldManiphestTaskAdapter' => 'HeraldAdapter',
     'HeraldNewController' => 'HeraldController',
     'HeraldPholioMockAdapter' => 'HeraldAdapter',
     'HeraldPreCommitAdapter' => 'HeraldAdapter',
     'HeraldPreCommitContentAdapter' => 'HeraldPreCommitAdapter',
     'HeraldPreCommitRefAdapter' => 'HeraldPreCommitAdapter',
     'HeraldRecursiveConditionsException' => 'Exception',
     'HeraldRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'HeraldRule' => array(
       'HeraldDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'HeraldRuleController' => 'HeraldController',
     'HeraldRuleEdit' => 'HeraldDAO',
     'HeraldRuleEditHistoryController' => 'HeraldController',
     'HeraldRuleEditHistoryView' => 'AphrontView',
     'HeraldRuleEditor' => 'PhabricatorApplicationTransactionEditor',
     'HeraldRuleListController' => 'HeraldController',
     'HeraldRulePHIDType' => 'PhabricatorPHIDType',
     'HeraldRuleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HeraldRuleSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'HeraldRuleTestCase' => 'PhabricatorTestCase',
     'HeraldRuleTransaction' => 'PhabricatorApplicationTransaction',
     'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'HeraldRuleViewController' => 'HeraldController',
     'HeraldSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'HeraldTestConsoleController' => 'HeraldController',
     'HeraldTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'HeraldTranscript' => array(
       'HeraldDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'HeraldTranscriptController' => 'HeraldController',
     'HeraldTranscriptGarbageCollector' => 'PhabricatorGarbageCollector',
     'HeraldTranscriptListController' => 'HeraldController',
     'HeraldTranscriptQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'HeraldTranscriptSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'HeraldTranscriptTestCase' => 'PhabricatorTestCase',
     'JavelinReactorExample' => 'PhabricatorUIExample',
     'JavelinUIExample' => 'PhabricatorUIExample',
     'JavelinViewExample' => 'PhabricatorUIExample',
     'JavelinViewExampleServerView' => 'AphrontView',
     'LegalpadController' => 'PhabricatorController',
     'LegalpadCreateDocumentsCapability' => 'PhabricatorPolicyCapability',
     'LegalpadDAO' => 'PhabricatorLiskDAO',
     'LegalpadDefaultEditCapability' => 'PhabricatorPolicyCapability',
     'LegalpadDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'LegalpadDocument' => array(
       'LegalpadDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorDestructibleInterface',
     ),
     'LegalpadDocumentBody' => array(
       'LegalpadDAO',
       'PhabricatorMarkupInterface',
     ),
     'LegalpadDocumentCommentController' => 'LegalpadController',
     'LegalpadDocumentDatasource' => 'PhabricatorTypeaheadDatasource',
     'LegalpadDocumentDoneController' => 'LegalpadController',
     'LegalpadDocumentEditController' => 'LegalpadController',
     'LegalpadDocumentEditor' => 'PhabricatorApplicationTransactionEditor',
     'LegalpadDocumentListController' => 'LegalpadController',
     'LegalpadDocumentManageController' => 'LegalpadController',
     'LegalpadDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'LegalpadDocumentRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'LegalpadDocumentSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'LegalpadDocumentSignController' => 'LegalpadController',
     'LegalpadDocumentSignature' => array(
       'LegalpadDAO',
       'PhabricatorPolicyInterface',
     ),
     'LegalpadDocumentSignatureAddController' => 'LegalpadController',
     'LegalpadDocumentSignatureListController' => 'LegalpadController',
     'LegalpadDocumentSignatureQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'LegalpadDocumentSignatureSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'LegalpadDocumentSignatureVerificationController' => 'LegalpadController',
     'LegalpadDocumentSignatureViewController' => 'LegalpadController',
     'LegalpadMockMailReceiver' => 'PhabricatorObjectMailReceiver',
     'LegalpadReplyHandler' => 'PhabricatorMailReplyHandler',
     'LegalpadSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'LegalpadTransaction' => 'PhabricatorApplicationTransaction',
     'LegalpadTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'LegalpadTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'LegalpadTransactionType' => 'LegalpadConstants',
     'LegalpadTransactionView' => 'PhabricatorApplicationTransactionView',
     'LiskChunkTestCase' => 'PhabricatorTestCase',
     'LiskDAOTestCase' => 'PhabricatorTestCase',
     'LiskEphemeralObjectException' => 'Exception',
     'LiskFixtureTestCase' => 'PhabricatorTestCase',
     'LiskIsolationTestCase' => 'PhabricatorTestCase',
     'LiskIsolationTestDAO' => 'LiskDAO',
     'LiskIsolationTestDAOException' => 'Exception',
     'LiskMigrationIterator' => 'PhutilBufferedIterator',
     'LiskRawMigrationIterator' => 'PhutilBufferedIterator',
     'MacroConduitAPIMethod' => 'ConduitAPIMethod',
     'MacroCreateMemeConduitAPIMethod' => 'MacroConduitAPIMethod',
     'MacroQueryConduitAPIMethod' => 'MacroConduitAPIMethod',
     'ManiphestActionMenuEventListener' => 'PhabricatorEventListener',
     'ManiphestBatchEditController' => 'ManiphestController',
     'ManiphestBulkEditCapability' => 'PhabricatorPolicyCapability',
     'ManiphestConduitAPIMethod' => 'ConduitAPIMethod',
     'ManiphestConfiguredCustomField' => array(
       'ManiphestCustomField',
       'PhabricatorStandardCustomFieldInterface',
     ),
     'ManiphestController' => 'PhabricatorController',
     'ManiphestCreateMailReceiver' => 'PhabricatorMailReceiver',
     'ManiphestCreateTaskConduitAPIMethod' => 'ManiphestConduitAPIMethod',
     'ManiphestCustomField' => 'PhabricatorCustomField',
     'ManiphestCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
     'ManiphestCustomFieldStatusParser' => 'PhabricatorCustomFieldMonogramParser',
     'ManiphestCustomFieldStatusParserTestCase' => 'PhabricatorTestCase',
     'ManiphestCustomFieldStorage' => 'PhabricatorCustomFieldStorage',
     'ManiphestCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
     'ManiphestDAO' => 'PhabricatorLiskDAO',
     'ManiphestDefaultEditCapability' => 'PhabricatorPolicyCapability',
     'ManiphestDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'ManiphestEditAssignCapability' => 'PhabricatorPolicyCapability',
     'ManiphestEditPoliciesCapability' => 'PhabricatorPolicyCapability',
     'ManiphestEditPriorityCapability' => 'PhabricatorPolicyCapability',
     'ManiphestEditProjectsCapability' => 'PhabricatorPolicyCapability',
     'ManiphestEditStatusCapability' => 'PhabricatorPolicyCapability',
     'ManiphestExcelDefaultFormat' => 'ManiphestExcelFormat',
     'ManiphestExportController' => 'ManiphestController',
     'ManiphestFindConduitAPIMethod' => 'ManiphestQueryConduitAPIMethod',
     'ManiphestGetTaskTransactionsConduitAPIMethod' => 'ManiphestConduitAPIMethod',
     'ManiphestHovercardEventListener' => 'PhabricatorEventListener',
     'ManiphestInfoConduitAPIMethod' => 'ManiphestConduitAPIMethod',
     'ManiphestNameIndex' => 'ManiphestDAO',
     'ManiphestNameIndexEventListener' => 'PhabricatorEventListener',
     'ManiphestQueryConduitAPIMethod' => 'ManiphestConduitAPIMethod',
     'ManiphestQueryStatusesConduitAPIMethod' => 'ManiphestConduitAPIMethod',
     'ManiphestRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'ManiphestReplyHandler' => 'PhabricatorMailReplyHandler',
     'ManiphestReportController' => 'ManiphestController',
     'ManiphestSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'ManiphestSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'ManiphestStatusConfigOptionType' => 'PhabricatorConfigJSONOptionType',
     'ManiphestSubpriorityController' => 'ManiphestController',
     'ManiphestSubscribeController' => 'ManiphestController',
     'ManiphestTask' => array(
       'ManiphestDAO',
       'PhabricatorMarkupInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorMentionableInterface',
       'PhrequentTrackableInterface',
       'PhabricatorCustomFieldInterface',
       'PhabricatorDestructibleInterface',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorProjectInterface',
     ),
     'ManiphestTaskDescriptionPreviewController' => 'ManiphestController',
     'ManiphestTaskDetailController' => 'ManiphestController',
     'ManiphestTaskEditController' => 'ManiphestController',
     'ManiphestTaskHasCommitEdgeType' => 'PhabricatorEdgeType',
     'ManiphestTaskHasRevisionEdgeType' => 'PhabricatorEdgeType',
     'ManiphestTaskListController' => 'ManiphestController',
     'ManiphestTaskListView' => 'ManiphestView',
     'ManiphestTaskMailReceiver' => 'PhabricatorObjectMailReceiver',
     'ManiphestTaskOwner' => 'ManiphestConstants',
     'ManiphestTaskPHIDType' => 'PhabricatorPHIDType',
     'ManiphestTaskPriority' => 'ManiphestConstants',
     'ManiphestTaskPriorityDatasource' => 'PhabricatorTypeaheadDatasource',
     'ManiphestTaskQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'ManiphestTaskResultListView' => 'ManiphestView',
     'ManiphestTaskSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'ManiphestTaskStatus' => 'ManiphestConstants',
     'ManiphestTaskStatusDatasource' => 'PhabricatorTypeaheadDatasource',
     'ManiphestTaskStatusTestCase' => 'PhabricatorTestCase',
     'ManiphestTaskSubscriber' => 'ManiphestDAO',
     'ManiphestTransaction' => 'PhabricatorApplicationTransaction',
     'ManiphestTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'ManiphestTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'ManiphestTransactionPreviewController' => 'ManiphestController',
     'ManiphestTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'ManiphestTransactionSaveController' => 'ManiphestController',
     'ManiphestUpdateConduitAPIMethod' => 'ManiphestConduitAPIMethod',
     'ManiphestView' => 'AphrontView',
     'MetaMTAMailReceivedGarbageCollector' => 'PhabricatorGarbageCollector',
     'MetaMTAMailSentGarbageCollector' => 'PhabricatorGarbageCollector',
     'MetaMTANotificationType' => 'MetaMTAConstants',
     'MetaMTAReceivedMailStatus' => 'MetaMTAConstants',
     'NuanceConduitAPIMethod' => 'ConduitAPIMethod',
     'NuanceController' => 'PhabricatorController',
     'NuanceCreateItemConduitAPIMethod' => 'NuanceConduitAPIMethod',
     'NuanceDAO' => 'PhabricatorLiskDAO',
     'NuanceItem' => array(
       'NuanceDAO',
       'PhabricatorPolicyInterface',
     ),
     'NuanceItemEditController' => 'NuanceController',
     'NuanceItemEditor' => 'PhabricatorApplicationTransactionEditor',
     'NuanceItemPHIDType' => 'PhabricatorPHIDType',
     'NuanceItemQuery' => 'NuanceQuery',
     'NuanceItemTransaction' => 'NuanceTransaction',
     'NuanceItemTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'NuanceItemTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'NuanceItemViewController' => 'NuanceController',
     'NuancePhabricatorFormSourceDefinition' => 'NuanceSourceDefinition',
     'NuanceQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'NuanceQueue' => array(
       'NuanceDAO',
       'PhabricatorPolicyInterface',
     ),
     'NuanceQueueEditController' => 'NuanceController',
     'NuanceQueueEditor' => 'PhabricatorApplicationTransactionEditor',
     'NuanceQueueItem' => 'NuanceDAO',
     'NuanceQueuePHIDType' => 'PhabricatorPHIDType',
     'NuanceQueueQuery' => 'NuanceQuery',
     'NuanceQueueTransaction' => 'NuanceTransaction',
     'NuanceQueueTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'NuanceQueueTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'NuanceQueueViewController' => 'NuanceController',
     'NuanceRequestor' => 'NuanceDAO',
     'NuanceRequestorEditController' => 'NuanceController',
     'NuanceRequestorEditor' => 'PhabricatorApplicationTransactionEditor',
     'NuanceRequestorPHIDType' => 'PhabricatorPHIDType',
     'NuanceRequestorQuery' => 'NuanceQuery',
     'NuanceRequestorSource' => 'NuanceDAO',
     'NuanceRequestorTransaction' => 'NuanceTransaction',
     'NuanceRequestorTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'NuanceRequestorTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'NuanceRequestorViewController' => 'NuanceController',
     'NuanceSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'NuanceSource' => array(
       'NuanceDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'NuanceSourceDefaultEditCapability' => 'PhabricatorPolicyCapability',
     'NuanceSourceDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'NuanceSourceDefinition' => 'Phobject',
     'NuanceSourceEditController' => 'NuanceController',
     'NuanceSourceEditor' => 'PhabricatorApplicationTransactionEditor',
     'NuanceSourceManageCapability' => 'PhabricatorPolicyCapability',
     'NuanceSourcePHIDType' => 'PhabricatorPHIDType',
     'NuanceSourceQuery' => 'NuanceQuery',
     'NuanceSourceTransaction' => 'NuanceTransaction',
     'NuanceSourceTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'NuanceSourceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'NuanceSourceViewController' => 'NuanceController',
     'NuanceTransaction' => 'PhabricatorApplicationTransaction',
     'OwnersConduitAPIMethod' => 'ConduitAPIMethod',
     'OwnersPackageReplyHandler' => 'PhabricatorMailReplyHandler',
     'OwnersQueryConduitAPIMethod' => 'OwnersConduitAPIMethod',
     'PHIDConduitAPIMethod' => 'ConduitAPIMethod',
     'PHIDInfoConduitAPIMethod' => 'PHIDConduitAPIMethod',
     'PHIDLookupConduitAPIMethod' => 'PHIDConduitAPIMethod',
     'PHIDQueryConduitAPIMethod' => 'PHIDConduitAPIMethod',
     'PHUIActionHeaderExample' => 'PhabricatorUIExample',
     'PHUIActionHeaderView' => 'AphrontView',
     'PHUIBoxExample' => 'PhabricatorUIExample',
     'PHUIBoxView' => 'AphrontTagView',
     'PHUIButtonBarExample' => 'PhabricatorUIExample',
     'PHUIButtonBarView' => 'AphrontTagView',
     'PHUIButtonExample' => 'PhabricatorUIExample',
     'PHUIButtonView' => 'AphrontTagView',
     'PHUICalendarListView' => 'AphrontTagView',
     'PHUICalendarMonthView' => 'AphrontView',
     'PHUICalendarWidgetView' => 'AphrontTagView',
     'PHUIColorPalletteExample' => 'PhabricatorUIExample',
     'PHUIDocumentExample' => 'PhabricatorUIExample',
     'PHUIDocumentView' => 'AphrontTagView',
     'PHUIFeedStoryExample' => 'PhabricatorUIExample',
     'PHUIFeedStoryView' => 'AphrontView',
     'PHUIFormDividerControl' => 'AphrontFormControl',
     'PHUIFormFreeformDateControl' => 'AphrontFormControl',
     'PHUIFormInsetView' => 'AphrontView',
     'PHUIFormLayoutView' => 'AphrontView',
     'PHUIFormMultiSubmitControl' => 'AphrontFormControl',
     'PHUIFormPageView' => 'AphrontView',
     'PHUIHandleTagListView' => 'AphrontTagView',
     'PHUIHeaderView' => 'AphrontView',
     'PHUIIconExample' => 'PhabricatorUIExample',
     'PHUIIconView' => 'AphrontTagView',
     'PHUIImageMaskExample' => 'PhabricatorUIExample',
     'PHUIImageMaskView' => 'AphrontTagView',
     'PHUIInfoPanelExample' => 'PhabricatorUIExample',
     'PHUIInfoPanelView' => 'AphrontView',
     'PHUIListExample' => 'PhabricatorUIExample',
     'PHUIListItemView' => 'AphrontTagView',
     'PHUIListView' => 'AphrontTagView',
     'PHUIListViewTestCase' => 'PhabricatorTestCase',
     'PHUIObjectBoxView' => 'AphrontView',
     'PHUIObjectItemListExample' => 'PhabricatorUIExample',
     'PHUIObjectItemListView' => 'AphrontTagView',
     'PHUIObjectItemView' => 'AphrontTagView',
     'PHUIPagedFormView' => 'AphrontTagView',
     'PHUIPinboardItemView' => 'AphrontView',
     'PHUIPinboardView' => 'AphrontView',
     'PHUIPropertyGroupView' => 'AphrontTagView',
     'PHUIPropertyListExample' => 'PhabricatorUIExample',
     'PHUIPropertyListView' => 'AphrontView',
     'PHUIRemarkupPreviewPanel' => 'AphrontTagView',
     'PHUIStatusItemView' => 'AphrontTagView',
     'PHUIStatusListView' => 'AphrontTagView',
     'PHUITagExample' => 'PhabricatorUIExample',
     'PHUITagView' => 'AphrontTagView',
     'PHUITextExample' => 'PhabricatorUIExample',
     'PHUITextView' => 'AphrontTagView',
     'PHUITimelineEventView' => 'AphrontView',
     'PHUITimelineExample' => 'PhabricatorUIExample',
     'PHUITimelineView' => 'AphrontView',
     'PHUIWorkboardView' => 'AphrontTagView',
     'PHUIWorkpanelView' => 'AphrontTagView',
     'PackageCreateMail' => 'PackageMail',
     'PackageDeleteMail' => 'PackageMail',
     'PackageMail' => 'PhabricatorMail',
     'PackageModifyMail' => 'PackageMail',
     'PassphraseAbstractKey' => 'Phobject',
     'PassphraseConduitAPIMethod' => 'ConduitAPIMethod',
     'PassphraseController' => 'PhabricatorController',
     'PassphraseCredential' => array(
       'PassphraseDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PassphraseCredentialConduitController' => 'PassphraseController',
     'PassphraseCredentialControl' => 'AphrontFormControl',
     'PassphraseCredentialCreateController' => 'PassphraseController',
     'PassphraseCredentialDestroyController' => 'PassphraseController',
     'PassphraseCredentialEditController' => 'PassphraseController',
     'PassphraseCredentialListController' => 'PassphraseController',
     'PassphraseCredentialLockController' => 'PassphraseController',
     'PassphraseCredentialPHIDType' => 'PhabricatorPHIDType',
     'PassphraseCredentialPublicController' => 'PassphraseController',
     'PassphraseCredentialQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PassphraseCredentialRevealController' => 'PassphraseController',
     'PassphraseCredentialSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PassphraseCredentialTransaction' => 'PhabricatorApplicationTransaction',
     'PassphraseCredentialTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'PassphraseCredentialTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PassphraseCredentialType' => 'Phobject',
     'PassphraseCredentialTypePassword' => 'PassphraseCredentialType',
     'PassphraseCredentialTypeSSHGeneratedKey' => 'PassphraseCredentialTypeSSHPrivateKey',
     'PassphraseCredentialTypeSSHPrivateKey' => 'PassphraseCredentialType',
     'PassphraseCredentialTypeSSHPrivateKeyFile' => 'PassphraseCredentialTypeSSHPrivateKey',
     'PassphraseCredentialTypeSSHPrivateKeyText' => 'PassphraseCredentialTypeSSHPrivateKey',
     'PassphraseCredentialViewController' => 'PassphraseController',
     'PassphraseDAO' => 'PhabricatorLiskDAO',
     'PassphrasePasswordKey' => 'PassphraseAbstractKey',
     'PassphraseQueryConduitAPIMethod' => 'PassphraseConduitAPIMethod',
     'PassphraseRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'PassphraseSSHKey' => 'PassphraseAbstractKey',
     'PassphraseSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PassphraseSecret' => 'PassphraseDAO',
     'PasteConduitAPIMethod' => 'ConduitAPIMethod',
     'PasteCreateConduitAPIMethod' => 'PasteConduitAPIMethod',
     'PasteCreateMailReceiver' => 'PhabricatorMailReceiver',
     'PasteDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'PasteEmbedView' => 'AphrontView',
     'PasteInfoConduitAPIMethod' => 'PasteConduitAPIMethod',
     'PasteMockMailReceiver' => 'PhabricatorObjectMailReceiver',
     'PasteQueryConduitAPIMethod' => 'PasteConduitAPIMethod',
     'PasteReplyHandler' => 'PhabricatorMailReplyHandler',
     'PeopleBrowseUserDirectoryCapability' => 'PhabricatorPolicyCapability',
     'PeopleUserLogGarbageCollector' => 'PhabricatorGarbageCollector',
     'Phabricator404Controller' => 'PhabricatorController',
     'PhabricatorAWSConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorAccessControlTestCase' => 'PhabricatorTestCase',
     'PhabricatorAccessLogConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorActionListView' => 'AphrontView',
     'PhabricatorActionView' => 'AphrontView',
     'PhabricatorAllCapsTranslation' => 'PhabricatorTranslation',
     'PhabricatorAlmanacApplication' => 'PhabricatorApplication',
     'PhabricatorAmazonAuthProvider' => 'PhabricatorOAuth2AuthProvider',
     'PhabricatorAnchorView' => 'AphrontView',
     'PhabricatorAphlictManagementBuildWorkflow' => 'PhabricatorAphlictManagementWorkflow',
     'PhabricatorAphlictManagementDebugWorkflow' => 'PhabricatorAphlictManagementWorkflow',
     'PhabricatorAphlictManagementRestartWorkflow' => 'PhabricatorAphlictManagementWorkflow',
     'PhabricatorAphlictManagementStartWorkflow' => 'PhabricatorAphlictManagementWorkflow',
     'PhabricatorAphlictManagementStatusWorkflow' => 'PhabricatorAphlictManagementWorkflow',
     'PhabricatorAphlictManagementStopWorkflow' => 'PhabricatorAphlictManagementWorkflow',
     'PhabricatorAphlictManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorAphrontBarExample' => 'PhabricatorUIExample',
     'PhabricatorAphrontViewTestCase' => 'PhabricatorTestCase',
     'PhabricatorAppSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorApplication' => 'PhabricatorPolicyInterface',
     'PhabricatorApplicationApplicationPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorApplicationConfigOptions' => 'Phobject',
     'PhabricatorApplicationDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController',
     'PhabricatorApplicationEditController' => 'PhabricatorApplicationsController',
     'PhabricatorApplicationLaunchView' => 'AphrontTagView',
     'PhabricatorApplicationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorApplicationSearchController' => 'PhabricatorSearchBaseController',
     'PhabricatorApplicationStatusView' => 'AphrontView',
     'PhabricatorApplicationTransaction' => array(
       'PhabricatorLiskDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorApplicationTransactionComment' => array(
       'PhabricatorLiskDAO',
       'PhabricatorMarkupInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorApplicationTransactionCommentEditController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionCommentEditor' => 'PhabricatorEditor',
     'PhabricatorApplicationTransactionCommentHistoryController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionCommentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorApplicationTransactionCommentQuoteController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionCommentRawController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionCommentRemoveController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionCommentView' => 'AphrontView',
     'PhabricatorApplicationTransactionController' => 'PhabricatorController',
     'PhabricatorApplicationTransactionDetailController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionEditor' => 'PhabricatorEditor',
     'PhabricatorApplicationTransactionFeedStory' => 'PhabricatorFeedStory',
     'PhabricatorApplicationTransactionNoEffectException' => 'Exception',
     'PhabricatorApplicationTransactionNoEffectResponse' => 'AphrontProxyResponse',
     'PhabricatorApplicationTransactionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorApplicationTransactionResponse' => 'AphrontProxyResponse',
     'PhabricatorApplicationTransactionShowOlderController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionStructureException' => 'Exception',
     'PhabricatorApplicationTransactionTextDiffDetailView' => 'AphrontView',
     'PhabricatorApplicationTransactionTransactionPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorApplicationTransactionValidationError' => 'Phobject',
     'PhabricatorApplicationTransactionValidationException' => 'Exception',
     'PhabricatorApplicationTransactionValueController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionView' => 'AphrontView',
     'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController',
     'PhabricatorApplicationsApplication' => 'PhabricatorApplication',
     'PhabricatorApplicationsController' => 'PhabricatorController',
     'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController',
     'PhabricatorAsanaAuthProvider' => 'PhabricatorOAuth2AuthProvider',
     'PhabricatorAsanaConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
     'PhabricatorAuditApplication' => 'PhabricatorApplication',
     'PhabricatorAuditCommentEditor' => 'PhabricatorEditor',
     'PhabricatorAuditController' => 'PhabricatorController',
     'PhabricatorAuditDAO' => 'PhabricatorLiskDAO',
     'PhabricatorAuditEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorAuditInlineComment' => 'PhabricatorInlineCommentInterface',
     'PhabricatorAuditListController' => 'PhabricatorAuditController',
     'PhabricatorAuditListView' => 'AphrontView',
     'PhabricatorAuditMailReceiver' => 'PhabricatorObjectMailReceiver',
     'PhabricatorAuditManagementDeleteWorkflow' => 'PhabricatorAuditManagementWorkflow',
     'PhabricatorAuditManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorAuditPreviewController' => 'PhabricatorAuditController',
     'PhabricatorAuditReplyHandler' => 'PhabricatorMailReplyHandler',
     'PhabricatorAuditTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorAuditTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PhabricatorAuditTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorAuditTransactionView' => 'PhabricatorApplicationTransactionView',
     'PhabricatorAuthAccountView' => 'AphrontView',
     'PhabricatorAuthApplication' => 'PhabricatorApplication',
     'PhabricatorAuthAuthFactorPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorAuthAuthProviderPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorAuthConfirmLinkController' => 'PhabricatorAuthController',
     'PhabricatorAuthController' => 'PhabricatorController',
     'PhabricatorAuthDAO' => 'PhabricatorLiskDAO',
     'PhabricatorAuthDisableController' => 'PhabricatorAuthProviderConfigController',
     'PhabricatorAuthDowngradeSessionController' => 'PhabricatorAuthController',
     'PhabricatorAuthEditController' => 'PhabricatorAuthProviderConfigController',
     'PhabricatorAuthFactor' => 'Phobject',
     'PhabricatorAuthFactorConfig' => 'PhabricatorAuthDAO',
     'PhabricatorAuthFactorTOTP' => 'PhabricatorAuthFactor',
     'PhabricatorAuthFactorTOTPTestCase' => 'PhabricatorTestCase',
     'PhabricatorAuthFinishController' => 'PhabricatorAuthController',
     'PhabricatorAuthHighSecurityRequiredException' => 'Exception',
     'PhabricatorAuthLinkController' => 'PhabricatorAuthController',
     'PhabricatorAuthListController' => 'PhabricatorAuthProviderConfigController',
     'PhabricatorAuthLoginController' => 'PhabricatorAuthController',
     'PhabricatorAuthManagementLDAPWorkflow' => 'PhabricatorAuthManagementWorkflow',
     'PhabricatorAuthManagementListFactorsWorkflow' => 'PhabricatorAuthManagementWorkflow',
     'PhabricatorAuthManagementRecoverWorkflow' => 'PhabricatorAuthManagementWorkflow',
     'PhabricatorAuthManagementRefreshWorkflow' => 'PhabricatorAuthManagementWorkflow',
     'PhabricatorAuthManagementStripWorkflow' => 'PhabricatorAuthManagementWorkflow',
     'PhabricatorAuthManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorAuthNeedsApprovalController' => 'PhabricatorAuthController',
     'PhabricatorAuthNeedsMultiFactorController' => 'PhabricatorAuthController',
     'PhabricatorAuthNewController' => 'PhabricatorAuthProviderConfigController',
     'PhabricatorAuthOldOAuthRedirectController' => 'PhabricatorAuthController',
     'PhabricatorAuthOneTimeLoginController' => 'PhabricatorAuthController',
     'PhabricatorAuthProviderConfig' => array(
       'PhabricatorAuthDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorAuthProviderConfigController' => 'PhabricatorAuthController',
     'PhabricatorAuthProviderConfigEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorAuthProviderConfigQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorAuthProviderConfigTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorAuthProviderConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorAuthRegisterController' => 'PhabricatorAuthController',
     'PhabricatorAuthRevokeTokenController' => 'PhabricatorAuthController',
     'PhabricatorAuthSSHKey' => array(
       'PhabricatorAuthDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorAuthSSHKeyController' => 'PhabricatorAuthController',
     'PhabricatorAuthSSHKeyDeleteController' => 'PhabricatorAuthSSHKeyController',
     'PhabricatorAuthSSHKeyEditController' => 'PhabricatorAuthSSHKeyController',
     'PhabricatorAuthSSHKeyGenerateController' => 'PhabricatorAuthSSHKeyController',
     'PhabricatorAuthSSHKeyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorAuthSSHKeyTableView' => 'AphrontView',
     'PhabricatorAuthSSHPublicKey' => 'Phobject',
     'PhabricatorAuthSession' => array(
       'PhabricatorAuthDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorAuthSessionEngine' => 'Phobject',
     'PhabricatorAuthSessionGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorAuthSessionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorAuthStartController' => 'PhabricatorAuthController',
     'PhabricatorAuthTemporaryToken' => array(
       'PhabricatorAuthDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorAuthTemporaryTokenGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorAuthTemporaryTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorAuthTerminateSessionController' => 'PhabricatorAuthController',
     'PhabricatorAuthTryFactorAction' => 'PhabricatorSystemAction',
     'PhabricatorAuthUnlinkController' => 'PhabricatorAuthController',
     'PhabricatorAuthValidateController' => 'PhabricatorAuthController',
     'PhabricatorAuthenticationConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorAutoEventListener' => 'PhabricatorEventListener',
     'PhabricatorBarePageExample' => 'PhabricatorUIExample',
     'PhabricatorBarePageView' => 'AphrontPageView',
     'PhabricatorBaseEnglishTranslation' => 'PhabricatorTranslation',
     'PhabricatorBcryptPasswordHasher' => 'PhabricatorPasswordHasher',
     'PhabricatorBitbucketAuthProvider' => 'PhabricatorOAuth1AuthProvider',
     'PhabricatorBot' => 'PhabricatorDaemon',
     'PhabricatorBotBaseStreamingProtocolAdapter' => 'PhabricatorBaseProtocolAdapter',
     'PhabricatorBotChannel' => 'PhabricatorBotTarget',
     'PhabricatorBotDebugLogHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotFeedNotificationHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotFlowdockProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter',
     'PhabricatorBotLogHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotMacroHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotObjectNameHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotSymbolHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotUser' => 'PhabricatorBotTarget',
     'PhabricatorBotWhatsNewHandler' => 'PhabricatorBotHandler',
     'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList',
     'PhabricatorBusyExample' => 'PhabricatorUIExample',
     'PhabricatorCacheDAO' => 'PhabricatorLiskDAO',
     'PhabricatorCacheGeneralGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorCacheManagementPurgeWorkflow' => 'PhabricatorCacheManagementWorkflow',
     'PhabricatorCacheManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorCacheMarkupGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorCacheSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorCacheTTLGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorCalendarApplication' => 'PhabricatorApplication',
     'PhabricatorCalendarBrowseController' => 'PhabricatorCalendarController',
     'PhabricatorCalendarController' => 'PhabricatorController',
     'PhabricatorCalendarDAO' => 'PhabricatorLiskDAO',
     'PhabricatorCalendarEvent' => array(
       'PhabricatorCalendarDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorCalendarEventDeleteController' => 'PhabricatorCalendarController',
     'PhabricatorCalendarEventEditController' => 'PhabricatorCalendarController',
     'PhabricatorCalendarEventInvalidEpochException' => 'Exception',
     'PhabricatorCalendarEventListController' => 'PhabricatorCalendarController',
     'PhabricatorCalendarEventPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorCalendarEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorCalendarEventSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorCalendarEventViewController' => 'PhabricatorCalendarController',
     'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
     'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
     'PhabricatorCalendarViewController' => 'PhabricatorCalendarController',
     'PhabricatorCampfireProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter',
     'PhabricatorCelerityApplication' => 'PhabricatorApplication',
     'PhabricatorCelerityTestCase' => 'PhabricatorTestCase',
     'PhabricatorChangeParserTestCase' => 'PhabricatorWorkingCopyTestCase',
     'PhabricatorChangesetResponse' => 'AphrontProxyResponse',
     'PhabricatorChatLogApplication' => 'PhabricatorApplication',
     'PhabricatorChatLogChannel' => array(
       'PhabricatorChatLogDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorChatLogChannelListController' => 'PhabricatorChatLogController',
     'PhabricatorChatLogChannelLogController' => 'PhabricatorChatLogController',
     'PhabricatorChatLogChannelQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorChatLogController' => 'PhabricatorController',
     'PhabricatorChatLogDAO' => 'PhabricatorLiskDAO',
     'PhabricatorChatLogEvent' => array(
       'PhabricatorChatLogDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorChatLogEventType' => 'PhabricatorChatLogConstants',
     'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorCommitBranchesField' => 'PhabricatorCommitCustomField',
     'PhabricatorCommitCustomField' => 'PhabricatorCustomField',
     'PhabricatorCommitSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorCommitTagsField' => 'PhabricatorCommitCustomField',
     'PhabricatorCommonPasswords' => 'Phobject',
     'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
     'PhabricatorConduitApplication' => 'PhabricatorApplication',
     'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO',
     'PhabricatorConduitConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
     'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
     'PhabricatorConduitController' => 'PhabricatorController',
     'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
     'PhabricatorConduitListController' => 'PhabricatorConduitController',
     'PhabricatorConduitLogController' => 'PhabricatorConduitController',
     'PhabricatorConduitLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorConduitMethodCallLog' => array(
       'PhabricatorConduitDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorConduitMethodQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorConduitSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
     'PhabricatorConfigAllController' => 'PhabricatorConfigController',
     'PhabricatorConfigApplication' => 'PhabricatorApplication',
     'PhabricatorConfigColumnSchema' => 'PhabricatorConfigStorageSchema',
     'PhabricatorConfigConfigPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorConfigController' => 'PhabricatorController',
     'PhabricatorConfigCoreSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorConfigDatabaseController' => 'PhabricatorConfigController',
     'PhabricatorConfigDatabaseIssueController' => 'PhabricatorConfigDatabaseController',
     'PhabricatorConfigDatabaseSchema' => 'PhabricatorConfigStorageSchema',
     'PhabricatorConfigDatabaseSource' => 'PhabricatorConfigProxySource',
     'PhabricatorConfigDatabaseStatusController' => 'PhabricatorConfigDatabaseController',
     'PhabricatorConfigDefaultSource' => 'PhabricatorConfigProxySource',
     'PhabricatorConfigDictionarySource' => 'PhabricatorConfigSource',
     'PhabricatorConfigEditController' => 'PhabricatorConfigController',
     'PhabricatorConfigEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorConfigEntry' => array(
       'PhabricatorConfigEntryDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorConfigEntryDAO' => 'PhabricatorLiskDAO',
     'PhabricatorConfigEntryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorConfigFileSource' => 'PhabricatorConfigProxySource',
     'PhabricatorConfigGroupController' => 'PhabricatorConfigController',
     'PhabricatorConfigIgnoreController' => 'PhabricatorConfigController',
     'PhabricatorConfigIssueListController' => 'PhabricatorConfigController',
     'PhabricatorConfigIssueViewController' => 'PhabricatorConfigController',
     'PhabricatorConfigJSONOptionType' => 'PhabricatorConfigOptionType',
     'PhabricatorConfigKeySchema' => 'PhabricatorConfigStorageSchema',
     'PhabricatorConfigListController' => 'PhabricatorConfigController',
     'PhabricatorConfigLocalSource' => 'PhabricatorConfigProxySource',
     'PhabricatorConfigManagementDeleteWorkflow' => 'PhabricatorConfigManagementWorkflow',
     'PhabricatorConfigManagementGetWorkflow' => 'PhabricatorConfigManagementWorkflow',
     'PhabricatorConfigManagementListWorkflow' => 'PhabricatorConfigManagementWorkflow',
     'PhabricatorConfigManagementMigrateWorkflow' => 'PhabricatorConfigManagementWorkflow',
     'PhabricatorConfigManagementSetWorkflow' => 'PhabricatorConfigManagementWorkflow',
     'PhabricatorConfigManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorConfigOption' => array(
       'Phobject',
       'PhabricatorMarkupInterface',
     ),
     'PhabricatorConfigProxySource' => 'PhabricatorConfigSource',
     'PhabricatorConfigResponse' => 'AphrontHTMLResponse',
     'PhabricatorConfigSchemaQuery' => 'Phobject',
     'PhabricatorConfigSchemaSpec' => 'Phobject',
     'PhabricatorConfigServerSchema' => 'PhabricatorConfigStorageSchema',
     'PhabricatorConfigSiteSource' => 'PhabricatorConfigProxySource',
     'PhabricatorConfigStackSource' => 'PhabricatorConfigSource',
     'PhabricatorConfigStorageSchema' => 'Phobject',
     'PhabricatorConfigTableSchema' => 'PhabricatorConfigStorageSchema',
     'PhabricatorConfigTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorConfigValidationException' => 'Exception',
     'PhabricatorConfigWelcomeController' => 'PhabricatorConfigController',
     'PhabricatorConpherenceApplication' => 'PhabricatorApplication',
     'PhabricatorConpherenceThreadPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorConsoleApplication' => 'PhabricatorApplication',
     'PhabricatorContentSourceView' => 'AphrontView',
     'PhabricatorController' => 'AphrontController',
     'PhabricatorCookies' => 'Phobject',
     'PhabricatorCoreConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorCountdown' => array(
       'PhabricatorCountdownDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorCountdownApplication' => 'PhabricatorApplication',
     'PhabricatorCountdownController' => 'PhabricatorController',
     'PhabricatorCountdownCountdownPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorCountdownDAO' => 'PhabricatorLiskDAO',
     'PhabricatorCountdownDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'PhabricatorCountdownDeleteController' => 'PhabricatorCountdownController',
     'PhabricatorCountdownEditController' => 'PhabricatorCountdownController',
     'PhabricatorCountdownListController' => 'PhabricatorCountdownController',
     'PhabricatorCountdownQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorCountdownRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'PhabricatorCountdownSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorCountdownView' => 'AphrontTagView',
     'PhabricatorCountdownViewController' => 'PhabricatorCountdownController',
     'PhabricatorCrumbView' => 'AphrontView',
     'PhabricatorCrumbsView' => 'AphrontView',
     'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery',
     'PhabricatorCustomFieldConfigOptionType' => 'PhabricatorConfigOptionType',
     'PhabricatorCustomFieldDataNotAvailableException' => 'Exception',
     'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception',
     'PhabricatorCustomFieldIndexStorage' => 'PhabricatorLiskDAO',
     'PhabricatorCustomFieldList' => 'Phobject',
     'PhabricatorCustomFieldMonogramParser' => 'Phobject',
     'PhabricatorCustomFieldNotAttachedException' => 'Exception',
     'PhabricatorCustomFieldNotProxyException' => 'Exception',
     'PhabricatorCustomFieldNumericIndexStorage' => 'PhabricatorCustomFieldIndexStorage',
     'PhabricatorCustomFieldStorage' => 'PhabricatorLiskDAO',
     'PhabricatorCustomFieldStringIndexStorage' => 'PhabricatorCustomFieldIndexStorage',
     'PhabricatorDaemon' => 'PhutilDaemon',
     'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
     'PhabricatorDaemonController' => 'PhabricatorController',
     'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
     'PhabricatorDaemonEventListener' => 'PhabricatorEventListener',
     'PhabricatorDaemonLog' => array(
       'PhabricatorDaemonDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
     'PhabricatorDaemonLogEventGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorDaemonLogEventViewController' => 'PhabricatorDaemonController',
     'PhabricatorDaemonLogEventsView' => 'AphrontView',
     'PhabricatorDaemonLogGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController',
     'PhabricatorDaemonLogListView' => 'AphrontView',
     'PhabricatorDaemonLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
     'PhabricatorDaemonManagementDebugWorkflow' => 'PhabricatorDaemonManagementWorkflow',
     'PhabricatorDaemonManagementLaunchWorkflow' => 'PhabricatorDaemonManagementWorkflow',
     'PhabricatorDaemonManagementListWorkflow' => 'PhabricatorDaemonManagementWorkflow',
     'PhabricatorDaemonManagementLogWorkflow' => 'PhabricatorDaemonManagementWorkflow',
     'PhabricatorDaemonManagementRestartWorkflow' => 'PhabricatorDaemonManagementWorkflow',
     'PhabricatorDaemonManagementStartWorkflow' => 'PhabricatorDaemonManagementWorkflow',
     'PhabricatorDaemonManagementStatusWorkflow' => 'PhabricatorDaemonManagementWorkflow',
     'PhabricatorDaemonManagementStopWorkflow' => 'PhabricatorDaemonManagementWorkflow',
     'PhabricatorDaemonManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorDaemonTaskGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorDaemonsApplication' => 'PhabricatorApplication',
     'PhabricatorDashboard' => array(
       'PhabricatorDashboardDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorDashboardAddPanelController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardApplication' => 'PhabricatorApplication',
     'PhabricatorDashboardController' => 'PhabricatorController',
     'PhabricatorDashboardCopyController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardDAO' => 'PhabricatorLiskDAO',
     'PhabricatorDashboardDashboardPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorDashboardEditController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardHistoryController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardInstall' => 'PhabricatorDashboardDAO',
     'PhabricatorDashboardInstallController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardListController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardManageController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardMovePanelController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardPanel' => array(
       'PhabricatorDashboardDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorCustomFieldInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorDashboardPanelArchiveController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardPanelCoreCustomField' => array(
       'PhabricatorDashboardPanelCustomField',
       'PhabricatorStandardCustomFieldInterface',
     ),
     'PhabricatorDashboardPanelCustomField' => 'PhabricatorCustomField',
     'PhabricatorDashboardPanelEditController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardPanelListController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardPanelPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorDashboardPanelQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorDashboardPanelRenderController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardPanelRenderingEngine' => 'Phobject',
     'PhabricatorDashboardPanelSearchApplicationCustomField' => 'PhabricatorStandardCustomField',
     'PhabricatorDashboardPanelSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorDashboardPanelSearchQueryCustomField' => 'PhabricatorStandardCustomField',
     'PhabricatorDashboardPanelTabsCustomField' => 'PhabricatorStandardCustomField',
     'PhabricatorDashboardPanelTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorDashboardPanelTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorDashboardPanelType' => 'Phobject',
     'PhabricatorDashboardPanelTypeQuery' => 'PhabricatorDashboardPanelType',
     'PhabricatorDashboardPanelTypeTabs' => 'PhabricatorDashboardPanelType',
     'PhabricatorDashboardPanelTypeText' => 'PhabricatorDashboardPanelType',
     'PhabricatorDashboardPanelViewController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorDashboardRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'PhabricatorDashboardRemovePanelController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardRenderingEngine' => 'Phobject',
     'PhabricatorDashboardSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorDashboardTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorDashboardTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorDashboardTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorDashboardUninstallController' => 'PhabricatorDashboardController',
     'PhabricatorDashboardViewController' => 'PhabricatorDashboardController',
     'PhabricatorDataNotAttachedException' => 'Exception',
     'PhabricatorDebugController' => 'PhabricatorController',
     'PhabricatorDefaultFileStorageEngineSelector' => 'PhabricatorFileStorageEngineSelector',
     'PhabricatorDefaultSearchEngineSelector' => 'PhabricatorSearchEngineSelector',
     'PhabricatorDestructionEngine' => 'Phobject',
     'PhabricatorDeveloperConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorDifferentialApplication' => 'PhabricatorApplication',
     'PhabricatorDifferentialConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorDifferentialRevisionTestDataGenerator' => 'PhabricatorTestDataGenerator',
     'PhabricatorDiffusionApplication' => 'PhabricatorApplication',
     'PhabricatorDiffusionConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorDisabledUserController' => 'PhabricatorAuthController',
     'PhabricatorDisqusAuthProvider' => 'PhabricatorOAuth2AuthProvider',
     'PhabricatorDisqusConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorDivinerApplication' => 'PhabricatorApplication',
     'PhabricatorDoorkeeperApplication' => 'PhabricatorApplication',
     'PhabricatorDraft' => 'PhabricatorDraftDAO',
     'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
     'PhabricatorDrydockApplication' => 'PhabricatorApplication',
     'PhabricatorEdgeConfig' => 'PhabricatorEdgeConstants',
     'PhabricatorEdgeCycleException' => 'Exception',
     'PhabricatorEdgeEditor' => 'Phobject',
     'PhabricatorEdgeGraph' => 'AbstractDirectedGraph',
     'PhabricatorEdgeQuery' => 'PhabricatorQuery',
     'PhabricatorEdgeTestCase' => 'PhabricatorTestCase',
     'PhabricatorEdgeType' => 'Phobject',
     'PhabricatorEditor' => 'Phobject',
     'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
     'PhabricatorEmailVerificationController' => 'PhabricatorAuthController',
     'PhabricatorEmbedFileRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'PhabricatorEmojiRemarkupRule' => 'PhutilRemarkupRule',
     'PhabricatorEmptyQueryException' => 'Exception',
     'PhabricatorEnglishTranslation' => 'PhabricatorBaseEnglishTranslation',
     'PhabricatorEnvTestCase' => 'PhabricatorTestCase',
     'PhabricatorErrorExample' => 'PhabricatorUIExample',
     'PhabricatorEvent' => 'PhutilEvent',
     'PhabricatorEventListener' => 'PhutilEventListener',
     'PhabricatorEventType' => 'PhutilEventType',
     'PhabricatorExampleEventListener' => 'PhabricatorEventListener',
     'PhabricatorExtendingPhabricatorConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorExternalAccount' => array(
       'PhabricatorUserDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorExternalAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorFacebookAuthProvider' => 'PhabricatorOAuth2AuthProvider',
     'PhabricatorFactAggregate' => 'PhabricatorFactDAO',
     'PhabricatorFactApplication' => 'PhabricatorApplication',
     'PhabricatorFactChartController' => 'PhabricatorFactController',
     'PhabricatorFactController' => 'PhabricatorController',
     'PhabricatorFactCountEngine' => 'PhabricatorFactEngine',
     'PhabricatorFactCursor' => 'PhabricatorFactDAO',
     'PhabricatorFactDAO' => 'PhabricatorLiskDAO',
     'PhabricatorFactDaemon' => 'PhabricatorDaemon',
     'PhabricatorFactHomeController' => 'PhabricatorFactController',
     'PhabricatorFactLastUpdatedEngine' => 'PhabricatorFactEngine',
     'PhabricatorFactManagementAnalyzeWorkflow' => 'PhabricatorFactManagementWorkflow',
     'PhabricatorFactManagementCursorsWorkflow' => 'PhabricatorFactManagementWorkflow',
     'PhabricatorFactManagementDestroyWorkflow' => 'PhabricatorFactManagementWorkflow',
     'PhabricatorFactManagementListWorkflow' => 'PhabricatorFactManagementWorkflow',
     'PhabricatorFactManagementStatusWorkflow' => 'PhabricatorFactManagementWorkflow',
     'PhabricatorFactManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorFactRaw' => 'PhabricatorFactDAO',
     'PhabricatorFactSimpleSpec' => 'PhabricatorFactSpec',
     'PhabricatorFactUpdateIterator' => 'PhutilBufferedIterator',
     'PhabricatorFeedApplication' => 'PhabricatorApplication',
     'PhabricatorFeedConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorFeedController' => 'PhabricatorController',
     'PhabricatorFeedDAO' => 'PhabricatorLiskDAO',
     'PhabricatorFeedDetailController' => 'PhabricatorFeedController',
     'PhabricatorFeedListController' => 'PhabricatorFeedController',
     'PhabricatorFeedManagementRepublishWorkflow' => 'PhabricatorFeedManagementWorkflow',
     'PhabricatorFeedManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorFeedPublicStreamController' => 'PhabricatorFeedController',
     'PhabricatorFeedQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorFeedSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorFeedStory' => array(
       'PhabricatorPolicyInterface',
       'PhabricatorMarkupInterface',
     ),
     'PhabricatorFeedStoryAggregate' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryAudit' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryCommit' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryData' => 'PhabricatorFeedDAO',
     'PhabricatorFeedStoryDifferential' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryDifferentialAggregate' => 'PhabricatorFeedStoryAggregate',
     'PhabricatorFeedStoryManiphestAggregate' => 'PhabricatorFeedStoryAggregate',
     'PhabricatorFeedStoryNotification' => 'PhabricatorFeedDAO',
     'PhabricatorFeedStoryPhriction' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO',
     'PhabricatorFeedStoryStatus' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryTypeConstants' => 'PhabricatorFeedConstants',
     'PhabricatorFile' => array(
       'PhabricatorFileDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorFileCommentController' => 'PhabricatorFileController',
     'PhabricatorFileComposeController' => 'PhabricatorFileController',
     'PhabricatorFileController' => 'PhabricatorController',
     'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
     'PhabricatorFileDataController' => 'PhabricatorFileController',
     'PhabricatorFileDeleteController' => 'PhabricatorFileController',
     'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
     'PhabricatorFileEditController' => 'PhabricatorFileController',
     'PhabricatorFileEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorFileFilePHIDType' => 'PhabricatorPHIDType',
     'PhabricatorFileImageMacro' => array(
       'PhabricatorFileDAO',
       'PhabricatorSubscribableInterface',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorFileInfoController' => 'PhabricatorFileController',
     'PhabricatorFileLinkListView' => 'AphrontView',
     'PhabricatorFileLinkView' => 'AphrontView',
     'PhabricatorFileListController' => 'PhabricatorFileController',
     'PhabricatorFileQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorFileSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorFileSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO',
     'PhabricatorFileStorageConfigurationException' => 'Exception',
     'PhabricatorFileTemporaryGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorFileTestCase' => 'PhabricatorTestCase',
     'PhabricatorFileTestDataGenerator' => 'PhabricatorTestDataGenerator',
     'PhabricatorFileTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorFileTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PhabricatorFileTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorFileTransformController' => 'PhabricatorFileController',
     'PhabricatorFileUploadController' => 'PhabricatorFileController',
     'PhabricatorFileUploadDialogController' => 'PhabricatorFileController',
     'PhabricatorFileUploadException' => 'Exception',
     'PhabricatorFilesApplication' => 'PhabricatorApplication',
     'PhabricatorFilesConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorFilesManagementCompactWorkflow' => 'PhabricatorFilesManagementWorkflow',
     'PhabricatorFilesManagementEnginesWorkflow' => 'PhabricatorFilesManagementWorkflow',
     'PhabricatorFilesManagementMigrateWorkflow' => 'PhabricatorFilesManagementWorkflow',
     'PhabricatorFilesManagementPurgeWorkflow' => 'PhabricatorFilesManagementWorkflow',
     'PhabricatorFilesManagementRebuildWorkflow' => 'PhabricatorFilesManagementWorkflow',
     'PhabricatorFilesManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorFlag' => array(
       'PhabricatorFlagDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorFlagColor' => 'PhabricatorFlagConstants',
     'PhabricatorFlagController' => 'PhabricatorController',
     'PhabricatorFlagDAO' => 'PhabricatorLiskDAO',
     'PhabricatorFlagDeleteController' => 'PhabricatorFlagController',
     'PhabricatorFlagEditController' => 'PhabricatorFlagController',
     'PhabricatorFlagListController' => 'PhabricatorFlagController',
     'PhabricatorFlagQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorFlagSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorFlagSelectControl' => 'AphrontFormControl',
     'PhabricatorFlaggableInterface' => 'PhabricatorPHIDInterface',
     'PhabricatorFlagsApplication' => 'PhabricatorApplication',
     'PhabricatorFlagsUIEventListener' => 'PhabricatorEventListener',
     'PhabricatorFormExample' => 'PhabricatorUIExample',
     'PhabricatorFundApplication' => 'PhabricatorApplication',
     'PhabricatorGarbageCollector' => 'Phobject',
     'PhabricatorGarbageCollectorConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon',
     'PhabricatorGestureExample' => 'PhabricatorUIExample',
     'PhabricatorGitGraphStream' => 'PhabricatorRepositoryGraphStream',
     'PhabricatorGitHubAuthProvider' => 'PhabricatorOAuth2AuthProvider',
     'PhabricatorGlobalLock' => 'PhutilLock',
     'PhabricatorGlobalUploadTargetView' => 'AphrontView',
     'PhabricatorGoogleAuthProvider' => 'PhabricatorOAuth2AuthProvider',
     'PhabricatorHandleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorHarbormasterApplication' => 'PhabricatorApplication',
     'PhabricatorHarbormasterConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorHashTestCase' => 'PhabricatorTestCase',
     'PhabricatorHelpApplication' => 'PhabricatorApplication',
     'PhabricatorHelpController' => 'PhabricatorController',
     'PhabricatorHelpEditorProtocolController' => 'PhabricatorHelpController',
     'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
     'PhabricatorHeraldApplication' => 'PhabricatorApplication',
     'PhabricatorHomeApplication' => 'PhabricatorApplication',
     'PhabricatorHomeController' => 'PhabricatorController',
     'PhabricatorHomeMainController' => 'PhabricatorHomeController',
     'PhabricatorHomeQuickCreateController' => 'PhabricatorHomeController',
     'PhabricatorHovercardExample' => 'PhabricatorUIExample',
     'PhabricatorHovercardView' => 'AphrontView',
     'PhabricatorHunksManagementMigrateWorkflow' => 'PhabricatorHunksManagementWorkflow',
     'PhabricatorHunksManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorIRCProtocolAdapter' => 'PhabricatorBaseProtocolAdapter',
     'PhabricatorIconRemarkupRule' => 'PhutilRemarkupRule',
     'PhabricatorImageMacroRemarkupRule' => 'PhutilRemarkupRule',
     'PhabricatorInfrastructureTestCase' => 'PhabricatorTestCase',
     'PhabricatorInlineCommentController' => 'PhabricatorController',
     'PhabricatorInlineCommentInterface' => 'PhabricatorMarkupInterface',
     'PhabricatorInlineCommentPreviewController' => 'PhabricatorController',
     'PhabricatorInlineSummaryView' => 'AphrontView',
     'PhabricatorInternationalizationManagementExtractWorkflow' => 'PhabricatorInternationalizationManagementWorkflow',
     'PhabricatorInternationalizationManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorIteratedMD5PasswordHasher' => 'PhabricatorPasswordHasher',
     'PhabricatorJIRAAuthProvider' => 'PhabricatorOAuth1AuthProvider',
     'PhabricatorJavelinLinter' => 'ArcanistLinter',
     'PhabricatorKeyValueDatabaseCache' => 'PhutilKeyValueCache',
     'PhabricatorLDAPAuthProvider' => 'PhabricatorAuthProvider',
     'PhabricatorLegacyEdgeType' => 'PhabricatorEdgeType',
     'PhabricatorLegalpadApplication' => 'PhabricatorApplication',
     'PhabricatorLegalpadConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorLegalpadDocumentPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorLipsumGenerateWorkflow' => 'PhabricatorLipsumManagementWorkflow',
     'PhabricatorLipsumManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorLipsumMondrianArtist' => 'PhabricatorLipsumArtist',
     'PhabricatorLiskDAO' => 'LiskDAO',
     'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine',
     'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase',
     'PhabricatorLogoutController' => 'PhabricatorAuthController',
     'PhabricatorMacroApplication' => 'PhabricatorApplication',
     'PhabricatorMacroAudioController' => 'PhabricatorMacroController',
     'PhabricatorMacroCommentController' => 'PhabricatorMacroController',
     'PhabricatorMacroConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorMacroController' => 'PhabricatorController',
     'PhabricatorMacroDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorMacroDisableController' => 'PhabricatorMacroController',
     'PhabricatorMacroEditController' => 'PhabricatorMacroController',
     'PhabricatorMacroEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorMacroListController' => 'PhabricatorMacroController',
     'PhabricatorMacroMacroPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorMacroMailReceiver' => 'PhabricatorObjectMailReceiver',
     'PhabricatorMacroManageCapability' => 'PhabricatorPolicyCapability',
     'PhabricatorMacroMemeController' => 'PhabricatorMacroController',
     'PhabricatorMacroMemeDialogController' => 'PhabricatorMacroController',
     'PhabricatorMacroQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorMacroReplyHandler' => 'PhabricatorMailReplyHandler',
     'PhabricatorMacroSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorMacroTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorMacroTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PhabricatorMacroTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorMacroViewController' => 'PhabricatorMacroController',
     'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter',
     'PhabricatorMailImplementationMailgunAdapter' => 'PhabricatorMailImplementationAdapter',
     'PhabricatorMailImplementationPHPMailerAdapter' => 'PhabricatorMailImplementationAdapter',
     'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
     'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
     'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
     'PhabricatorMailManagementListInboundWorkflow' => 'PhabricatorMailManagementWorkflow',
     'PhabricatorMailManagementListOutboundWorkflow' => 'PhabricatorMailManagementWorkflow',
     'PhabricatorMailManagementReceiveTestWorkflow' => 'PhabricatorMailManagementWorkflow',
     'PhabricatorMailManagementResendWorkflow' => 'PhabricatorMailManagementWorkflow',
     'PhabricatorMailManagementSendTestWorkflow' => 'PhabricatorMailManagementWorkflow',
     'PhabricatorMailManagementShowInboundWorkflow' => 'PhabricatorMailManagementWorkflow',
     'PhabricatorMailManagementShowOutboundWorkflow' => 'PhabricatorMailManagementWorkflow',
     'PhabricatorMailManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorMailReceiverTestCase' => 'PhabricatorTestCase',
     'PhabricatorMailgunConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorMailingListDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorMailingListListPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorMailingListQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorMailingListSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorMailingListsApplication' => 'PhabricatorApplication',
     'PhabricatorMailingListsController' => 'PhabricatorController',
     'PhabricatorMailingListsEditController' => 'PhabricatorMailingListsController',
     'PhabricatorMailingListsListController' => 'PhabricatorMailingListsController',
     'PhabricatorMainMenuGroupView' => 'AphrontView',
     'PhabricatorMainMenuIconView' => 'AphrontView',
     'PhabricatorMainMenuSearchView' => 'AphrontView',
     'PhabricatorMainMenuView' => 'AphrontView',
     'PhabricatorManagementWorkflow' => 'PhutilArgumentWorkflow',
     'PhabricatorManiphestApplication' => 'PhabricatorApplication',
     'PhabricatorManiphestConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorManiphestTaskTestDataGenerator' => 'PhabricatorTestDataGenerator',
     'PhabricatorMarkupCache' => 'PhabricatorCacheDAO',
     'PhabricatorMarkupOneOff' => 'PhabricatorMarkupInterface',
     'PhabricatorMarkupPreviewController' => 'PhabricatorController',
     'PhabricatorMemeRemarkupRule' => 'PhutilRemarkupRule',
     'PhabricatorMentionRemarkupRule' => 'PhutilRemarkupRule',
     'PhabricatorMercurialGraphStream' => 'PhabricatorRepositoryGraphStream',
     'PhabricatorMetaMTAActorQuery' => 'PhabricatorQuery',
     'PhabricatorMetaMTAApplication' => 'PhabricatorApplication',
     'PhabricatorMetaMTAConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorMetaMTAController' => 'PhabricatorController',
     'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
     'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
     'PhabricatorMetaMTAErrorMailAction' => 'PhabricatorSystemAction',
     'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
     'PhabricatorMetaMTAMailBodyTestCase' => 'PhabricatorTestCase',
     'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase',
     'PhabricatorMetaMTAMailableDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'PhabricatorMetaMTAMailgunReceiveController' => 'PhabricatorMetaMTAController',
     'PhabricatorMetaMTAMailingList' => array(
       'PhabricatorMetaMTADAO',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorMetaMTAMemberQuery' => 'PhabricatorQuery',
     'PhabricatorMetaMTAPermanentFailureException' => 'Exception',
     'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO',
     'PhabricatorMetaMTAReceivedMailProcessingException' => 'Exception',
     'PhabricatorMetaMTAReceivedMailTestCase' => 'PhabricatorTestCase',
     'PhabricatorMetaMTASchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorMetaMTASendGridReceiveController' => 'PhabricatorMetaMTAController',
     'PhabricatorMetaMTAWorker' => 'PhabricatorWorker',
     'PhabricatorMultiColumnExample' => 'PhabricatorUIExample',
     'PhabricatorMustVerifyEmailController' => 'PhabricatorAuthController',
     'PhabricatorMySQLConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorMySQLFileStorageEngine' => 'PhabricatorFileStorageEngine',
     'PhabricatorNamedQuery' => array(
       'PhabricatorSearchDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorNamedQueryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorNavigationRemarkupRule' => 'PhutilRemarkupRule',
     'PhabricatorNotificationAdHocFeedStory' => 'PhabricatorFeedStory',
     'PhabricatorNotificationClearController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorNotificationController' => 'PhabricatorController',
     'PhabricatorNotificationIndividualController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationListController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationPanelController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorNotificationSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorNotificationStatusController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationStatusView' => 'AphrontTagView',
     'PhabricatorNotificationTestController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationsApplication' => 'PhabricatorApplication',
     'PhabricatorNuanceApplication' => 'PhabricatorApplication',
     'PhabricatorOAuth1AuthProvider' => 'PhabricatorOAuthAuthProvider',
     'PhabricatorOAuth2AuthProvider' => 'PhabricatorOAuthAuthProvider',
     'PhabricatorOAuthAuthProvider' => 'PhabricatorAuthProvider',
     'PhabricatorOAuthClientAuthorization' => array(
       'PhabricatorOAuthServerDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorOAuthClientAuthorizationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorOAuthClientController' => 'PhabricatorOAuthServerController',
     'PhabricatorOAuthClientDeleteController' => 'PhabricatorOAuthClientController',
     'PhabricatorOAuthClientEditController' => 'PhabricatorOAuthClientController',
     'PhabricatorOAuthClientListController' => 'PhabricatorOAuthClientController',
     'PhabricatorOAuthClientViewController' => 'PhabricatorOAuthClientController',
     'PhabricatorOAuthResponse' => 'AphrontResponse',
     'PhabricatorOAuthServerAccessToken' => 'PhabricatorOAuthServerDAO',
     'PhabricatorOAuthServerApplication' => 'PhabricatorApplication',
     'PhabricatorOAuthServerAuthController' => 'PhabricatorAuthController',
     'PhabricatorOAuthServerAuthorizationCode' => 'PhabricatorOAuthServerDAO',
     'PhabricatorOAuthServerAuthorizationsSettingsPanel' => 'PhabricatorSettingsPanel',
     'PhabricatorOAuthServerClient' => array(
       'PhabricatorOAuthServerDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorOAuthServerClientAuthorizationPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorOAuthServerClientPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorOAuthServerClientQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorOAuthServerClientSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorOAuthServerController' => 'PhabricatorController',
     'PhabricatorOAuthServerCreateClientsCapability' => 'PhabricatorPolicyCapability',
     'PhabricatorOAuthServerDAO' => 'PhabricatorLiskDAO',
     'PhabricatorOAuthServerTestCase' => 'PhabricatorTestCase',
     'PhabricatorOAuthServerTestController' => 'PhabricatorOAuthServerController',
     'PhabricatorOAuthServerTokenController' => 'PhabricatorAuthController',
     'PhabricatorObjectHandle' => 'PhabricatorPolicyInterface',
     'PhabricatorObjectHandleStatus' => 'PhabricatorObjectHandleConstants',
     'PhabricatorObjectListQueryTestCase' => 'PhabricatorTestCase',
     'PhabricatorObjectMailReceiver' => 'PhabricatorMailReceiver',
     'PhabricatorObjectMailReceiverTestCase' => 'PhabricatorTestCase',
     'PhabricatorObjectMentionedByObject' => 'PhabricatorEdgeType',
     'PhabricatorObjectMentionsObject' => 'PhabricatorEdgeType',
     'PhabricatorObjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorObjectRemarkupRule' => 'PhutilRemarkupRule',
     'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
     'PhabricatorOwnersApplication' => 'PhabricatorApplication',
     'PhabricatorOwnersConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorOwnersController' => 'PhabricatorController',
     'PhabricatorOwnersDAO' => 'PhabricatorLiskDAO',
     'PhabricatorOwnersDeleteController' => 'PhabricatorOwnersController',
     'PhabricatorOwnersDetailController' => 'PhabricatorOwnersController',
     'PhabricatorOwnersEditController' => 'PhabricatorOwnersController',
     'PhabricatorOwnersListController' => 'PhabricatorOwnersController',
     'PhabricatorOwnersOwner' => 'PhabricatorOwnersDAO',
     'PhabricatorOwnersPackage' => array(
       'PhabricatorOwnersDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorOwnersPackageDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorOwnersPackagePHIDType' => 'PhabricatorPHIDType',
     'PhabricatorOwnersPackageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorOwnersPackageTestCase' => 'PhabricatorTestCase',
     'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
     'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPHPASTApplication' => 'PhabricatorApplication',
     'PhabricatorPHPMailerConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPagedFormExample' => 'PhabricatorUIExample',
     'PhabricatorPassphraseApplication' => 'PhabricatorApplication',
     'PhabricatorPasswordAuthProvider' => 'PhabricatorAuthProvider',
     'PhabricatorPasswordHasher' => 'Phobject',
     'PhabricatorPasswordHasherTestCase' => 'PhabricatorTestCase',
     'PhabricatorPasswordHasherUnavailableException' => 'Exception',
     'PhabricatorPaste' => array(
       'PhabricatorPasteDAO',
       'PhabricatorSubscribableInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorMentionableInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorProjectInterface',
       'PhabricatorDestructibleInterface',
       'PhabricatorApplicationTransactionInterface',
     ),
     'PhabricatorPasteApplication' => 'PhabricatorApplication',
     'PhabricatorPasteCommentController' => 'PhabricatorPasteController',
     'PhabricatorPasteConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPasteController' => 'PhabricatorController',
     'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
     'PhabricatorPasteEditController' => 'PhabricatorPasteController',
     'PhabricatorPasteEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorPasteListController' => 'PhabricatorPasteController',
     'PhabricatorPastePastePHIDType' => 'PhabricatorPHIDType',
     'PhabricatorPasteQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorPasteRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'PhabricatorPasteSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorPasteSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorPasteTestDataGenerator' => 'PhabricatorTestDataGenerator',
     'PhabricatorPasteTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorPasteTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PhabricatorPasteTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorPasteViewController' => 'PhabricatorPasteController',
     'PhabricatorPeopleApplication' => 'PhabricatorApplication',
     'PhabricatorPeopleApproveController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleCalendarController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleController' => 'PhabricatorController',
     'PhabricatorPeopleCreateController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorPeopleDeleteController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleDisableController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleEmpowerController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleExternalPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorPeopleHovercardEventListener' => 'PhabricatorEventListener',
     'PhabricatorPeopleLdapController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorPeopleLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleNewController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleProfileEditController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleProfilePictureController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorPeopleRenameController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorPeopleTestDataGenerator' => 'PhabricatorTestDataGenerator',
     'PhabricatorPeopleUserPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorPeopleWelcomeController' => 'PhabricatorPeopleController',
     'PhabricatorPersonaAuthProvider' => 'PhabricatorAuthProvider',
     'PhabricatorPhameApplication' => 'PhabricatorApplication',
     'PhabricatorPhameBlogPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorPhameConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPhamePostPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorPhluxApplication' => 'PhabricatorApplication',
     'PhabricatorPholioApplication' => 'PhabricatorApplication',
     'PhabricatorPholioConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPholioMockTestDataGenerator' => 'PhabricatorTestDataGenerator',
     'PhabricatorPhortuneApplication' => 'PhabricatorApplication',
     'PhabricatorPhragmentApplication' => 'PhabricatorApplication',
     'PhabricatorPhrequentApplication' => 'PhabricatorApplication',
     'PhabricatorPhrequentConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPhrictionApplication' => 'PhabricatorApplication',
     'PhabricatorPhrictionConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPolicies' => 'PhabricatorPolicyConstants',
     'PhabricatorPolicy' => array(
       'PhabricatorPolicyDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorPolicyApplication' => 'PhabricatorApplication',
     'PhabricatorPolicyAwareQuery' => 'PhabricatorOffsetPagedQuery',
     'PhabricatorPolicyAwareTestQuery' => 'PhabricatorPolicyAwareQuery',
     'PhabricatorPolicyCanEditCapability' => 'PhabricatorPolicyCapability',
     'PhabricatorPolicyCanJoinCapability' => 'PhabricatorPolicyCapability',
     'PhabricatorPolicyCanViewCapability' => 'PhabricatorPolicyCapability',
     'PhabricatorPolicyCapability' => 'Phobject',
     'PhabricatorPolicyConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPolicyController' => 'PhabricatorController',
     'PhabricatorPolicyDAO' => 'PhabricatorLiskDAO',
     'PhabricatorPolicyDataTestCase' => 'PhabricatorTestCase',
     'PhabricatorPolicyEditController' => 'PhabricatorPolicyController',
     'PhabricatorPolicyException' => 'Exception',
     'PhabricatorPolicyExplainController' => 'PhabricatorPolicyController',
     'PhabricatorPolicyInterface' => 'PhabricatorPHIDInterface',
     'PhabricatorPolicyManagementShowWorkflow' => 'PhabricatorPolicyManagementWorkflow',
     'PhabricatorPolicyManagementUnlockWorkflow' => 'PhabricatorPolicyManagementWorkflow',
     'PhabricatorPolicyManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorPolicyPHIDTypePolicy' => 'PhabricatorPHIDType',
     'PhabricatorPolicyQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorPolicyRuleAdministrators' => 'PhabricatorPolicyRule',
     'PhabricatorPolicyRuleLegalpadSignature' => 'PhabricatorPolicyRule',
     'PhabricatorPolicyRuleLunarPhase' => 'PhabricatorPolicyRule',
     'PhabricatorPolicyRuleProjects' => 'PhabricatorPolicyRule',
     'PhabricatorPolicyRuleUsers' => 'PhabricatorPolicyRule',
     'PhabricatorPolicyTestCase' => 'PhabricatorTestCase',
     'PhabricatorPolicyTestObject' => 'PhabricatorPolicyInterface',
     'PhabricatorPolicyType' => 'PhabricatorPolicyConstants',
     'PhabricatorPonderApplication' => 'PhabricatorApplication',
     'PhabricatorProject' => array(
       'PhabricatorProjectDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorCustomFieldInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorProjectApplication' => 'PhabricatorApplication',
     'PhabricatorProjectArchiveController' => 'PhabricatorProjectController',
     'PhabricatorProjectBoardController' => 'PhabricatorProjectController',
     'PhabricatorProjectBoardImportController' => 'PhabricatorProjectBoardController',
     'PhabricatorProjectBoardReorderController' => 'PhabricatorProjectBoardController',
     'PhabricatorProjectBoardViewController' => 'PhabricatorProjectBoardController',
     'PhabricatorProjectColumn' => array(
       'PhabricatorProjectDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorProjectColumnDetailController' => 'PhabricatorProjectBoardController',
     'PhabricatorProjectColumnEditController' => 'PhabricatorProjectBoardController',
     'PhabricatorProjectColumnHideController' => 'PhabricatorProjectBoardController',
     'PhabricatorProjectColumnPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorProjectColumnPosition' => array(
       'PhabricatorProjectDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorProjectColumnPositionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorProjectColumnQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorProjectColumnTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorProjectColumnTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorProjectColumnTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorProjectConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorProjectConfiguredCustomField' => array(
       'PhabricatorProjectStandardCustomField',
       'PhabricatorStandardCustomFieldInterface',
     ),
     'PhabricatorProjectController' => 'PhabricatorController',
     'PhabricatorProjectCustomField' => 'PhabricatorCustomField',
     'PhabricatorProjectCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
     'PhabricatorProjectCustomFieldStorage' => 'PhabricatorCustomFieldStorage',
     'PhabricatorProjectCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
     'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
     'PhabricatorProjectDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorProjectDescriptionField' => 'PhabricatorProjectStandardCustomField',
     'PhabricatorProjectEditDetailsController' => 'PhabricatorProjectController',
     'PhabricatorProjectEditIconController' => 'PhabricatorProjectController',
     'PhabricatorProjectEditMainController' => 'PhabricatorProjectController',
     'PhabricatorProjectEditPictureController' => 'PhabricatorProjectController',
     'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase',
     'PhabricatorProjectIcon' => 'Phobject',
     'PhabricatorProjectListController' => 'PhabricatorProjectController',
     'PhabricatorProjectMembersEditController' => 'PhabricatorProjectController',
     'PhabricatorProjectMembersRemoveController' => 'PhabricatorProjectController',
     'PhabricatorProjectMoveController' => 'PhabricatorProjectController',
     'PhabricatorProjectNameCollisionException' => 'Exception',
     'PhabricatorProjectObjectHasProjectEdgeType' => 'PhabricatorEdgeType',
     'PhabricatorProjectOrUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
     'PhabricatorProjectProjectHasObjectEdgeType' => 'PhabricatorEdgeType',
     'PhabricatorProjectProjectPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorProjectSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorProjectSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorProjectSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PhabricatorProjectSlug' => 'PhabricatorProjectDAO',
     'PhabricatorProjectStandardCustomField' => array(
       'PhabricatorProjectCustomField',
       'PhabricatorStandardCustomFieldInterface',
     ),
     'PhabricatorProjectTestDataGenerator' => 'PhabricatorTestDataGenerator',
     'PhabricatorProjectTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorProjectTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorProjectTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorProjectUIEventListener' => 'PhabricatorEventListener',
     'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
     'PhabricatorProjectWatchController' => 'PhabricatorProjectController',
     'PhabricatorProjectWikiExplainController' => 'PhabricatorProjectController',
     'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorRedirectController' => 'PhabricatorController',
     'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
     'PhabricatorRegistrationProfile' => 'Phobject',
     'PhabricatorReleephApplication' => 'PhabricatorApplication',
     'PhabricatorReleephApplicationConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorRemarkupControl' => 'AphrontFormTextAreaControl',
     'PhabricatorRemarkupCowsayBlockInterpreter' => 'PhutilRemarkupBlockInterpreter',
     'PhabricatorRemarkupCustomBlockRule' => 'PhutilRemarkupBlockRule',
     'PhabricatorRemarkupCustomInlineRule' => 'PhutilRemarkupRule',
     'PhabricatorRemarkupExample' => 'PhabricatorUIExample',
     'PhabricatorRemarkupFigletBlockInterpreter' => 'PhutilRemarkupBlockInterpreter',
     'PhabricatorRemarkupGraphvizBlockInterpreter' => 'PhutilRemarkupBlockInterpreter',
     'PhabricatorRepositoriesApplication' => 'PhabricatorApplication',
     'PhabricatorRepository' => array(
       'PhabricatorRepositoryDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorMarkupInterface',
       'PhabricatorDestructibleInterface',
       'PhabricatorProjectInterface',
     ),
     'PhabricatorRepositoryArcanistProject' => array(
       'PhabricatorRepositoryDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorRepositoryArcanistProjectDeleteController' => 'PhabricatorRepositoryController',
     'PhabricatorRepositoryArcanistProjectEditController' => 'PhabricatorRepositoryController',
     'PhabricatorRepositoryArcanistProjectPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorRepositoryArcanistProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorRepositoryAuditRequest' => array(
       'PhabricatorRepositoryDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorRepositoryBranch' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositoryCommit' => array(
       'PhabricatorRepositoryDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorProjectInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorMentionableInterface',
       'HarbormasterBuildableInterface',
       'PhabricatorCustomFieldInterface',
       'PhabricatorApplicationTransactionInterface',
     ),
     'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
     'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositoryCommitHeraldWorker' => 'PhabricatorRepositoryCommitParserWorker',
     'PhabricatorRepositoryCommitMessageParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
     'PhabricatorRepositoryCommitOwnersWorker' => 'PhabricatorRepositoryCommitParserWorker',
     'PhabricatorRepositoryCommitPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker',
     'PhabricatorRepositoryCommitSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorRepositoryController' => 'PhabricatorController',
     'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
     'PhabricatorRepositoryDiscoveryEngine' => 'PhabricatorRepositoryEngine',
     'PhabricatorRepositoryEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
     'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
     'PhabricatorRepositoryGraphStream' => 'Phobject',
     'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController',
     'PhabricatorRepositoryManagementCacheWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementEditWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementImportingWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementLookupUsersWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementMarkImportedWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementMirrorWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementParentsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementPullWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementRefsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementUpdateWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
     'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
     'PhabricatorRepositoryMirror' => array(
       'PhabricatorRepositoryDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorRepositoryMirrorEngine' => 'PhabricatorRepositoryEngine',
     'PhabricatorRepositoryMirrorPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorRepositoryMirrorQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorRepositoryParsedChange' => 'Phobject',
     'PhabricatorRepositoryPullEngine' => 'PhabricatorRepositoryEngine',
     'PhabricatorRepositoryPullLocalDaemon' => 'PhabricatorDaemon',
     'PhabricatorRepositoryPushEvent' => array(
       'PhabricatorRepositoryDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorRepositoryPushEventPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorRepositoryPushEventQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorRepositoryPushLog' => array(
       'PhabricatorRepositoryDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorRepositoryPushLogPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorRepositoryPushLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorRepositoryPushLogSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorRepositoryPushMailWorker' => 'PhabricatorWorker',
     'PhabricatorRepositoryPushReplyHandler' => 'PhabricatorMailReplyHandler',
     'PhabricatorRepositoryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorRepositoryRefCursor' => array(
       'PhabricatorRepositoryDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorRepositoryRefCursorQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorRepositoryRefEngine' => 'PhabricatorRepositoryEngine',
     'PhabricatorRepositoryRepositoryPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorRepositorySchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorRepositorySearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorRepositoryStatusMessage' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositorySvnCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
     'PhabricatorRepositorySvnCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
     'PhabricatorRepositorySymbol' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositoryTestCase' => 'PhabricatorTestCase',
     'PhabricatorRepositoryTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorRepositoryTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorRepositoryURINormalizer' => 'Phobject',
     'PhabricatorRepositoryURINormalizerTestCase' => 'PhabricatorTestCase',
     'PhabricatorRepositoryURITestCase' => 'PhabricatorTestCase',
     'PhabricatorRepositoryVCSPassword' => 'PhabricatorRepositoryDAO',
     'PhabricatorRobotsController' => 'PhabricatorController',
     'PhabricatorS3FileStorageEngine' => 'PhabricatorFileStorageEngine',
     'PhabricatorSMS' => 'PhabricatorSMSDAO',
     'PhabricatorSMSConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorSMSDAO' => 'PhabricatorLiskDAO',
     'PhabricatorSMSDemultiplexWorker' => 'PhabricatorSMSWorker',
     'PhabricatorSMSImplementationTestBlackholeAdapter' => 'PhabricatorSMSImplementationAdapter',
     'PhabricatorSMSImplementationTwilioAdapter' => 'PhabricatorSMSImplementationAdapter',
     'PhabricatorSMSManagementListOutboundWorkflow' => 'PhabricatorSMSManagementWorkflow',
     'PhabricatorSMSManagementSendTestWorkflow' => 'PhabricatorSMSManagementWorkflow',
     'PhabricatorSMSManagementShowOutboundWorkflow' => 'PhabricatorSMSManagementWorkflow',
     'PhabricatorSMSManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorSMSSendWorker' => 'PhabricatorSMSWorker',
     'PhabricatorSMSWorker' => 'PhabricatorWorker',
     'PhabricatorSSHKeyGenerator' => 'Phobject',
     'PhabricatorSSHLog' => 'Phobject',
     'PhabricatorSSHPassthruCommand' => 'Phobject',
     'PhabricatorSSHWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorSavedQuery' => array(
       'PhabricatorSearchDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorSavedQueryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorSearchApplication' => 'PhabricatorApplication',
     'PhabricatorSearchApplicationSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorSearchAttachController' => 'PhabricatorSearchBaseController',
     'PhabricatorSearchBaseController' => 'PhabricatorController',
     'PhabricatorSearchConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
     'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
     'PhabricatorSearchDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'PhabricatorSearchDeleteController' => 'PhabricatorSearchBaseController',
     'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
     'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
     'PhabricatorSearchDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
     'PhabricatorSearchEditController' => 'PhabricatorSearchBaseController',
     'PhabricatorSearchEngineElastic' => 'PhabricatorSearchEngine',
     'PhabricatorSearchEngineMySQL' => 'PhabricatorSearchEngine',
     'PhabricatorSearchHovercardController' => 'PhabricatorSearchBaseController',
     'PhabricatorSearchManagementIndexWorkflow' => 'PhabricatorSearchManagementWorkflow',
     'PhabricatorSearchManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorSearchOrderController' => 'PhabricatorSearchBaseController',
     'PhabricatorSearchResultView' => 'AphrontView',
     'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController',
     'PhabricatorSearchWorker' => 'PhabricatorWorker',
     'PhabricatorSecurityConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorSendGridConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorSettingsAddEmailAction' => 'PhabricatorSystemAction',
     'PhabricatorSettingsAdjustController' => 'PhabricatorController',
     'PhabricatorSettingsApplication' => 'PhabricatorApplication',
     'PhabricatorSettingsMainController' => 'PhabricatorController',
     'PhabricatorSettingsPanelAccount' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelActivity' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelConduit' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelConpherencePreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelDeveloperPreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelDiffPreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelDisplayPreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelEmailAddresses' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelEmailFormat' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelEmailPreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelExternalAccounts' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelHomePreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelMultiFactor' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelPassword' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelSSHKeys' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelSearchPreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelSessions' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelTokens' => 'PhabricatorSettingsPanel',
     'PhabricatorSetupCheckAPC' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckAphlict' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckAuth' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckBaseURI' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckBinaries' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckDaemons' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckDatabase' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckExtensions' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckExtraConfig' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckFileinfo' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckGD' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckImagemagick' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckInvalidConfig' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckMail' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckMySQL' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckPHPConfig' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckPath' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckPygment' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckRepositories' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckSecurity' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckStorage' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckTimezone' => 'PhabricatorSetupCheck',
     'PhabricatorSetupIssueExample' => 'PhabricatorUIExample',
     'PhabricatorSetupIssueView' => 'AphrontView',
     'PhabricatorSlowvoteApplication' => 'PhabricatorApplication',
     'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO',
     'PhabricatorSlowvoteCloseController' => 'PhabricatorSlowvoteController',
     'PhabricatorSlowvoteCommentController' => 'PhabricatorSlowvoteController',
     'PhabricatorSlowvoteController' => 'PhabricatorController',
     'PhabricatorSlowvoteDAO' => 'PhabricatorLiskDAO',
     'PhabricatorSlowvoteDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'PhabricatorSlowvoteEditController' => 'PhabricatorSlowvoteController',
     'PhabricatorSlowvoteEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorSlowvoteListController' => 'PhabricatorSlowvoteController',
     'PhabricatorSlowvoteOption' => 'PhabricatorSlowvoteDAO',
     'PhabricatorSlowvotePoll' => array(
       'PhabricatorSlowvoteDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorProjectInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PhabricatorSlowvotePollController' => 'PhabricatorSlowvoteController',
     'PhabricatorSlowvotePollPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorSlowvoteQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorSlowvoteSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorSlowvoteSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhabricatorSlowvoteTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorSlowvoteTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PhabricatorSlowvoteTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorSlowvoteVoteController' => 'PhabricatorSlowvoteController',
     'PhabricatorSlugTestCase' => 'PhabricatorTestCase',
     'PhabricatorSortTableExample' => 'PhabricatorUIExample',
     'PhabricatorSourceCodeView' => 'AphrontView',
     'PhabricatorStandardCustomField' => 'PhabricatorCustomField',
     'PhabricatorStandardCustomFieldBool' => 'PhabricatorStandardCustomField',
     'PhabricatorStandardCustomFieldCredential' => 'PhabricatorStandardCustomField',
     'PhabricatorStandardCustomFieldDate' => 'PhabricatorStandardCustomField',
     'PhabricatorStandardCustomFieldHeader' => 'PhabricatorStandardCustomField',
     'PhabricatorStandardCustomFieldInt' => 'PhabricatorStandardCustomField',
     'PhabricatorStandardCustomFieldPHIDs' => 'PhabricatorStandardCustomField',
     'PhabricatorStandardCustomFieldRemarkup' => 'PhabricatorStandardCustomField',
     'PhabricatorStandardCustomFieldSelect' => 'PhabricatorStandardCustomField',
     'PhabricatorStandardCustomFieldText' => 'PhabricatorStandardCustomField',
     'PhabricatorStandardCustomFieldUsers' => 'PhabricatorStandardCustomFieldPHIDs',
     'PhabricatorStandardPageView' => 'PhabricatorBarePageView',
     'PhabricatorStatusController' => 'PhabricatorController',
     'PhabricatorStorageManagementAdjustWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementProbeWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementQuickstartWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementStatusWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementUpgradeWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorStorageSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
     'PhabricatorSubscriptionsApplication' => 'PhabricatorApplication',
     'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
     'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
     'PhabricatorSubscriptionsListController' => 'PhabricatorController',
     'PhabricatorSubscriptionsTransactionController' => 'PhabricatorController',
     'PhabricatorSubscriptionsUIEventListener' => 'PhabricatorEventListener',
     'PhabricatorSupportApplication' => 'PhabricatorApplication',
     'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorSystemActionEngine' => 'Phobject',
     'PhabricatorSystemActionGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorSystemActionLog' => 'PhabricatorSystemDAO',
     'PhabricatorSystemActionRateLimitException' => 'Exception',
     'PhabricatorSystemApplication' => 'PhabricatorApplication',
     'PhabricatorSystemDAO' => 'PhabricatorLiskDAO',
     'PhabricatorSystemDestructionGarbageCollector' => 'PhabricatorGarbageCollector',
     'PhabricatorSystemDestructionLog' => 'PhabricatorSystemDAO',
     'PhabricatorSystemRemoveDestroyWorkflow' => 'PhabricatorSystemRemoveWorkflow',
     'PhabricatorSystemRemoveLogWorkflow' => 'PhabricatorSystemRemoveWorkflow',
     'PhabricatorSystemRemoveWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorSystemSelectEncodingController' => 'PhabricatorController',
     'PhabricatorSystemSelectHighlightController' => 'PhabricatorController',
     'PhabricatorTaskmasterDaemon' => 'PhabricatorDaemon',
     'PhabricatorTestApplication' => 'PhabricatorApplication',
     'PhabricatorTestCase' => 'ArcanistPhutilTestCase',
     'PhabricatorTestController' => 'PhabricatorController',
     'PhabricatorTestStorageEngine' => 'PhabricatorFileStorageEngine',
     'PhabricatorTestWorker' => 'PhabricatorWorker',
     'PhabricatorTimeTestCase' => 'PhabricatorTestCase',
     'PhabricatorToken' => array(
       'PhabricatorTokenDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorTokenController' => 'PhabricatorController',
     'PhabricatorTokenCount' => 'PhabricatorTokenDAO',
     'PhabricatorTokenCountQuery' => 'PhabricatorOffsetPagedQuery',
     'PhabricatorTokenDAO' => 'PhabricatorLiskDAO',
     'PhabricatorTokenGiveController' => 'PhabricatorTokenController',
     'PhabricatorTokenGiven' => array(
       'PhabricatorTokenDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorTokenGivenController' => 'PhabricatorTokenController',
     'PhabricatorTokenGivenEditor' => 'PhabricatorEditor',
     'PhabricatorTokenGivenFeedStory' => 'PhabricatorFeedStory',
     'PhabricatorTokenGivenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorTokenLeaderController' => 'PhabricatorTokenController',
     'PhabricatorTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorTokenReceiverQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorTokenTokenPHIDType' => 'PhabricatorPHIDType',
     'PhabricatorTokenUIEventListener' => 'PhabricatorEventListener',
     'PhabricatorTokensApplication' => 'PhabricatorApplication',
     'PhabricatorTransactionView' => 'AphrontView',
     'PhabricatorTransactionsApplication' => 'PhabricatorApplication',
     'PhabricatorTransformedFile' => 'PhabricatorFileDAO',
     'PhabricatorTranslationsConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorTrivialTestCase' => 'PhabricatorTestCase',
     'PhabricatorTwitchAuthProvider' => 'PhabricatorOAuth2AuthProvider',
     'PhabricatorTwitterAuthProvider' => 'PhabricatorOAuth1AuthProvider',
     'PhabricatorTwoColumnExample' => 'PhabricatorUIExample',
     'PhabricatorTypeaheadApplication' => 'PhabricatorApplication',
     'PhabricatorTypeaheadCompositeDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorTypeaheadDatasource' => 'Phobject',
     'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
     'PhabricatorTypeaheadModularDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
     'PhabricatorTypeaheadMonogramDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorTypeaheadNoOwnerDatasource' => 'PhabricatorTypeaheadDatasource',
     'PhabricatorTypeaheadOwnerDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'PhabricatorTypeaheadRuntimeCompositeDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
     'PhabricatorUIConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorUIExampleRenderController' => 'PhabricatorController',
     'PhabricatorUIExamplesApplication' => 'PhabricatorApplication',
     'PhabricatorUIListFilterExample' => 'PhabricatorUIExample',
     'PhabricatorUINotificationExample' => 'PhabricatorUIExample',
     'PhabricatorUIPagerExample' => 'PhabricatorUIExample',
     'PhabricatorUIStatusExample' => 'PhabricatorUIExample',
     'PhabricatorUITooltipExample' => 'PhabricatorUIExample',
     'PhabricatorUnitsTestCase' => 'PhabricatorTestCase',
     'PhabricatorUser' => array(
       'PhabricatorUserDAO',
       'PhutilPerson',
       'PhabricatorPolicyInterface',
       'PhabricatorCustomFieldInterface',
       'PhabricatorDestructibleInterface',
       'PhabricatorSSHPublicKeyInterface',
     ),
     'PhabricatorUserBlurbField' => 'PhabricatorUserCustomField',
     'PhabricatorUserConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorUserConfiguredCustomField' => array(
       'PhabricatorUserCustomField',
       'PhabricatorStandardCustomFieldInterface',
     ),
     'PhabricatorUserConfiguredCustomFieldStorage' => 'PhabricatorCustomFieldStorage',
     'PhabricatorUserCustomField' => 'PhabricatorCustomField',
     'PhabricatorUserCustomFieldNumericIndex' => 'PhabricatorCustomFieldNumericIndexStorage',
     'PhabricatorUserCustomFieldStringIndex' => 'PhabricatorCustomFieldStringIndexStorage',
     'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
     'PhabricatorUserEditor' => 'PhabricatorEditor',
     'PhabricatorUserEditorTestCase' => 'PhabricatorTestCase',
     'PhabricatorUserEmail' => 'PhabricatorUserDAO',
     'PhabricatorUserEmailTestCase' => 'PhabricatorTestCase',
     'PhabricatorUserLog' => array(
       'PhabricatorUserDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhabricatorUserLogView' => 'AphrontView',
     'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
     'PhabricatorUserProfile' => 'PhabricatorUserDAO',
     'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorUserRealNameField' => 'PhabricatorUserCustomField',
     'PhabricatorUserRolesField' => 'PhabricatorUserCustomField',
     'PhabricatorUserSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhabricatorUserSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PhabricatorUserSinceField' => 'PhabricatorUserCustomField',
     'PhabricatorUserStatusField' => 'PhabricatorUserCustomField',
     'PhabricatorUserTestCase' => 'PhabricatorTestCase',
     'PhabricatorUserTitleField' => 'PhabricatorUserCustomField',
     'PhabricatorUserTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorVCSResponse' => 'AphrontResponse',
     'PhabricatorWordPressAuthProvider' => 'PhabricatorOAuth2AuthProvider',
     'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask',
     'PhabricatorWorkerArchiveTask' => 'PhabricatorWorkerTask',
     'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',
     'PhabricatorWorkerLeaseQuery' => 'PhabricatorQuery',
     'PhabricatorWorkerManagementFloodWorkflow' => 'PhabricatorWorkerManagementWorkflow',
     'PhabricatorWorkerManagementWorkflow' => 'PhabricatorManagementWorkflow',
     'PhabricatorWorkerPermanentFailureException' => 'Exception',
     'PhabricatorWorkerTask' => 'PhabricatorWorkerDAO',
     'PhabricatorWorkerTaskData' => 'PhabricatorWorkerDAO',
     'PhabricatorWorkerTaskDetailController' => 'PhabricatorDaemonController',
     'PhabricatorWorkerTaskUpdateController' => 'PhabricatorDaemonController',
     'PhabricatorWorkerTestCase' => 'PhabricatorTestCase',
     'PhabricatorWorkerYieldException' => 'Exception',
     'PhabricatorWorkingCopyDiscoveryTestCase' => 'PhabricatorWorkingCopyTestCase',
     'PhabricatorWorkingCopyPullTestCase' => 'PhabricatorWorkingCopyTestCase',
     'PhabricatorWorkingCopyTestCase' => 'PhabricatorTestCase',
     'PhabricatorXHPASTViewController' => 'PhabricatorController',
     'PhabricatorXHPASTViewDAO' => 'PhabricatorLiskDAO',
     'PhabricatorXHPASTViewFrameController' => 'PhabricatorXHPASTViewController',
     'PhabricatorXHPASTViewFramesetController' => 'PhabricatorXHPASTViewController',
     'PhabricatorXHPASTViewInputController' => 'PhabricatorXHPASTViewPanelController',
     'PhabricatorXHPASTViewPanelController' => 'PhabricatorXHPASTViewController',
     'PhabricatorXHPASTViewParseTree' => 'PhabricatorXHPASTViewDAO',
     'PhabricatorXHPASTViewRunController' => 'PhabricatorXHPASTViewController',
     'PhabricatorXHPASTViewStreamController' => 'PhabricatorXHPASTViewPanelController',
     'PhabricatorXHPASTViewTreeController' => 'PhabricatorXHPASTViewPanelController',
     'PhabricatorXHProfApplication' => 'PhabricatorApplication',
     'PhabricatorXHProfController' => 'PhabricatorController',
     'PhabricatorXHProfDAO' => 'PhabricatorLiskDAO',
     'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController',
     'PhabricatorXHProfProfileSymbolView' => 'PhabricatorXHProfProfileView',
     'PhabricatorXHProfProfileTopLevelView' => 'PhabricatorXHProfProfileView',
     'PhabricatorXHProfProfileView' => 'AphrontView',
     'PhabricatorXHProfSample' => 'PhabricatorXHProfDAO',
     'PhabricatorXHProfSampleListController' => 'PhabricatorXHProfController',
     'PhabricatorYoutubeRemarkupRule' => 'PhutilRemarkupRule',
     'PhameBasicBlogSkin' => 'PhameBlogSkin',
     'PhameBasicTemplateBlogSkin' => 'PhameBasicBlogSkin',
     'PhameBlog' => array(
       'PhameDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorMarkupInterface',
     ),
     'PhameBlogDeleteController' => 'PhameController',
     'PhameBlogEditController' => 'PhameController',
     'PhameBlogFeedController' => 'PhameController',
     'PhameBlogListController' => 'PhameController',
     'PhameBlogLiveController' => 'PhameController',
     'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhameBlogSkin' => 'PhabricatorController',
     'PhameBlogViewController' => 'PhameController',
     'PhameCelerityResources' => 'CelerityResources',
     'PhameConduitAPIMethod' => 'ConduitAPIMethod',
     'PhameController' => 'PhabricatorController',
     'PhameCreatePostConduitAPIMethod' => 'PhameConduitAPIMethod',
     'PhameDAO' => 'PhabricatorLiskDAO',
     'PhamePost' => array(
       'PhameDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorMarkupInterface',
       'PhabricatorTokenReceiverInterface',
     ),
     'PhamePostDeleteController' => 'PhameController',
     'PhamePostEditController' => 'PhameController',
     'PhamePostFramedController' => 'PhameController',
     'PhamePostListController' => 'PhameController',
     'PhamePostNewController' => 'PhameController',
     'PhamePostNotLiveController' => 'PhameController',
     'PhamePostPreviewController' => 'PhameController',
     'PhamePostPublishController' => 'PhameController',
     'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhamePostUnpublishController' => 'PhameController',
     'PhamePostView' => 'AphrontView',
     'PhamePostViewController' => 'PhameController',
     'PhameQueryConduitAPIMethod' => 'PhameConduitAPIMethod',
     'PhameQueryPostsConduitAPIMethod' => 'PhameConduitAPIMethod',
     'PhameResourceController' => 'CelerityResourceController',
     'PhameSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhluxController' => 'PhabricatorController',
     'PhluxDAO' => 'PhabricatorLiskDAO',
     'PhluxEditController' => 'PhluxController',
     'PhluxListController' => 'PhluxController',
     'PhluxTransaction' => 'PhabricatorApplicationTransaction',
     'PhluxTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhluxVariable' => array(
       'PhluxDAO',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorPolicyInterface',
     ),
     'PhluxVariableEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhluxVariablePHIDType' => 'PhabricatorPHIDType',
     'PhluxVariableQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhluxViewController' => 'PhluxController',
     'PholioActionMenuEventListener' => 'PhabricatorEventListener',
     'PholioController' => 'PhabricatorController',
     'PholioDAO' => 'PhabricatorLiskDAO',
     'PholioDefaultEditCapability' => 'PhabricatorPolicyCapability',
     'PholioDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'PholioImage' => array(
       'PholioDAO',
       'PhabricatorMarkupInterface',
       'PhabricatorPolicyInterface',
     ),
     'PholioImagePHIDType' => 'PhabricatorPHIDType',
     'PholioImageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PholioImageUploadController' => 'PholioController',
     'PholioInlineController' => 'PholioController',
     'PholioInlineListController' => 'PholioController',
     'PholioInlineThumbController' => 'PholioController',
     'PholioMock' => array(
       'PholioDAO',
       'PhabricatorMarkupInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorApplicationTransactionInterface',
       'PhabricatorProjectInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PholioMockCommentController' => 'PholioController',
     'PholioMockEditController' => 'PholioController',
     'PholioMockEditor' => 'PhabricatorApplicationTransactionEditor',
     'PholioMockEmbedView' => 'AphrontView',
     'PholioMockImagesView' => 'AphrontView',
     'PholioMockListController' => 'PholioController',
     'PholioMockMailReceiver' => 'PhabricatorObjectMailReceiver',
     'PholioMockPHIDType' => 'PhabricatorPHIDType',
     'PholioMockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PholioMockSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PholioMockThumbGridView' => 'AphrontView',
     'PholioMockViewController' => 'PholioController',
     'PholioRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'PholioReplyHandler' => 'PhabricatorMailReplyHandler',
     'PholioSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PholioSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PholioTransaction' => 'PhabricatorApplicationTransaction',
     'PholioTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PholioTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PholioTransactionType' => 'PholioConstants',
     'PholioTransactionView' => 'PhabricatorApplicationTransactionView',
     'PholioUploadedImageView' => 'AphrontView',
     'PhortuneAccount' => array(
       'PhortuneDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'PhortuneAccountEditController' => 'PhortuneController',
     'PhortuneAccountEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhortuneAccountHasMemberEdgeType' => 'PhabricatorEdgeType',
     'PhortuneAccountListController' => 'PhortuneController',
     'PhortuneAccountPHIDType' => 'PhabricatorPHIDType',
     'PhortuneAccountQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhortuneAccountTransaction' => 'PhabricatorApplicationTransaction',
     'PhortuneAccountTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhortuneAccountViewController' => 'PhortuneController',
     'PhortuneBalancedPaymentProvider' => 'PhortunePaymentProvider',
     'PhortuneCart' => array(
       'PhortuneDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'PhortuneCartAcceptController' => 'PhortuneCartController',
     'PhortuneCartCancelController' => 'PhortuneCartController',
     'PhortuneCartCheckoutController' => 'PhortuneCartController',
     'PhortuneCartController' => 'PhortuneController',
     'PhortuneCartEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhortuneCartListController' => 'PhortuneController',
     'PhortuneCartPHIDType' => 'PhabricatorPHIDType',
     'PhortuneCartQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhortuneCartReplyHandler' => 'PhabricatorMailReplyHandler',
     'PhortuneCartSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhortuneCartTransaction' => 'PhabricatorApplicationTransaction',
     'PhortuneCartTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhortuneCartUpdateController' => 'PhortuneCartController',
     'PhortuneCartViewController' => 'PhortuneCartController',
     'PhortuneCharge' => array(
       'PhortuneDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhortuneChargeListController' => 'PhortuneController',
     'PhortuneChargePHIDType' => 'PhabricatorPHIDType',
     'PhortuneChargeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhortuneChargeSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhortuneChargeTableView' => 'AphrontView',
     'PhortuneController' => 'PhabricatorController',
     'PhortuneCurrency' => 'Phobject',
     'PhortuneCurrencySerializer' => 'PhabricatorLiskSerializer',
     'PhortuneCurrencyTestCase' => 'PhabricatorTestCase',
     'PhortuneDAO' => 'PhabricatorLiskDAO',
     'PhortuneErrCode' => 'PhortuneConstants',
     'PhortuneLandingController' => 'PhortuneController',
     'PhortuneMemberHasAccountEdgeType' => 'PhabricatorEdgeType',
     'PhortuneMemberHasMerchantEdgeType' => 'PhabricatorEdgeType',
     'PhortuneMerchant' => array(
       'PhortuneDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'PhortuneMerchantCapability' => 'PhabricatorPolicyCapability',
     'PhortuneMerchantController' => 'PhortuneController',
     'PhortuneMerchantEditController' => 'PhortuneMerchantController',
     'PhortuneMerchantEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhortuneMerchantHasMemberEdgeType' => 'PhabricatorEdgeType',
     'PhortuneMerchantListController' => 'PhortuneMerchantController',
     'PhortuneMerchantPHIDType' => 'PhabricatorPHIDType',
     'PhortuneMerchantQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhortuneMerchantSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhortuneMerchantTransaction' => 'PhabricatorApplicationTransaction',
     'PhortuneMerchantTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhortuneMerchantViewController' => 'PhortuneMerchantController',
     'PhortuneMonthYearExpiryControl' => 'AphrontFormControl',
     'PhortuneMultiplePaymentProvidersException' => 'Exception',
     'PhortuneNoPaymentProviderException' => 'Exception',
     'PhortuneNotImplementedException' => 'Exception',
     'PhortuneOrderTableView' => 'AphrontView',
     'PhortunePayPalPaymentProvider' => 'PhortunePaymentProvider',
     'PhortunePaymentMethod' => array(
       'PhortuneDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhortunePaymentMethodCreateController' => 'PhortuneController',
     'PhortunePaymentMethodDisableController' => 'PhortuneController',
     'PhortunePaymentMethodEditController' => 'PhortuneController',
     'PhortunePaymentMethodPHIDType' => 'PhabricatorPHIDType',
     'PhortunePaymentMethodQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhortunePaymentProviderConfig' => array(
       'PhortuneDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhortunePaymentProviderConfigEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhortunePaymentProviderConfigQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhortunePaymentProviderConfigTransaction' => 'PhabricatorApplicationTransaction',
     'PhortunePaymentProviderConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhortunePaymentProviderPHIDType' => 'PhabricatorPHIDType',
     'PhortuneProduct' => array(
       'PhortuneDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhortuneProductListController' => 'PhabricatorController',
     'PhortuneProductPHIDType' => 'PhabricatorPHIDType',
     'PhortuneProductQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhortuneProductViewController' => 'PhortuneController',
     'PhortuneProviderActionController' => 'PhortuneController',
     'PhortuneProviderDisableController' => 'PhortuneMerchantController',
     'PhortuneProviderEditController' => 'PhortuneMerchantController',
     'PhortunePurchase' => array(
       'PhortuneDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhortunePurchasePHIDType' => 'PhabricatorPHIDType',
     'PhortunePurchaseQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhortuneSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhortuneStripePaymentProvider' => 'PhortunePaymentProvider',
     'PhortuneTestPaymentProvider' => 'PhortunePaymentProvider',
     'PhortuneWePayPaymentProvider' => 'PhortunePaymentProvider',
     'PhragmentBrowseController' => 'PhragmentController',
     'PhragmentCanCreateCapability' => 'PhabricatorPolicyCapability',
     'PhragmentConduitAPIMethod' => 'ConduitAPIMethod',
     'PhragmentController' => 'PhabricatorController',
     'PhragmentCreateController' => 'PhragmentController',
     'PhragmentDAO' => 'PhabricatorLiskDAO',
     'PhragmentFragment' => array(
       'PhragmentDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhragmentFragmentPHIDType' => 'PhabricatorPHIDType',
     'PhragmentFragmentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhragmentFragmentVersion' => array(
       'PhragmentDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhragmentFragmentVersionPHIDType' => 'PhabricatorPHIDType',
     'PhragmentFragmentVersionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhragmentGetPatchConduitAPIMethod' => 'PhragmentConduitAPIMethod',
     'PhragmentHistoryController' => 'PhragmentController',
     'PhragmentPatchController' => 'PhragmentController',
     'PhragmentPatchUtil' => 'Phobject',
     'PhragmentPolicyController' => 'PhragmentController',
     'PhragmentQueryFragmentsConduitAPIMethod' => 'PhragmentConduitAPIMethod',
     'PhragmentRevertController' => 'PhragmentController',
     'PhragmentSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhragmentSnapshot' => array(
       'PhragmentDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhragmentSnapshotChild' => array(
       'PhragmentDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhragmentSnapshotChildQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhragmentSnapshotCreateController' => 'PhragmentController',
     'PhragmentSnapshotDeleteController' => 'PhragmentController',
     'PhragmentSnapshotPHIDType' => 'PhabricatorPHIDType',
     'PhragmentSnapshotPromoteController' => 'PhragmentController',
     'PhragmentSnapshotQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhragmentSnapshotViewController' => 'PhragmentController',
     'PhragmentUpdateController' => 'PhragmentController',
     'PhragmentVersionController' => 'PhragmentController',
     'PhragmentZIPController' => 'PhragmentController',
     'PhrequentConduitAPIMethod' => 'ConduitAPIMethod',
     'PhrequentController' => 'PhabricatorController',
     'PhrequentDAO' => 'PhabricatorLiskDAO',
     'PhrequentListController' => 'PhrequentController',
     'PhrequentPopConduitAPIMethod' => 'PhrequentConduitAPIMethod',
     'PhrequentPushConduitAPIMethod' => 'PhrequentConduitAPIMethod',
     'PhrequentSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhrequentTimeBlock' => 'Phobject',
     'PhrequentTimeBlockTestCase' => 'PhabricatorTestCase',
     'PhrequentTimeSlices' => 'Phobject',
     'PhrequentTrackController' => 'PhrequentController',
     'PhrequentTrackingConduitAPIMethod' => 'PhrequentConduitAPIMethod',
     'PhrequentTrackingEditor' => 'PhabricatorEditor',
     'PhrequentUIEventListener' => 'PhabricatorEventListener',
     'PhrequentUserTime' => array(
       'PhrequentDAO',
       'PhabricatorPolicyInterface',
     ),
     'PhrequentUserTimeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhrictionActionConstants' => 'PhrictionConstants',
     'PhrictionChangeType' => 'PhrictionConstants',
     'PhrictionConduitAPIMethod' => 'ConduitAPIMethod',
     'PhrictionContent' => array(
       'PhrictionDAO',
       'PhabricatorMarkupInterface',
     ),
     'PhrictionController' => 'PhabricatorController',
     'PhrictionCreateConduitAPIMethod' => 'PhrictionConduitAPIMethod',
     'PhrictionDAO' => 'PhabricatorLiskDAO',
     'PhrictionDeleteController' => 'PhrictionController',
     'PhrictionDiffController' => 'PhrictionController',
     'PhrictionDocument' => array(
       'PhrictionDAO',
       'PhabricatorPolicyInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorDestructibleInterface',
       'PhabricatorApplicationTransactionInterface',
     ),
     'PhrictionDocumentController' => 'PhrictionController',
     'PhrictionDocumentHeraldAdapter' => 'HeraldAdapter',
     'PhrictionDocumentPHIDType' => 'PhabricatorPHIDType',
     'PhrictionDocumentPreviewController' => 'PhrictionController',
     'PhrictionDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhrictionDocumentStatus' => 'PhrictionConstants',
     'PhrictionEditConduitAPIMethod' => 'PhrictionConduitAPIMethod',
     'PhrictionEditController' => 'PhrictionController',
     'PhrictionHistoryConduitAPIMethod' => 'PhrictionConduitAPIMethod',
     'PhrictionHistoryController' => 'PhrictionController',
     'PhrictionInfoConduitAPIMethod' => 'PhrictionConduitAPIMethod',
     'PhrictionListController' => 'PhrictionController',
     'PhrictionMoveController' => 'PhrictionController',
     'PhrictionNewController' => 'PhrictionController',
     'PhrictionRemarkupRule' => 'PhutilRemarkupRule',
     'PhrictionReplyHandler' => 'PhabricatorMailReplyHandler',
     'PhrictionSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PhrictionSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PhrictionSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PhrictionTransaction' => 'PhabricatorApplicationTransaction',
     'PhrictionTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PhrictionTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhrictionTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PonderAddAnswerView' => 'AphrontView',
     'PonderAnswer' => array(
       'PonderDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorMarkupInterface',
       'PonderVotableInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PonderAnswerCommentController' => 'PonderController',
     'PonderAnswerEditController' => 'PonderController',
     'PonderAnswerEditor' => 'PonderEditor',
     'PonderAnswerHistoryController' => 'PonderController',
     'PonderAnswerPHIDType' => 'PhabricatorPHIDType',
     'PonderAnswerQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PonderAnswerSaveController' => 'PonderController',
     'PonderAnswerTransaction' => 'PhabricatorApplicationTransaction',
     'PonderAnswerTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PonderAnswerTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PonderController' => 'PhabricatorController',
     'PonderDAO' => 'PhabricatorLiskDAO',
     'PonderEditor' => 'PhabricatorApplicationTransactionEditor',
     'PonderQuestion' => array(
       'PonderDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorMarkupInterface',
       'PonderVotableInterface',
       'PhabricatorSubscribableInterface',
       'PhabricatorFlaggableInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorTokenReceiverInterface',
       'PhabricatorProjectInterface',
       'PhabricatorDestructibleInterface',
     ),
     'PonderQuestionCommentController' => 'PonderController',
     'PonderQuestionEditController' => 'PonderController',
     'PonderQuestionEditor' => 'PonderEditor',
     'PonderQuestionHistoryController' => 'PonderController',
     'PonderQuestionListController' => 'PonderController',
     'PonderQuestionMailReceiver' => 'PhabricatorObjectMailReceiver',
     'PonderQuestionPHIDType' => 'PhabricatorPHIDType',
     'PonderQuestionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PonderQuestionReplyHandler' => 'PhabricatorMailReplyHandler',
     'PonderQuestionSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'PonderQuestionStatus' => 'PonderConstants',
     'PonderQuestionStatusController' => 'PonderController',
     'PonderQuestionTransaction' => 'PhabricatorApplicationTransaction',
     'PonderQuestionTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PonderQuestionTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PonderQuestionViewController' => 'PonderController',
     'PonderRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'PonderSchemaSpec' => 'PhabricatorConfigSchemaSpec',
     'PonderSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PonderTransactionFeedStory' => 'PhabricatorApplicationTransactionFeedStory',
     'PonderVotableView' => 'AphrontView',
     'PonderVote' => 'PonderConstants',
     'PonderVoteEditor' => 'PhabricatorEditor',
     'PonderVoteSaveController' => 'PonderController',
     'ProjectCanLockProjectsCapability' => 'PhabricatorPolicyCapability',
     'ProjectConduitAPIMethod' => 'ConduitAPIMethod',
     'ProjectCreateConduitAPIMethod' => 'ProjectConduitAPIMethod',
     'ProjectCreateProjectsCapability' => 'PhabricatorPolicyCapability',
     'ProjectDefaultEditCapability' => 'PhabricatorPolicyCapability',
     'ProjectDefaultJoinCapability' => 'PhabricatorPolicyCapability',
     'ProjectDefaultViewCapability' => 'PhabricatorPolicyCapability',
     'ProjectQueryConduitAPIMethod' => 'ProjectConduitAPIMethod',
     'ProjectRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'ProjectRemarkupRuleTestCase' => 'PhabricatorTestCase',
     'QueryFormattingTestCase' => 'PhabricatorTestCase',
     'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephBranch' => array(
       'ReleephDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'ReleephBranchAccessController' => 'ReleephBranchController',
     'ReleephBranchCommitFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephBranchController' => 'ReleephController',
     'ReleephBranchCreateController' => 'ReleephProductController',
     'ReleephBranchEditController' => 'ReleephBranchController',
     'ReleephBranchEditor' => 'PhabricatorEditor',
     'ReleephBranchHistoryController' => 'ReleephBranchController',
     'ReleephBranchNamePreviewController' => 'ReleephController',
     'ReleephBranchPHIDType' => 'PhabricatorPHIDType',
     'ReleephBranchPreviewView' => 'AphrontFormControl',
     'ReleephBranchQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'ReleephBranchSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'ReleephBranchTransaction' => 'PhabricatorApplicationTransaction',
     'ReleephBranchTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'ReleephBranchViewController' => array(
       'ReleephBranchController',
       'PhabricatorApplicationSearchResultsControllerInterface',
     ),
     'ReleephCommitFinderException' => 'Exception',
     'ReleephCommitMessageFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephConduitAPIMethod' => 'ConduitAPIMethod',
     'ReleephController' => 'PhabricatorController',
     'ReleephDAO' => 'PhabricatorLiskDAO',
     'ReleephDefaultFieldSelector' => 'ReleephFieldSelector',
     'ReleephDependsOnFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephDiffChurnFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephDiffMessageFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephDiffSizeFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephFieldParseException' => 'Exception',
     'ReleephFieldSpecification' => array(
       'PhabricatorCustomField',
       'PhabricatorMarkupInterface',
     ),
     'ReleephGetBranchesConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephIntentFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephLevelFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephOriginalCommitFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephProductActionController' => 'ReleephProductController',
     'ReleephProductController' => 'ReleephController',
     'ReleephProductCreateController' => 'ReleephProductController',
     'ReleephProductEditController' => 'ReleephProductController',
     'ReleephProductEditor' => 'PhabricatorApplicationTransactionEditor',
     'ReleephProductHistoryController' => 'ReleephProductController',
     'ReleephProductListController' => 'ReleephController',
     'ReleephProductPHIDType' => 'PhabricatorPHIDType',
     'ReleephProductQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'ReleephProductSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'ReleephProductTransaction' => 'PhabricatorApplicationTransaction',
     'ReleephProductTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'ReleephProductViewController' => array(
       'ReleephProductController',
       'PhabricatorApplicationSearchResultsControllerInterface',
     ),
     'ReleephProject' => array(
       'ReleephDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
     ),
     'ReleephProjectInfoConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephQueryBranchesConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephQueryProductsConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephQueryRequestsConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephReasonFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephRequest' => array(
       'ReleephDAO',
+      'PhabricatorApplicationTransactionInterface',
       'PhabricatorPolicyInterface',
       'PhabricatorCustomFieldInterface',
     ),
     'ReleephRequestActionController' => 'ReleephRequestController',
     'ReleephRequestCommentController' => 'ReleephRequestController',
     'ReleephRequestConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephRequestController' => 'ReleephController',
     'ReleephRequestDifferentialCreateController' => 'ReleephController',
     'ReleephRequestEditController' => 'ReleephBranchController',
     'ReleephRequestMailReceiver' => 'PhabricatorObjectMailReceiver',
     'ReleephRequestPHIDType' => 'PhabricatorPHIDType',
     'ReleephRequestQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'ReleephRequestReplyHandler' => 'PhabricatorMailReplyHandler',
     'ReleephRequestSearchEngine' => 'PhabricatorApplicationSearchEngine',
     'ReleephRequestTransaction' => 'PhabricatorApplicationTransaction',
     'ReleephRequestTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'ReleephRequestTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'ReleephRequestTransactionalEditor' => 'PhabricatorApplicationTransactionEditor',
     'ReleephRequestTypeaheadControl' => 'AphrontFormControl',
     'ReleephRequestTypeaheadController' => 'PhabricatorTypeaheadDatasourceController',
     'ReleephRequestView' => 'AphrontView',
     'ReleephRequestViewController' => 'ReleephBranchController',
     'ReleephRequestorFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephRevisionFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephSeverityFieldSpecification' => 'ReleephLevelFieldSpecification',
     'ReleephSummaryFieldSpecification' => 'ReleephFieldSpecification',
     'ReleephWorkCanPushConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephWorkGetAuthorInfoConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephWorkGetBranchCommitMessageConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephWorkGetBranchConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephWorkGetCommitMessageConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephWorkNextRequestConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephWorkRecordConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'ReleephWorkRecordPickStatusConduitAPIMethod' => 'ReleephConduitAPIMethod',
     'RemarkupProcessConduitAPIMethod' => 'ConduitAPIMethod',
     'RepositoryConduitAPIMethod' => 'ConduitAPIMethod',
     'RepositoryCreateConduitAPIMethod' => 'RepositoryConduitAPIMethod',
     'RepositoryQueryConduitAPIMethod' => 'RepositoryConduitAPIMethod',
     'ShellLogView' => 'AphrontView',
     'SlowvoteConduitAPIMethod' => 'ConduitAPIMethod',
     'SlowvoteEmbedView' => 'AphrontView',
     'SlowvoteInfoConduitAPIMethod' => 'SlowvoteConduitAPIMethod',
     'SlowvoteRemarkupRule' => 'PhabricatorObjectRemarkupRule',
     'TokenConduitAPIMethod' => 'ConduitAPIMethod',
     'TokenGiveConduitAPIMethod' => 'TokenConduitAPIMethod',
     'TokenGivenConduitAPIMethod' => 'TokenConduitAPIMethod',
     'TokenQueryConduitAPIMethod' => 'TokenConduitAPIMethod',
     'UserAddStatusConduitAPIMethod' => 'UserConduitAPIMethod',
     'UserConduitAPIMethod' => 'ConduitAPIMethod',
     'UserDisableConduitAPIMethod' => 'UserConduitAPIMethod',
     'UserEnableConduitAPIMethod' => 'UserConduitAPIMethod',
     'UserFindConduitAPIMethod' => 'UserConduitAPIMethod',
     'UserInfoConduitAPIMethod' => 'UserConduitAPIMethod',
     'UserQueryConduitAPIMethod' => 'UserConduitAPIMethod',
     'UserRemoveStatusConduitAPIMethod' => 'UserConduitAPIMethod',
     'UserWhoAmIConduitAPIMethod' => 'UserConduitAPIMethod',
   ),
 ));
diff --git a/src/applications/audit/storage/PhabricatorAuditTransaction.php b/src/applications/audit/storage/PhabricatorAuditTransaction.php
index 2932364350..01b947da6d 100644
--- a/src/applications/audit/storage/PhabricatorAuditTransaction.php
+++ b/src/applications/audit/storage/PhabricatorAuditTransaction.php
@@ -1,468 +1,472 @@
 <?php
 
 final class PhabricatorAuditTransaction
   extends PhabricatorApplicationTransaction {
 
   const TYPE_COMMIT = 'audit:commit';
 
   const MAILTAG_ACTION_CONCERN = 'audit-action-concern';
   const MAILTAG_ACTION_ACCEPT  = 'audit-action-accept';
   const MAILTAG_ACTION_RESIGN  = 'audit-action-resign';
   const MAILTAG_ACTION_CLOSE   = 'audit-action-close';
   const MAILTAG_ADD_AUDITORS   = 'audit-add-auditors';
   const MAILTAG_ADD_CCS        = 'audit-add-ccs';
   const MAILTAG_COMMENT        = 'audit-comment';
   const MAILTAG_COMMIT         = 'audit-commit';
   const MAILTAG_PROJECTS       = 'audit-projects';
   const MAILTAG_OTHER          = 'audit-other';
 
   public function getApplicationName() {
     return 'audit';
   }
 
   public function getApplicationTransactionType() {
     return PhabricatorRepositoryCommitPHIDType::TYPECONST;
   }
 
   public function getApplicationTransactionCommentObject() {
     return new PhabricatorAuditTransactionComment();
   }
 
+  public function getApplicationTransactionViewObject() {
+    return new PhabricatorAuditTransactionView();
+  }
+
   public function getRemarkupBlocks() {
     $blocks = parent::getRemarkupBlocks();
 
     switch ($this->getTransactionType()) {
     case self::TYPE_COMMIT:
       $data = $this->getNewValue();
       $blocks[] = $data['description'];
       break;
     }
 
     return $blocks;
   }
 
   public function getRequiredHandlePHIDs() {
     $phids = parent::getRequiredHandlePHIDs();
 
     $type = $this->getTransactionType();
 
     switch ($type) {
       case self::TYPE_COMMIT:
         $phids[] = $this->getObjectPHID();
         $data = $this->getNewValue();
         if ($data['authorPHID']) {
           $phids[] = $data['authorPHID'];
         }
         if ($data['committerPHID']) {
           $phids[] = $data['committerPHID'];
         }
         break;
       case PhabricatorAuditActionConstants::ADD_CCS:
       case PhabricatorAuditActionConstants::ADD_AUDITORS:
         $old = $this->getOldValue();
         $new = $this->getNewValue();
 
         if (!is_array($old)) {
           $old = array();
         }
         if (!is_array($new)) {
           $new = array();
         }
 
         foreach (array_keys($old + $new) as $phid) {
           $phids[] = $phid;
         }
         break;
     }
 
     return $phids;
   }
 
   public function getActionName() {
 
     switch ($this->getTransactionType()) {
       case PhabricatorAuditActionConstants::ACTION:
         switch ($this->getNewValue()) {
           case PhabricatorAuditActionConstants::CONCERN:
             return pht('Raised Concern');
           case PhabricatorAuditActionConstants::ACCEPT:
             return pht('Accepted');
           case PhabricatorAuditActionConstants::RESIGN:
             return pht('Resigned');
           case PhabricatorAuditActionConstants::CLOSE:
             return pht('Closed');
         }
         break;
       case PhabricatorAuditActionConstants::ADD_AUDITORS:
         return pht('Added Auditors');
       case self::TYPE_COMMIT:
         return pht('Committed');
     }
 
     return parent::getActionName();
   }
 
   public function getColor() {
 
     $type = $this->getTransactionType();
 
     switch ($type) {
       case PhabricatorAuditActionConstants::ACTION:
         switch ($this->getNewValue()) {
           case PhabricatorAuditActionConstants::CONCERN:
             return 'red';
           case PhabricatorAuditActionConstants::ACCEPT:
             return 'green';
         }
     }
 
     return parent::getColor();
   }
 
   public function getTitle() {
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     $author_handle = $this->renderHandleLink($this->getAuthorPHID());
 
     $type = $this->getTransactionType();
 
     switch ($type) {
       case PhabricatorAuditActionConstants::ADD_CCS:
       case PhabricatorAuditActionConstants::ADD_AUDITORS:
         if (!is_array($old)) {
           $old = array();
         }
         if (!is_array($new)) {
           $new = array();
         }
         $add = array_keys(array_diff_key($new, $old));
         $rem = array_keys(array_diff_key($old, $new));
         break;
     }
 
     switch ($type) {
       case self::TYPE_COMMIT:
         $author = null;
         if ($new['authorPHID']) {
           $author = $this->renderHandleLink($new['authorPHID']);
         } else {
           $author = $new['authorName'];
         }
 
         $committer = null;
         if ($new['committerPHID']) {
           $committer = $this->renderHandleLink($new['committerPHID']);
         } else if ($new['committerName']) {
           $committer = $new['committerName'];
         }
 
         $commit = $this->renderHandleLink($this->getObjectPHID());
 
         if (!$committer) {
           $committer = $author;
           $author = null;
         }
 
         if ($author) {
           $title = pht(
             '%s committed %s (authored by %s).',
             $committer,
             $commit,
             $author);
         } else {
           $title = pht(
             '%s committed %s.',
             $committer,
             $commit);
         }
         return $title;
 
       case PhabricatorAuditActionConstants::INLINE:
         return pht(
           '%s added inline comments.',
           $author_handle);
 
       case PhabricatorAuditActionConstants::ADD_CCS:
         if ($add && $rem) {
           return pht(
             '%s edited subscribers; added: %s, removed: %s.',
             $author_handle,
             $this->renderHandleList($add),
             $this->renderHandleList($rem));
         } else if ($add) {
           return pht(
             '%s added subscribers: %s.',
             $author_handle,
             $this->renderHandleList($add));
         } else if ($rem) {
           return pht(
             '%s removed subscribers: %s.',
             $author_handle,
             $this->renderHandleList($rem));
         } else {
           return pht(
             '%s added subscribers...',
             $author_handle);
         }
 
       case PhabricatorAuditActionConstants::ADD_AUDITORS:
         if ($add && $rem) {
           return pht(
             '%s edited auditors; added: %s, removed: %s.',
             $author_handle,
             $this->renderHandleList($add),
             $this->renderHandleList($rem));
         } else if ($add) {
           return pht(
             '%s added auditors: %s.',
             $author_handle,
             $this->renderHandleList($add));
         } else if ($rem) {
           return pht(
             '%s removed auditors: %s.',
             $author_handle,
             $this->renderHandleList($rem));
         } else {
           return pht(
             '%s added auditors...',
             $author_handle);
         }
 
       case PhabricatorAuditActionConstants::ACTION:
         switch ($new) {
           case PhabricatorAuditActionConstants::ACCEPT:
             return pht(
               '%s accepted this commit.',
               $author_handle);
           case PhabricatorAuditActionConstants::CONCERN:
             return pht(
               '%s raised a concern with this commit.',
               $author_handle);
           case PhabricatorAuditActionConstants::RESIGN:
             return pht(
               '%s resigned from this audit.',
               $author_handle);
           case PhabricatorAuditActionConstants::CLOSE:
             return pht(
               '%s closed this audit.',
               $author_handle);
         }
 
     }
 
     return parent::getTitle();
   }
 
   public function getTitleForFeed(PhabricatorFeedStory $story) {
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     $author_handle = $this->renderHandleLink($this->getAuthorPHID());
     $object_handle = $this->renderHandleLink($this->getObjectPHID());
 
     $type = $this->getTransactionType();
 
     switch ($type) {
       case PhabricatorAuditActionConstants::ADD_CCS:
       case PhabricatorAuditActionConstants::ADD_AUDITORS:
         if (!is_array($old)) {
           $old = array();
         }
         if (!is_array($new)) {
           $new = array();
         }
         $add = array_keys(array_diff_key($new, $old));
         $rem = array_keys(array_diff_key($old, $new));
         break;
     }
 
     switch ($type) {
       case self::TYPE_COMMIT:
         $author = null;
         if ($new['authorPHID']) {
           $author = $this->renderHandleLink($new['authorPHID']);
         } else {
           $author = $new['authorName'];
         }
 
         $committer = null;
         if ($new['committerPHID']) {
           $committer = $this->renderHandleLink($new['committerPHID']);
         } else if ($new['committerName']) {
           $committer = $new['committerName'];
         }
 
         if (!$committer) {
           $committer = $author;
           $author = null;
         }
 
         if ($author) {
           $title = pht(
             '%s committed %s (authored by %s).',
             $committer,
             $object_handle,
             $author);
         } else {
           $title = pht(
             '%s committed %s.',
             $committer,
             $object_handle);
         }
         return $title;
 
       case PhabricatorAuditActionConstants::INLINE:
         return pht(
           '%s added inline comments to %s.',
           $author_handle,
           $object_handle);
 
       case PhabricatorAuditActionConstants::ADD_AUDITORS:
         if ($add && $rem) {
           return pht(
             '%s edited auditors for %s; added: %s, removed: %s.',
             $author_handle,
             $object_handle,
             $this->renderHandleList($add),
             $this->renderHandleList($rem));
         } else if ($add) {
           return pht(
             '%s added auditors to %s: %s.',
             $author_handle,
             $object_handle,
             $this->renderHandleList($add));
         } else if ($rem) {
           return pht(
             '%s removed auditors from %s: %s.',
             $author_handle,
             $object_handle,
             $this->renderHandleList($rem));
         } else {
           return pht(
             '%s added auditors to %s...',
             $author_handle,
             $object_handle);
         }
 
       case PhabricatorAuditActionConstants::ACTION:
         switch ($new) {
           case PhabricatorAuditActionConstants::ACCEPT:
             return pht(
               '%s accepted %s.',
               $author_handle,
               $object_handle);
           case PhabricatorAuditActionConstants::CONCERN:
             return pht(
               '%s raised a concern with %s.',
               $author_handle,
               $object_handle);
           case PhabricatorAuditActionConstants::RESIGN:
             return pht(
               '%s resigned from auditing %s.',
               $author_handle,
               $object_handle);
           case PhabricatorAuditActionConstants::CLOSE:
             return pht(
               '%s closed the audit of %s.',
               $author_handle,
               $object_handle);
         }
 
     }
 
     return parent::getTitleForFeed($story);
   }
 
   public function getBodyForFeed(PhabricatorFeedStory $story) {
     switch ($this->getTransactionType()) {
       case self::TYPE_COMMIT:
         $data = $this->getNewValue();
         return $story->renderSummary($data['summary']);
     }
     return parent::getBodyForFeed($story);
   }
 
 
   // TODO: These two mail methods can likely be abstracted by introducing a
   // formal concept of "inline comment" transactions.
 
   public function shouldHideForMail(array $xactions) {
     $type_inline = PhabricatorAuditActionConstants::INLINE;
     switch ($this->getTransactionType()) {
       case $type_inline:
         foreach ($xactions as $xaction) {
           if ($xaction->getTransactionType() != $type_inline) {
             return true;
           }
         }
         return ($this !== head($xactions));
     }
 
     return parent::shouldHideForMail($xactions);
   }
 
   public function getBodyForMail() {
     switch ($this->getTransactionType()) {
       case PhabricatorAuditActionConstants::INLINE:
         return null;
       case self::TYPE_COMMIT:
         $data = $this->getNewValue();
         return $data['description'];
     }
 
     return parent::getBodyForMail();
   }
 
   public function getMailTags() {
     $tags = array();
     switch ($this->getTransactionType()) {
       case PhabricatorAuditActionConstants::ACTION:
         switch ($this->getNewValue()) {
           case PhabricatorAuditActionConstants::CONCERN:
             $tags[] = self::MAILTAG_ACTION_CONCERN;
             break;
           case PhabricatorAuditActionConstants::ACCEPT:
             $tags[] = self::MAILTAG_ACTION_ACCEPT;
             break;
           case PhabricatorAuditActionConstants::RESIGN:
             $tags[] = self::MAILTAG_ACTION_RESIGN;
             break;
           case PhabricatorAuditActionConstants::CLOSE:
             $tags[] = self::MAILTAG_ACTION_CLOSE;
             break;
         }
         break;
       case PhabricatorAuditActionConstants::ADD_AUDITORS:
         $tags[] = self::MAILTAG_ADD_AUDITORS;
         break;
       case PhabricatorAuditActionConstants::ADD_CCS:
         $tags[] = self::MAILTAG_ADD_CCS;
         break;
       case PhabricatorAuditActionConstants::INLINE:
       case PhabricatorTransactions::TYPE_COMMENT:
         $tags[] = self::MAILTAG_COMMENT;
         break;
       case self::TYPE_COMMIT:
         $tags[] = self::MAILTAG_COMMIT;
         break;
       case PhabricatorTransactions::TYPE_EDGE:
         switch ($this->getMetadataValue('edge:type')) {
           case PhabricatorProjectObjectHasProjectEdgeType::EDGECONST:
             $tags[] = self::MAILTAG_PROJECTS;
             break;
           case PhabricatorEdgeConfig::TYPE_OBJECT_HAS_SUBSCRIBER:
             $tags[] = self::MAILTAG_ADD_CCS;
             break;
           default:
             $tags[] = self::MAILTAG_OTHER;
             break;
         }
         break;
       default:
         $tags[] = self::MAILTAG_OTHER;
         break;
     }
     return $tags;
   }
 }
diff --git a/src/applications/differential/controller/DifferentialRevisionViewController.php b/src/applications/differential/controller/DifferentialRevisionViewController.php
index e2afe57248..85faa55ce7 100644
--- a/src/applications/differential/controller/DifferentialRevisionViewController.php
+++ b/src/applications/differential/controller/DifferentialRevisionViewController.php
@@ -1,968 +1,960 @@
 <?php
 
 final class DifferentialRevisionViewController extends DifferentialController {
 
   private $revisionID;
 
   public function shouldAllowPublic() {
     return true;
   }
 
   public function willProcessRequest(array $data) {
     $this->revisionID = $data['id'];
   }
 
   public function processRequest() {
 
     $request = $this->getRequest();
     $user = $request->getUser();
     $viewer_is_anonymous = !$user->isLoggedIn();
 
     $revision = id(new DifferentialRevisionQuery())
       ->withIDs(array($this->revisionID))
       ->setViewer($request->getUser())
       ->needRelationships(true)
       ->needReviewerStatus(true)
       ->needReviewerAuthority(true)
       ->executeOne();
 
     if (!$revision) {
       return new Aphront404Response();
     }
 
     $diffs = id(new DifferentialDiffQuery())
       ->setViewer($request->getUser())
       ->withRevisionIDs(array($this->revisionID))
       ->needArcanistProjects(true)
       ->execute();
     $diffs = array_reverse($diffs, $preserve_keys = true);
 
     if (!$diffs) {
       throw new Exception(
         'This revision has no diffs. Something has gone quite wrong.');
     }
 
     $revision->attachActiveDiff(last($diffs));
 
     $diff_vs = $request->getInt('vs');
 
     $target_id = $request->getInt('id');
     $target = idx($diffs, $target_id, end($diffs));
 
     $target_manual = $target;
     if (!$target_id) {
       foreach ($diffs as $diff) {
         if ($diff->getCreationMethod() != 'commit') {
           $target_manual = $diff;
         }
       }
     }
 
     if (empty($diffs[$diff_vs])) {
       $diff_vs = null;
     }
 
     $repository = null;
     $repository_phid = $target->getRepositoryPHID();
     if ($repository_phid) {
       if ($repository_phid == $revision->getRepositoryPHID()) {
         $repository = $revision->getRepository();
       } else {
         $repository = id(new PhabricatorRepositoryQuery())
           ->setViewer($user)
           ->withPHIDs(array($repository_phid))
           ->executeOne();
       }
     }
 
     list($changesets, $vs_map, $vs_changesets, $rendering_references) =
       $this->loadChangesetsAndVsMap(
         $target,
         idx($diffs, $diff_vs),
         $repository);
 
     if ($request->getExists('download')) {
       return $this->buildRawDiffResponse(
         $revision,
         $changesets,
         $vs_changesets,
         $vs_map,
         $repository);
     }
 
     $props = id(new DifferentialDiffProperty())->loadAllWhere(
       'diffID = %d',
       $target_manual->getID());
     $props = mpull($props, 'getData', 'getName');
 
     $all_changesets = $changesets;
     $inlines = $this->loadInlineComments(
       $revision,
       $all_changesets);
 
     $object_phids = array_merge(
       $revision->getReviewers(),
       $revision->getCCPHIDs(),
       $revision->loadCommitPHIDs(),
       array(
         $revision->getAuthorPHID(),
         $user->getPHID(),
       ));
 
     foreach ($revision->getAttached() as $type => $phids) {
       foreach ($phids as $phid => $info) {
         $object_phids[] = $phid;
       }
     }
 
     $field_list = PhabricatorCustomField::getObjectFields(
       $revision,
       PhabricatorCustomField::ROLE_VIEW);
 
     $field_list->setViewer($user);
     $field_list->readFieldsFromStorage($revision);
 
     $warning_handle_map = array();
     foreach ($field_list->getFields() as $key => $field) {
       $req = $field->getRequiredHandlePHIDsForRevisionHeaderWarnings();
       foreach ($req as $phid) {
         $warning_handle_map[$key][] = $phid;
         $object_phids[] = $phid;
       }
     }
 
     $handles = $this->loadViewerHandles($object_phids);
 
     $request_uri = $request->getRequestURI();
 
     $limit = 100;
     $large = $request->getStr('large');
     if (count($changesets) > $limit && !$large) {
       $count = count($changesets);
       $warning = new AphrontErrorView();
       $warning->setTitle('Very Large Diff');
       $warning->setSeverity(AphrontErrorView::SEVERITY_WARNING);
       $warning->appendChild(hsprintf(
         '%s <strong>%s</strong>',
         pht(
           'This diff is very large and affects %s files. '.
           'You may load each file individually or ',
           new PhutilNumber($count)),
         phutil_tag(
           'a',
           array(
             'class' => 'button grey',
             'href' => $request_uri
               ->alter('large', 'true')
               ->setFragment('toc'),
           ),
           pht('Show All Files Inline'))));
       $warning = $warning->render();
 
       $my_inlines = id(new DifferentialInlineCommentQuery())
         ->withDraftComments($user->getPHID(), $this->revisionID)
         ->execute();
 
       $visible_changesets = array();
       foreach ($inlines + $my_inlines as $inline) {
         $changeset_id = $inline->getChangesetID();
         if (isset($changesets[$changeset_id])) {
           $visible_changesets[$changeset_id] = $changesets[$changeset_id];
         }
       }
 
       if (!empty($props['arc:lint'])) {
         $changeset_paths = mpull($changesets, null, 'getFilename');
         foreach ($props['arc:lint'] as $lint) {
           $changeset = idx($changeset_paths, $lint['path']);
           if ($changeset) {
             $visible_changesets[$changeset->getID()] = $changeset;
           }
         }
       }
     } else {
       $warning = null;
       $visible_changesets = $changesets;
     }
 
 
     // TODO: This should be in a DiffQuery or similar.
     $need_props = array();
     foreach ($field_list->getFields() as $field) {
       foreach ($field->getRequiredDiffPropertiesForRevisionView() as $prop) {
         $need_props[$prop] = $prop;
       }
     }
 
     if ($need_props) {
       $prop_diff = $revision->getActiveDiff();
       $load_props = id(new DifferentialDiffProperty())->loadAllWhere(
         'diffID = %d AND name IN (%Ls)',
         $prop_diff->getID(),
         $need_props);
       $load_props = mpull($load_props, 'getData', 'getName');
       foreach ($need_props as $need) {
         $prop_diff->attachProperty($need, idx($load_props, $need));
       }
     }
 
     $commit_hashes = mpull($diffs, 'getSourceControlBaseRevision');
     $local_commits = idx($props, 'local:commits', array());
     foreach ($local_commits as $local_commit) {
       $commit_hashes[] = idx($local_commit, 'tree');
       $commit_hashes[] = idx($local_commit, 'local');
     }
     $commit_hashes = array_unique(array_filter($commit_hashes));
     if ($commit_hashes) {
       $commits_for_links = id(new DiffusionCommitQuery())
         ->setViewer($user)
         ->withIdentifiers($commit_hashes)
         ->execute();
       $commits_for_links = mpull(
         $commits_for_links,
         null,
         'getCommitIdentifier');
     } else {
       $commits_for_links = array();
     }
 
     $revision_detail = id(new DifferentialRevisionDetailView())
       ->setUser($user)
       ->setRevision($revision)
       ->setDiff(end($diffs))
       ->setCustomFields($field_list)
       ->setURI($request->getRequestURI());
 
     $actions = $this->getRevisionActions($revision);
 
     $whitespace = $request->getStr(
       'whitespace',
       DifferentialChangesetParser::WHITESPACE_IGNORE_ALL);
 
     $arc_project = $target->getArcanistProject();
     if ($arc_project) {
       list($symbol_indexes, $project_phids) = $this->buildSymbolIndexes(
         $arc_project,
         $visible_changesets);
     } else {
       $symbol_indexes = array();
       $project_phids = null;
     }
 
     $revision_detail->setActions($actions);
     $revision_detail->setUser($user);
 
     $revision_detail_box = $revision_detail->render();
 
     $revision_warnings = $this->buildRevisionWarnings(
       $revision,
       $field_list,
       $warning_handle_map,
       $handles);
     if ($revision_warnings) {
       $revision_warnings = id(new AphrontErrorView())
         ->setSeverity(AphrontErrorView::SEVERITY_WARNING)
         ->setErrors($revision_warnings);
       $revision_detail_box->setErrorView($revision_warnings);
     }
 
     $comment_view = $this->buildTransactions(
       $revision,
       $diff_vs ? $diffs[$diff_vs] : $target,
       $target,
       $all_changesets);
 
     if (!$viewer_is_anonymous) {
       $comment_view->setQuoteRef('D'.$revision->getID());
       $comment_view->setQuoteTargetID('comment-content');
     }
 
     $wrap_id = celerity_generate_unique_node_id();
     $comment_view = phutil_tag(
       'div',
       array(
         'id' => $wrap_id,
       ),
       $comment_view);
 
     if ($arc_project) {
       Javelin::initBehavior(
         'repository-crossreference',
         array(
           'section' => $wrap_id,
           'projects' => $project_phids,
         ));
     }
 
     $changeset_view = new DifferentialChangesetListView();
     $changeset_view->setChangesets($changesets);
     $changeset_view->setVisibleChangesets($visible_changesets);
 
     if (!$viewer_is_anonymous) {
       $changeset_view->setInlineCommentControllerURI(
         '/differential/comment/inline/edit/'.$revision->getID().'/');
     }
 
     $changeset_view->setStandaloneURI('/differential/changeset/');
     $changeset_view->setRawFileURIs(
       '/differential/changeset/?view=old',
       '/differential/changeset/?view=new');
 
     $changeset_view->setUser($user);
     $changeset_view->setDiff($target);
     $changeset_view->setRenderingReferences($rendering_references);
     $changeset_view->setVsMap($vs_map);
     $changeset_view->setWhitespace($whitespace);
     if ($repository) {
       $changeset_view->setRepository($repository);
     }
     $changeset_view->setSymbolIndexes($symbol_indexes);
     $changeset_view->setTitle('Diff '.$target->getID());
 
     $diff_history = id(new DifferentialRevisionUpdateHistoryView())
       ->setUser($user)
       ->setDiffs($diffs)
       ->setSelectedVersusDiffID($diff_vs)
       ->setSelectedDiffID($target->getID())
       ->setSelectedWhitespace($whitespace)
       ->setCommitsForLinks($commits_for_links);
 
     $local_view = id(new DifferentialLocalCommitsView())
       ->setUser($user)
       ->setLocalCommits(idx($props, 'local:commits'))
       ->setCommitsForLinks($commits_for_links);
 
     if ($repository) {
       $other_revisions = $this->loadOtherRevisions(
         $changesets,
         $target,
         $repository);
     } else {
       $other_revisions = array();
     }
 
     $other_view = null;
     if ($other_revisions) {
       $other_view = $this->renderOtherRevisions($other_revisions);
     }
 
     $toc_view = new DifferentialDiffTableOfContentsView();
     $toc_view->setChangesets($changesets);
     $toc_view->setVisibleChangesets($visible_changesets);
     $toc_view->setRenderingReferences($rendering_references);
     $toc_view->setUnitTestData(idx($props, 'arc:unit', array()));
     if ($repository) {
       $toc_view->setRepository($repository);
     }
     $toc_view->setDiff($target);
     $toc_view->setUser($user);
     $toc_view->setRevisionID($revision->getID());
     $toc_view->setWhitespace($whitespace);
 
     $comment_form = null;
     if (!$viewer_is_anonymous) {
       $draft = id(new PhabricatorDraft())->loadOneWhere(
         'authorPHID = %s AND draftKey = %s',
         $user->getPHID(),
         'differential-comment-'.$revision->getID());
 
       $reviewers = array();
       $ccs = array();
       if ($draft) {
         $reviewers = idx($draft->getMetadata(), 'reviewers', array());
         $ccs = idx($draft->getMetadata(), 'ccs', array());
         if ($reviewers || $ccs) {
           $handles = $this->loadViewerHandles(array_merge($reviewers, $ccs));
           $reviewers = array_select_keys($handles, $reviewers);
           $ccs = array_select_keys($handles, $ccs);
         }
       }
 
       $comment_form = new DifferentialAddCommentView();
       $comment_form->setRevision($revision);
 
       $review_warnings = array();
       foreach ($field_list->getFields() as $field) {
         $review_warnings[] = $field->getWarningsForDetailView();
       }
       $review_warnings = array_mergev($review_warnings);
 
       if ($review_warnings) {
         $review_warnings_panel = id(new AphrontErrorView())
           ->setSeverity(AphrontErrorView::SEVERITY_WARNING)
           ->setErrors($review_warnings);
         $comment_form->setErrorView($review_warnings_panel);
       }
 
       $comment_form->setActions($this->getRevisionCommentActions($revision));
       $action_uri = $this->getApplicationURI(
         'comment/save/'.$revision->getID().'/');
 
       $comment_form->setActionURI($action_uri);
       $comment_form->setUser($user);
       $comment_form->setDraft($draft);
       $comment_form->setReviewers(mpull($reviewers, 'getFullName', 'getPHID'));
       $comment_form->setCCs(mpull($ccs, 'getFullName', 'getPHID'));
 
       // TODO: This just makes the "Z" key work. Generalize this and remove
       // it at some point.
       $comment_form = phutil_tag(
         'div',
         array(
           'class' => 'differential-add-comment-panel',
         ),
         $comment_form);
     }
 
     $pane_id = celerity_generate_unique_node_id();
     Javelin::initBehavior(
       'differential-keyboard-navigation',
       array(
         'haunt' => $pane_id,
       ));
     Javelin::initBehavior('differential-user-select');
 
     $page_pane = id(new DifferentialPrimaryPaneView())
       ->setID($pane_id)
       ->appendChild(array(
         $comment_view,
         $diff_history,
         $warning,
         $local_view,
         $toc_view,
         $other_view,
         $changeset_view,
       ));
     if ($comment_form) {
 
       $page_pane->appendChild($comment_form);
     } else {
       // TODO: For now, just use this to get "Login to Comment".
       $page_pane->appendChild(
         id(new PhabricatorApplicationTransactionCommentView())
           ->setUser($user)
           ->setRequestURI($request->getRequestURI()));
     }
 
 
     $object_id = 'D'.$revision->getID();
 
     $top_anchor = id(new PhabricatorAnchorView())
       ->setAnchorName('top')
       ->setNavigationMarker(true);
 
     $content = array(
       $top_anchor,
       $revision_detail_box,
       $page_pane,
     );
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($object_id, '/'.$object_id);
     $crumbs->setActionList($revision_detail->getActionList());
 
     $prefs = $user->loadPreferences();
 
     $pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
     if ($prefs->getPreference($pref_filetree)) {
       $collapsed = $prefs->getPreference(
         PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED,
         false);
 
       $nav = id(new DifferentialChangesetFileTreeSideNavBuilder())
         ->setAnchorName('top')
         ->setTitle('D'.$revision->getID())
         ->setBaseURI(new PhutilURI('/D'.$revision->getID()))
         ->setCollapsed((bool)$collapsed)
         ->build($changesets);
       $nav->appendChild($content);
       $nav->setCrumbs($crumbs);
       $content = $nav;
     } else {
       array_unshift($content, $crumbs);
     }
 
     return $this->buildApplicationPage(
       $content,
       array(
         'title' => $object_id.' '.$revision->getTitle(),
         'pageObjects' => array($revision->getPHID()),
       ));
   }
 
   private function getRevisionActions(DifferentialRevision $revision) {
     $viewer = $this->getRequest()->getUser();
     $revision_id = $revision->getID();
     $revision_phid = $revision->getPHID();
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $revision,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $actions = array();
 
     $actions[] = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setHref("/differential/revision/edit/{$revision_id}/")
       ->setName(pht('Edit Revision'))
       ->setDisabled(!$can_edit)
       ->setWorkflow(!$can_edit);
 
     $this->requireResource('phabricator-object-selector-css');
     $this->requireResource('javelin-behavior-phabricator-object-selector');
 
     $actions[] = id(new PhabricatorActionView())
       ->setIcon('fa-link')
       ->setName(pht('Edit Dependencies'))
       ->setHref("/search/attach/{$revision_phid}/DREV/dependencies/")
       ->setWorkflow(true)
       ->setDisabled(!$can_edit);
 
     $maniphest = 'PhabricatorManiphestApplication';
     if (PhabricatorApplication::isClassInstalled($maniphest)) {
       $actions[] = id(new PhabricatorActionView())
         ->setIcon('fa-anchor')
         ->setName(pht('Edit Maniphest Tasks'))
         ->setHref("/search/attach/{$revision_phid}/TASK/")
         ->setWorkflow(true)
         ->setDisabled(!$can_edit);
     }
 
     $request_uri = $this->getRequest()->getRequestURI();
     $actions[] = id(new PhabricatorActionView())
       ->setIcon('fa-download')
       ->setName(pht('Download Raw Diff'))
       ->setHref($request_uri->alter('download', 'true'));
 
     return $actions;
   }
 
   private function getRevisionCommentActions(DifferentialRevision $revision) {
     $actions = array(
       DifferentialAction::ACTION_COMMENT => true,
     );
 
     $viewer = $this->getRequest()->getUser();
     $viewer_phid = $viewer->getPHID();
     $viewer_is_owner = ($viewer_phid == $revision->getAuthorPHID());
     $viewer_is_reviewer = in_array($viewer_phid, $revision->getReviewers());
     $status = $revision->getStatus();
 
     $viewer_has_accepted = false;
     $viewer_has_rejected = false;
     $status_accepted = DifferentialReviewerStatus::STATUS_ACCEPTED;
     $status_rejected = DifferentialReviewerStatus::STATUS_REJECTED;
     foreach ($revision->getReviewerStatus() as $reviewer) {
       if ($reviewer->getReviewerPHID() == $viewer_phid) {
         if ($reviewer->getStatus() == $status_accepted) {
           $viewer_has_accepted = true;
         }
         if ($reviewer->getStatus() == $status_rejected) {
           $viewer_has_rejected = true;
         }
         break;
       }
     }
 
     $allow_self_accept = PhabricatorEnv::getEnvConfig(
       'differential.allow-self-accept');
     $always_allow_abandon = PhabricatorEnv::getEnvConfig(
       'differential.always-allow-abandon');
     $always_allow_close = PhabricatorEnv::getEnvConfig(
       'differential.always-allow-close');
     $allow_reopen = PhabricatorEnv::getEnvConfig(
       'differential.allow-reopen');
 
     if ($viewer_is_owner) {
       switch ($status) {
         case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
           $actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept;
           $actions[DifferentialAction::ACTION_ABANDON] = true;
           $actions[DifferentialAction::ACTION_RETHINK] = true;
           break;
         case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
         case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED:
           $actions[DifferentialAction::ACTION_ACCEPT] = $allow_self_accept;
           $actions[DifferentialAction::ACTION_ABANDON] = true;
           $actions[DifferentialAction::ACTION_REQUEST] = true;
           break;
         case ArcanistDifferentialRevisionStatus::ACCEPTED:
           $actions[DifferentialAction::ACTION_ABANDON] = true;
           $actions[DifferentialAction::ACTION_REQUEST] = true;
           $actions[DifferentialAction::ACTION_RETHINK] = true;
           $actions[DifferentialAction::ACTION_CLOSE] = true;
           break;
         case ArcanistDifferentialRevisionStatus::CLOSED:
           break;
         case ArcanistDifferentialRevisionStatus::ABANDONED:
           $actions[DifferentialAction::ACTION_RECLAIM] = true;
           break;
       }
     } else {
       switch ($status) {
         case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
           $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon;
           $actions[DifferentialAction::ACTION_ACCEPT] = true;
           $actions[DifferentialAction::ACTION_REJECT] = true;
           $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer;
           break;
         case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
         case ArcanistDifferentialRevisionStatus::CHANGES_PLANNED:
           $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon;
           $actions[DifferentialAction::ACTION_ACCEPT] = true;
           $actions[DifferentialAction::ACTION_REJECT] = !$viewer_has_rejected;
           $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer;
           break;
         case ArcanistDifferentialRevisionStatus::ACCEPTED:
           $actions[DifferentialAction::ACTION_ABANDON] = $always_allow_abandon;
           $actions[DifferentialAction::ACTION_ACCEPT] = !$viewer_has_accepted;
           $actions[DifferentialAction::ACTION_REJECT] = true;
           $actions[DifferentialAction::ACTION_RESIGN] = $viewer_is_reviewer;
           break;
         case ArcanistDifferentialRevisionStatus::CLOSED:
         case ArcanistDifferentialRevisionStatus::ABANDONED:
           break;
       }
       if ($status != ArcanistDifferentialRevisionStatus::CLOSED) {
         $actions[DifferentialAction::ACTION_CLAIM] = true;
         $actions[DifferentialAction::ACTION_CLOSE] = $always_allow_close;
       }
     }
 
     $actions[DifferentialAction::ACTION_ADDREVIEWERS] = true;
     $actions[DifferentialAction::ACTION_ADDCCS] = true;
     $actions[DifferentialAction::ACTION_REOPEN] = $allow_reopen &&
       ($status == ArcanistDifferentialRevisionStatus::CLOSED);
 
     $actions = array_keys(array_filter($actions));
     $actions_dict = array();
     foreach ($actions as $action) {
       $actions_dict[$action] = DifferentialAction::getActionVerb($action);
     }
 
     return $actions_dict;
   }
 
   private function loadInlineComments(
     DifferentialRevision $revision,
     array &$changesets) {
     assert_instances_of($changesets, 'DifferentialChangeset');
 
     $inline_comments = array();
 
     $inline_comments = id(new DifferentialInlineCommentQuery())
       ->withRevisionIDs(array($revision->getID()))
       ->withNotDraft(true)
       ->execute();
 
     $load_changesets = array();
     foreach ($inline_comments as $inline) {
       $changeset_id = $inline->getChangesetID();
       if (isset($changesets[$changeset_id])) {
         continue;
       }
       $load_changesets[$changeset_id] = true;
     }
 
     $more_changesets = array();
     if ($load_changesets) {
       $changeset_ids = array_keys($load_changesets);
       $more_changesets += id(new DifferentialChangeset())
         ->loadAllWhere(
           'id IN (%Ld)',
           $changeset_ids);
     }
 
     if ($more_changesets) {
       $changesets += $more_changesets;
       $changesets = msort($changesets, 'getSortKey');
     }
 
     return $inline_comments;
   }
 
   private function loadChangesetsAndVsMap(
     DifferentialDiff $target,
     DifferentialDiff $diff_vs = null,
     PhabricatorRepository $repository = null) {
 
     $load_diffs = array($target);
     if ($diff_vs) {
       $load_diffs[] = $diff_vs;
     }
 
     $raw_changesets = id(new DifferentialChangesetQuery())
       ->setViewer($this->getRequest()->getUser())
       ->withDiffs($load_diffs)
       ->execute();
     $changeset_groups = mgroup($raw_changesets, 'getDiffID');
 
     $changesets = idx($changeset_groups, $target->getID(), array());
     $changesets = mpull($changesets, null, 'getID');
 
     $refs          = array();
     $vs_map        = array();
     $vs_changesets = array();
     if ($diff_vs) {
       $vs_id                  = $diff_vs->getID();
       $vs_changesets_path_map = array();
       foreach (idx($changeset_groups, $vs_id, array()) as $changeset) {
         $path = $changeset->getAbsoluteRepositoryPath($repository, $diff_vs);
         $vs_changesets_path_map[$path] = $changeset;
         $vs_changesets[$changeset->getID()] = $changeset;
       }
       foreach ($changesets as $key => $changeset) {
         $path = $changeset->getAbsoluteRepositoryPath($repository, $target);
         if (isset($vs_changesets_path_map[$path])) {
           $vs_map[$changeset->getID()] =
             $vs_changesets_path_map[$path]->getID();
           $refs[$changeset->getID()] =
             $changeset->getID().'/'.$vs_changesets_path_map[$path]->getID();
           unset($vs_changesets_path_map[$path]);
         } else {
           $refs[$changeset->getID()] = $changeset->getID();
         }
       }
       foreach ($vs_changesets_path_map as $path => $changeset) {
         $changesets[$changeset->getID()] = $changeset;
         $vs_map[$changeset->getID()]     = -1;
         $refs[$changeset->getID()]       = $changeset->getID().'/-1';
       }
     } else {
       foreach ($changesets as $changeset) {
         $refs[$changeset->getID()] = $changeset->getID();
       }
     }
 
     $changesets = msort($changesets, 'getSortKey');
 
     return array($changesets, $vs_map, $vs_changesets, $refs);
   }
 
   private function buildSymbolIndexes(
     PhabricatorRepositoryArcanistProject $arc_project,
     array $visible_changesets) {
     assert_instances_of($visible_changesets, 'DifferentialChangeset');
 
     $engine = PhabricatorSyntaxHighlighter::newEngine();
 
     $langs = $arc_project->getSymbolIndexLanguages();
     if (!$langs) {
       return array(array(), array());
     }
 
     $symbol_indexes = array();
 
     $project_phids = array_merge(
       array($arc_project->getPHID()),
       nonempty($arc_project->getSymbolIndexProjects(), array()));
 
     $indexed_langs = array_fill_keys($langs, true);
     foreach ($visible_changesets as $key => $changeset) {
       $lang = $engine->getLanguageFromFilename($changeset->getFilename());
       if (isset($indexed_langs[$lang])) {
         $symbol_indexes[$key] = array(
           'lang'      => $lang,
           'projects'  => $project_phids,
         );
       }
     }
 
     return array($symbol_indexes, $project_phids);
   }
 
   private function loadOtherRevisions(
     array $changesets,
     DifferentialDiff $target,
     PhabricatorRepository $repository) {
     assert_instances_of($changesets, 'DifferentialChangeset');
 
     $paths = array();
     foreach ($changesets as $changeset) {
       $paths[] = $changeset->getAbsoluteRepositoryPath(
         $repository,
         $target);
     }
 
     if (!$paths) {
       return array();
     }
 
     $path_map = id(new DiffusionPathIDQuery($paths))->loadPathIDs();
 
     if (!$path_map) {
       return array();
     }
 
     $query = id(new DifferentialRevisionQuery())
       ->setViewer($this->getRequest()->getUser())
       ->withStatus(DifferentialRevisionQuery::STATUS_OPEN)
       ->setOrder(DifferentialRevisionQuery::ORDER_PATH_MODIFIED)
       ->setLimit(10)
       ->needFlags(true)
       ->needDrafts(true)
       ->needRelationships(true);
 
     foreach ($path_map as $path => $path_id) {
       $query->withPath($repository->getID(), $path_id);
     }
 
     $results = $query->execute();
 
     // Strip out *this* revision.
     foreach ($results as $key => $result) {
       if ($result->getID() == $this->revisionID) {
         unset($results[$key]);
       }
     }
 
     return $results;
   }
 
   private function renderOtherRevisions(array $revisions) {
     assert_instances_of($revisions, 'DifferentialRevision');
 
     $user = $this->getRequest()->getUser();
 
     $view = id(new DifferentialRevisionListView())
       ->setRevisions($revisions)
       ->setUser($user);
 
     $phids = $view->getRequiredHandlePHIDs();
     $handles = $this->loadViewerHandles($phids);
     $view->setHandles($handles);
 
     return id(new PHUIObjectBoxView())
       ->setHeaderText(pht('Open Revisions Affecting These Files'))
       ->appendChild($view);
   }
 
 
   /**
    * Note this code is somewhat similar to the buildPatch method in
    * @{class:DifferentialReviewRequestMail}.
    *
    * @return @{class:AphrontRedirectResponse}
    */
   private function buildRawDiffResponse(
     DifferentialRevision $revision,
     array $changesets,
     array $vs_changesets,
     array $vs_map,
     PhabricatorRepository $repository = null) {
 
     assert_instances_of($changesets,    'DifferentialChangeset');
     assert_instances_of($vs_changesets, 'DifferentialChangeset');
 
     $viewer = $this->getRequest()->getUser();
 
     id(new DifferentialHunkQuery())
       ->setViewer($viewer)
       ->withChangesets($changesets)
       ->needAttachToChangesets(true)
       ->execute();
 
     $diff = new DifferentialDiff();
     $diff->attachChangesets($changesets);
     $raw_changes = $diff->buildChangesList();
     $changes = array();
     foreach ($raw_changes as $changedict) {
       $changes[] = ArcanistDiffChange::newFromDictionary($changedict);
     }
 
     $loader = id(new PhabricatorFileBundleLoader())
       ->setViewer($viewer);
 
     $bundle = ArcanistBundle::newFromChanges($changes);
     $bundle->setLoadFileDataCallback(array($loader, 'loadFileData'));
 
     $vcs = $repository ? $repository->getVersionControlSystem() : null;
     switch ($vcs) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         $raw_diff = $bundle->toGitPatch();
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
       default:
         $raw_diff = $bundle->toUnifiedDiff();
         break;
     }
 
     $request_uri = $this->getRequest()->getRequestURI();
 
     // this ends up being something like
     //   D123.diff
     // or the verbose
     //   D123.vs123.id123.whitespaceignore-all.diff
     // lame but nice to include these options
     $file_name = ltrim($request_uri->getPath(), '/').'.';
     foreach ($request_uri->getQueryParams() as $key => $value) {
       if ($key == 'download') {
         continue;
       }
       $file_name .= $key.$value.'.';
     }
     $file_name .= 'diff';
 
     $file = PhabricatorFile::buildFromFileDataOrHash(
       $raw_diff,
       array(
         'name' => $file_name,
         'ttl' => (60 * 60 * 24),
         'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
       ));
 
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
       $file->attachToObject($revision->getPHID());
     unset($unguarded);
 
     return $file->getRedirectResponse();
   }
 
   private function buildTransactions(
     DifferentialRevision $revision,
     DifferentialDiff $left_diff,
     DifferentialDiff $right_diff,
     array $changesets) {
 
-    $viewer = $this->getRequest()->getUser();
-
-    $xactions = id(new DifferentialTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($revision->getPHID()))
-      ->needComments(true)
-      ->execute();
-
-    $timeline = id(new DifferentialTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($revision->getPHID())
+    $timeline = $this->buildTransactionTimeline(
+      $revision,
+      new DifferentialTransactionQuery());
+    $timeline
       ->setChangesets($changesets)
       ->setRevision($revision)
       ->setLeftDiff($left_diff)
-      ->setRightDiff($right_diff)
-      ->setTransactions($xactions);
+      ->setRightDiff($right_diff);
 
     return $timeline;
   }
 
   private function buildRevisionWarnings(
     DifferentialRevision $revision,
     PhabricatorCustomFieldList $field_list,
     array $warning_handle_map,
     array $handles) {
 
     $warnings = array();
     foreach ($field_list->getFields() as $key => $field) {
       $phids = idx($warning_handle_map, $key, array());
       $field_handles = array_select_keys($handles, $phids);
       $field_warnings = $field->getWarningsForRevisionHeader($field_handles);
       foreach ($field_warnings as $warning) {
         $warnings[] = $warning;
       }
     }
 
     return $warnings;
   }
 
 }
diff --git a/src/applications/differential/storage/DifferentialTransaction.php b/src/applications/differential/storage/DifferentialTransaction.php
index b6df7cf4f5..b0c946ebb1 100644
--- a/src/applications/differential/storage/DifferentialTransaction.php
+++ b/src/applications/differential/storage/DifferentialTransaction.php
@@ -1,670 +1,674 @@
 <?php
 
 final class DifferentialTransaction extends PhabricatorApplicationTransaction {
 
   private $isCommandeerSideEffect;
 
 
   public function setIsCommandeerSideEffect($is_side_effect) {
     $this->isCommandeerSideEffect = $is_side_effect;
     return $this;
   }
 
   public function getIsCommandeerSideEffect() {
     return $this->isCommandeerSideEffect;
   }
 
   const TYPE_INLINE = 'differential:inline';
   const TYPE_UPDATE = 'differential:update';
   const TYPE_ACTION = 'differential:action';
   const TYPE_STATUS = 'differential:status';
 
   public function getApplicationName() {
     return 'differential';
   }
 
   public function getApplicationTransactionType() {
     return DifferentialRevisionPHIDType::TYPECONST;
   }
 
   public function getApplicationTransactionCommentObject() {
     return new DifferentialTransactionComment();
   }
 
+  public function getApplicationTransactionViewObject() {
+    return new DifferentialTransactionView();
+  }
+
   public function shouldHide() {
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     switch ($this->getTransactionType()) {
       case self::TYPE_UPDATE:
         // Older versions of this transaction have an ID for the new value,
         // and/or do not record the old value. Only hide the transaction if
         // the new value is a PHID, indicating that this is a newer style
         // transaction.
         if ($old === null) {
           if (phid_get_type($new) == DifferentialDiffPHIDType::TYPECONST) {
             return true;
           }
         }
         break;
 
       case PhabricatorTransactions::TYPE_EDGE:
         $add = array_diff_key($new, $old);
         $rem = array_diff_key($old, $new);
 
         // Hide metadata-only edge transactions. These correspond to users
         // accepting or rejecting revisions, but the change is always explicit
         // because of the TYPE_ACTION transaction. Rendering these transactions
         // just creates clutter.
 
         if (!$add && !$rem) {
           return true;
         }
         break;
     }
 
     return parent::shouldHide();
   }
 
   public function shouldHideForMail(array $xactions) {
     switch ($this->getTransactionType()) {
       case self::TYPE_INLINE:
         // Hide inlines when rendering mail transactions if any other
         // transaction type exists.
         foreach ($xactions as $xaction) {
           if ($xaction->getTransactionType() != self::TYPE_INLINE) {
             return true;
           }
         }
 
         // If only inline transactions exist, we just render the first one.
         return ($this !== head($xactions));
     }
 
     return parent::shouldHideForMail($xactions);
   }
 
   public function getBodyForMail() {
     switch ($this->getTransactionType()) {
       case self::TYPE_INLINE:
         // Don't render inlines into the mail body; they render into a special
         // section immediately after the body instead.
         return null;
     }
 
     return parent::getBodyForMail();
   }
 
   public function getRequiredHandlePHIDs() {
     $phids = parent::getRequiredHandlePHIDs();
 
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     switch ($this->getTransactionType()) {
       case self::TYPE_ACTION:
         if ($new == DifferentialAction::ACTION_CLOSE &&
             $this->getMetadataValue('isCommitClose')) {
           $phids[] = $this->getMetadataValue('commitPHID');
           if ($this->getMetadataValue('committerPHID')) {
             $phids[] = $this->getMetadataValue('committerPHID');
           }
           if ($this->getMetadataValue('authorPHID')) {
             $phids[] = $this->getMetadataValue('authorPHID');
           }
         }
         break;
       case self::TYPE_UPDATE:
         if ($new) {
           $phids[] = $new;
         }
         break;
     }
 
     return $phids;
   }
 
   public function getActionStrength() {
 
     switch ($this->getTransactionType()) {
       case self::TYPE_ACTION:
         return 3;
       case self::TYPE_UPDATE:
         return 2;
       case self::TYPE_INLINE:
         return 0.25;
     }
 
     return parent::getActionStrength();
   }
 
 
   public function getActionName() {
     switch ($this->getTransactionType()) {
       case self::TYPE_INLINE:
         return pht('Commented On');
       case self::TYPE_UPDATE:
         $old = $this->getOldValue();
         if ($old === null) {
           return pht('Request');
         } else {
           return pht('Updated');
         }
       case self::TYPE_ACTION:
         $map = array(
           DifferentialAction::ACTION_ACCEPT => pht('Accepted'),
           DifferentialAction::ACTION_REJECT => pht('Requested Changes To'),
           DifferentialAction::ACTION_RETHINK => pht('Planned Changes To'),
           DifferentialAction::ACTION_ABANDON => pht('Abandoned'),
           DifferentialAction::ACTION_CLOSE => pht('Closed'),
           DifferentialAction::ACTION_REQUEST => pht('Requested A Review Of'),
           DifferentialAction::ACTION_RESIGN => pht('Resigned From'),
           DifferentialAction::ACTION_ADDREVIEWERS => pht('Added Reviewers'),
           DifferentialAction::ACTION_CLAIM => pht('Commandeered'),
           DifferentialAction::ACTION_REOPEN => pht('Reopened'),
         );
         $name = idx($map, $this->getNewValue());
         if ($name !== null) {
           return $name;
         }
         break;
     }
 
     return parent::getActionName();
   }
 
   public function getMailTags() {
     $tags = array();
 
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_SUBSCRIBERS;
         $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_CC;
         break;
       case self::TYPE_ACTION:
         switch ($this->getNewValue()) {
           case DifferentialAction::ACTION_CLOSE:
             $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_CLOSED;
             break;
         }
         break;
       case self::TYPE_UPDATE:
         $old = $this->getOldValue();
         if ($old === null) {
           $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEW_REQUEST;
         } else {
           $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_UPDATED;
         }
         break;
       case PhabricatorTransactions::TYPE_EDGE:
         switch ($this->getMetadataValue('edge:type')) {
           case PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER:
             $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_REVIEWERS;
             break;
         }
         break;
       case PhabricatorTransactions::TYPE_COMMENT:
       case self::TYPE_INLINE:
         $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_COMMENT;
         break;
     }
 
     if (!$tags) {
       $tags[] = MetaMTANotificationType::TYPE_DIFFERENTIAL_OTHER;
     }
 
     return $tags;
   }
 
   public function getTitle() {
     $author_phid = $this->getAuthorPHID();
     $author_handle = $this->renderHandleLink($author_phid);
 
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     switch ($this->getTransactionType()) {
       case self::TYPE_INLINE:
         return pht(
           '%s added inline comments.',
           $author_handle);
       case self::TYPE_UPDATE:
         if ($this->getMetadataValue('isCommitUpdate')) {
           return pht(
             'This revision was automatically updated to reflect the '.
             'committed changes.');
         } else if ($new) {
           // TODO: Migrate to PHIDs and use handles here?
           if (phid_get_type($new) == DifferentialDiffPHIDType::TYPECONST) {
             return pht(
               '%s updated this revision to %s.',
               $author_handle,
               $this->renderHandleLink($new));
           } else {
             return pht(
               '%s updated this revision.',
               $author_handle);
           }
         } else {
           return pht(
             '%s updated this revision.',
             $author_handle);
         }
       case self::TYPE_ACTION:
         switch ($new) {
           case DifferentialAction::ACTION_CLOSE:
             if (!$this->getMetadataValue('isCommitClose')) {
               return DifferentialAction::getBasicStoryText(
                 $new,
                 $author_handle);
             }
             $commit_name = $this->renderHandleLink(
               $this->getMetadataValue('commitPHID'));
             $committer_phid = $this->getMetadataValue('committerPHID');
             $author_phid = $this->getMetadataValue('authorPHID');
             if ($this->getHandleIfExists($committer_phid)) {
               $committer_name = $this->renderHandleLink($committer_phid);
             } else {
               $committer_name = $this->getMetadataValue('committerName');
             }
             if ($this->getHandleIfExists($author_phid)) {
               $author_name = $this->renderHandleLink($author_phid);
             } else {
               $author_name = $this->getMetadataValue('authorName');
             }
 
             if ($committer_name && ($committer_name != $author_name)) {
               return pht(
                 'Closed by commit %s (authored by %s, committed by %s).',
                 $commit_name,
                 $author_name,
                 $committer_name);
             } else {
               return pht(
                 'Closed by commit %s (authored by %s).',
                 $commit_name,
                 $author_name);
             }
             break;
           default:
             return DifferentialAction::getBasicStoryText($new, $author_handle);
         }
         break;
       case self::TYPE_STATUS:
         switch ($this->getNewValue()) {
           case ArcanistDifferentialRevisionStatus::ACCEPTED:
             return pht(
               'This revision is now accepted and ready to land.');
           case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
             return pht(
               'This revision now requires changes to proceed.');
           case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
             return pht(
               'This revision now requires review to proceed.');
         }
     }
 
     return parent::getTitle();
   }
 
   public function renderExtraInformationLink() {
     if ($this->getMetadataValue('revisionMatchData')) {
       $details_href =
         '/differential/revision/closedetails/'.$this->getPHID().'/';
       $details_link = javelin_tag(
         'a',
         array(
           'href' => $details_href,
           'sigil' => 'workflow',
         ),
         pht('Explain Why'));
       return $details_link;
     }
     return parent::renderExtraInformationLink();
   }
 
   public function getTitleForFeed(PhabricatorFeedStory $story) {
     $author_phid = $this->getAuthorPHID();
     $object_phid = $this->getObjectPHID();
 
     $old = $this->getOldValue();
     $new = $this->getNewValue();
 
     $author_link = $this->renderHandleLink($author_phid);
     $object_link = $this->renderHandleLink($object_phid);
 
     switch ($this->getTransactionType()) {
       case self::TYPE_INLINE:
         return pht(
           '%s added inline comments to %s.',
           $author_link,
           $object_link);
       case self::TYPE_UPDATE:
         return pht(
           '%s updated the diff for %s.',
           $author_link,
           $object_link);
       case self::TYPE_ACTION:
         switch ($new) {
           case DifferentialAction::ACTION_ACCEPT:
             return pht(
               '%s accepted %s.',
               $author_link,
               $object_link);
           case DifferentialAction::ACTION_REJECT:
             return pht(
               '%s requested changes to %s.',
               $author_link,
               $object_link);
           case DifferentialAction::ACTION_RETHINK:
             return pht(
               '%s planned changes to %s.',
               $author_link,
               $object_link);
           case DifferentialAction::ACTION_ABANDON:
             return pht(
               '%s abandoned %s.',
               $author_link,
               $object_link);
           case DifferentialAction::ACTION_CLOSE:
             if (!$this->getMetadataValue('isCommitClose')) {
               return pht(
                 '%s closed %s.',
                 $author_link,
                 $object_link);
             } else {
               $commit_name = $this->renderHandleLink(
                 $this->getMetadataValue('commitPHID'));
               $committer_phid = $this->getMetadataValue('committerPHID');
               $author_phid = $this->getMetadataValue('authorPHID');
               if ($this->getHandleIfExists($committer_phid)) {
                 $committer_name = $this->renderHandleLink($committer_phid);
               } else {
                 $committer_name = $this->getMetadataValue('committerName');
               }
               if ($this->getHandleIfExists($author_phid)) {
                 $author_name = $this->renderHandleLink($author_phid);
               } else {
                 $author_name = $this->getMetadataValue('authorName');
               }
 
               if ($committer_name && ($committer_name != $author_name)) {
                 return pht(
                   '%s closed %s by commit %s (authored by %s).',
                   $author_link,
                   $object_link,
                   $commit_name,
                   $author_name);
               } else {
                 return pht(
                   '%s closed %s by commit %s.',
                   $author_link,
                   $object_link,
                   $commit_name);
               }
             }
             break;
 
           case DifferentialAction::ACTION_REQUEST:
             return pht(
               '%s requested review of %s.',
               $author_link,
               $object_link);
           case DifferentialAction::ACTION_RECLAIM:
             return pht(
               '%s reclaimed %s.',
               $author_link,
               $object_link);
           case DifferentialAction::ACTION_RESIGN:
             return pht(
               '%s resigned from %s.',
               $author_link,
               $object_link);
           case DifferentialAction::ACTION_CLAIM:
             return pht(
               '%s commandeered %s.',
               $author_link,
               $object_link);
           case DifferentialAction::ACTION_REOPEN:
             return pht(
               '%s reopened %s.',
               $author_link,
               $object_link);
         }
         break;
       case self::TYPE_STATUS:
         switch ($this->getNewValue()) {
           case ArcanistDifferentialRevisionStatus::ACCEPTED:
             return pht(
               '%s is now accepted and ready to land.',
               $object_link);
           case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
             return pht(
               '%s now requires changes to proceed.',
               $object_link);
           case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
             return pht(
               '%s now requires review to proceed.',
               $object_link);
         }
     }
 
     return parent::getTitleForFeed($story);
   }
 
   public function getIcon() {
     switch ($this->getTransactionType()) {
       case self::TYPE_INLINE:
         return 'fa-comment';
       case self::TYPE_UPDATE:
         return 'fa-refresh';
       case self::TYPE_STATUS:
         switch ($this->getNewValue()) {
           case ArcanistDifferentialRevisionStatus::ACCEPTED:
             return 'fa-check';
           case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
             return 'fa-times';
           case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
             return 'fa-undo';
         }
         break;
       case self::TYPE_ACTION:
         switch ($this->getNewValue()) {
           case DifferentialAction::ACTION_CLOSE:
             return 'fa-check';
           case DifferentialAction::ACTION_ACCEPT:
             return 'fa-check-circle-o';
           case DifferentialAction::ACTION_REJECT:
             return 'fa-times-circle-o';
           case DifferentialAction::ACTION_ABANDON:
             return 'fa-plane';
           case DifferentialAction::ACTION_RETHINK:
             return 'fa-headphones';
           case DifferentialAction::ACTION_REQUEST:
             return 'fa-refresh';
           case DifferentialAction::ACTION_RECLAIM:
           case DifferentialAction::ACTION_REOPEN:
             return 'fa-bullhorn';
           case DifferentialAction::ACTION_RESIGN:
             return 'fa-flag';
           case DifferentialAction::ACTION_CLAIM:
             return 'fa-flag';
         }
       case PhabricatorTransactions::TYPE_EDGE:
         switch ($this->getMetadataValue('edge:type')) {
           case PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER:
             return 'fa-user';
         }
     }
 
     return parent::getIcon();
   }
 
   public function shouldDisplayGroupWith(array $group) {
 
     // Never group status changes with other types of actions, they're indirect
     // and don't make sense when combined with direct actions.
 
     $type_status = self::TYPE_STATUS;
 
     if ($this->getTransactionType() == $type_status) {
       return false;
     }
 
     foreach ($group as $xaction) {
       if ($xaction->getTransactionType() == $type_status) {
         return false;
       }
     }
 
     return parent::shouldDisplayGroupWith($group);
   }
 
 
   public function getColor() {
     switch ($this->getTransactionType()) {
       case self::TYPE_UPDATE:
         return PhabricatorTransactions::COLOR_SKY;
       case self::TYPE_STATUS:
         switch ($this->getNewValue()) {
           case ArcanistDifferentialRevisionStatus::ACCEPTED:
             return PhabricatorTransactions::COLOR_GREEN;
           case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
             return PhabricatorTransactions::COLOR_RED;
           case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
             return PhabricatorTransactions::COLOR_ORANGE;
         }
         break;
       case self::TYPE_ACTION:
         switch ($this->getNewValue()) {
           case DifferentialAction::ACTION_CLOSE:
             return PhabricatorTransactions::COLOR_BLUE;
           case DifferentialAction::ACTION_ACCEPT:
             return PhabricatorTransactions::COLOR_GREEN;
           case DifferentialAction::ACTION_REJECT:
             return PhabricatorTransactions::COLOR_RED;
           case DifferentialAction::ACTION_ABANDON:
             return PhabricatorTransactions::COLOR_BLACK;
           case DifferentialAction::ACTION_RETHINK:
             return PhabricatorTransactions::COLOR_RED;
           case DifferentialAction::ACTION_REQUEST:
             return PhabricatorTransactions::COLOR_SKY;
           case DifferentialAction::ACTION_RECLAIM:
             return PhabricatorTransactions::COLOR_SKY;
           case DifferentialAction::ACTION_REOPEN:
             return PhabricatorTransactions::COLOR_SKY;
           case DifferentialAction::ACTION_RESIGN:
             return PhabricatorTransactions::COLOR_ORANGE;
           case DifferentialAction::ACTION_CLAIM:
             return PhabricatorTransactions::COLOR_YELLOW;
         }
     }
 
 
     return parent::getColor();
   }
 
   public function getNoEffectDescription() {
     switch ($this->getTransactionType()) {
       case PhabricatorTransactions::TYPE_EDGE:
         switch ($this->getMetadataValue('edge:type')) {
           case PhabricatorEdgeConfig::TYPE_DREV_HAS_REVIEWER:
             return pht(
               'The reviewers you are trying to add are already reviewing '.
               'this revision.');
         }
         break;
       case DifferentialTransaction::TYPE_ACTION:
         switch ($this->getNewValue()) {
           case DifferentialAction::ACTION_CLOSE:
             return pht('This revision is already closed.');
           case DifferentialAction::ACTION_ABANDON:
             return pht('This revision has already been abandoned.');
           case DifferentialAction::ACTION_RECLAIM:
             return pht(
               'You can not reclaim this revision because his revision is '.
               'not abandoned.');
           case DifferentialAction::ACTION_REOPEN:
             return pht(
               'You can not reopen this revision because this revision is '.
               'not closed.');
           case DifferentialAction::ACTION_RETHINK:
             return pht('This revision already requires changes.');
           case DifferentialAction::ACTION_REQUEST:
             return pht('Review is already requested for this revision.');
           case DifferentialAction::ACTION_RESIGN:
             return pht(
               'You can not resign from this revision because you are not '.
               'a reviewer.');
           case DifferentialAction::ACTION_CLAIM:
             return pht(
               'You can not commandeer this revision because you already own '.
               'it.');
           case DifferentialAction::ACTION_ACCEPT:
             return pht(
               'You have already accepted this revision.');
           case DifferentialAction::ACTION_REJECT:
             return pht(
               'You have already requested changes to this revision.');
         }
         break;
     }
 
     return parent::getNoEffectDescription();
   }
 
   public function renderAsTextForDoorkeeper(
     DoorkeeperFeedStoryPublisher $publisher,
     PhabricatorFeedStory $story,
     array $xactions) {
 
     $body = parent::renderAsTextForDoorkeeper($publisher, $story, $xactions);
 
     $inlines = array();
     foreach ($xactions as $xaction) {
       if ($xaction->getTransactionType() == self::TYPE_INLINE) {
         $inlines[] = $xaction;
       }
     }
 
     // TODO: This is a bit gross, but far less bad than it used to be. It
     // could be further cleaned up at some point.
 
     if ($inlines) {
       $engine = PhabricatorMarkupEngine::newMarkupEngine(array())
         ->setConfig('viewer', new PhabricatorUser())
         ->setMode(PhutilRemarkupEngine::MODE_TEXT);
 
       $body .= "\n\n";
       $body .= pht('Inline Comments');
       $body .= "\n";
 
       $changeset_ids = array();
       foreach ($inlines as $inline) {
         $changeset_ids[] = $inline->getComment()->getChangesetID();
       }
 
       $changesets = id(new DifferentialChangeset())->loadAllWhere(
         'id IN (%Ld)',
         $changeset_ids);
 
       foreach ($inlines as $inline) {
         $comment = $inline->getComment();
         $changeset = idx($changesets, $comment->getChangesetID());
         if (!$changeset) {
           continue;
         }
 
         $filename = $changeset->getDisplayFilename();
         $linenumber = $comment->getLineNumber();
         $inline_text = $engine->markupText($comment->getContent());
         $inline_text = rtrim($inline_text);
 
         $body .= "{$filename}:{$linenumber} {$inline_text}\n";
       }
     }
 
     return $body;
   }
 
 
 }
diff --git a/src/applications/diffusion/controller/DiffusionCommitController.php b/src/applications/diffusion/controller/DiffusionCommitController.php
index 54abc7e4d5..b41ad5cda5 100644
--- a/src/applications/diffusion/controller/DiffusionCommitController.php
+++ b/src/applications/diffusion/controller/DiffusionCommitController.php
@@ -1,1095 +1,1088 @@
 <?php
 
 final class DiffusionCommitController extends DiffusionController {
 
   const CHANGES_LIMIT = 100;
 
   private $auditAuthorityPHIDs;
   private $highlightedAudits;
 
   public function shouldAllowPublic() {
     return true;
   }
 
   public function willProcessRequest(array $data) {
     // This controller doesn't use blob/path stuff, just pass the dictionary
     // in directly instead of using the AphrontRequest parsing mechanism.
     $data['user'] = $this->getRequest()->getUser();
     $drequest = DiffusionRequest::newFromDictionary($data);
     $this->diffusionRequest = $drequest;
   }
 
   public function processRequest() {
     $drequest = $this->getDiffusionRequest();
 
     $request = $this->getRequest();
     $user = $request->getUser();
 
     if ($request->getStr('diff')) {
       return $this->buildRawDiffResponse($drequest);
     }
 
     $repository = $drequest->getRepository();
     $callsign = $repository->getCallsign();
 
     $content = array();
     $commit = id(new DiffusionCommitQuery())
       ->setViewer($request->getUser())
       ->withRepository($repository)
       ->withIdentifiers(array($drequest->getCommit()))
       ->needCommitData(true)
       ->needAuditRequests(true)
       ->executeOne();
 
     $crumbs = $this->buildCrumbs(array(
       'commit' => true,
     ));
 
     if (!$commit) {
       $exists = $this->callConduitWithDiffusionRequest(
         'diffusion.existsquery',
         array('commit' => $drequest->getCommit()));
       if (!$exists) {
         return new Aphront404Response();
       }
 
       $error = id(new AphrontErrorView())
         ->setTitle(pht('Commit Still Parsing'))
         ->appendChild(
           pht(
             'Failed to load the commit because the commit has not been '.
             'parsed yet.'));
 
       return $this->buildApplicationPage(
         array(
           $crumbs,
           $error,
         ),
         array(
           'title' => pht('Commit Still Parsing'),
         ));
     }
 
 
     $top_anchor = id(new PhabricatorAnchorView())
       ->setAnchorName('top')
       ->setNavigationMarker(true);
 
     $audit_requests = $commit->getAudits();
     $this->auditAuthorityPHIDs =
       PhabricatorAuditCommentEditor::loadAuditPHIDsForUser($user);
 
     $commit_data = $commit->getCommitData();
     $is_foreign = $commit_data->getCommitDetail('foreign-svn-stub');
     $changesets = null;
     if ($is_foreign) {
       $subpath = $commit_data->getCommitDetail('svn-subpath');
 
       $error_panel = new AphrontErrorView();
       $error_panel->setTitle(pht('Commit Not Tracked'));
       $error_panel->setSeverity(AphrontErrorView::SEVERITY_WARNING);
       $error_panel->appendChild(
         pht("This Diffusion repository is configured to track only one ".
         "subdirectory of the entire Subversion repository, and this commit ".
         "didn't affect the tracked subdirectory ('%s'), so no ".
         "information is available.", $subpath));
       $content[] = $error_panel;
       $content[] = $top_anchor;
     } else {
       $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
       $engine->setConfig('viewer', $user);
 
       require_celerity_resource('phabricator-remarkup-css');
 
       $parents = $this->callConduitWithDiffusionRequest(
         'diffusion.commitparentsquery',
         array('commit' => $drequest->getCommit()));
 
       if ($parents) {
         $parents = id(new DiffusionCommitQuery())
           ->setViewer($user)
           ->withRepository($repository)
           ->withIdentifiers($parents)
           ->execute();
       }
 
       $headsup_view = id(new PHUIHeaderView())
         ->setHeader(nonempty($commit->getSummary(), pht('Commit Detail')));
 
       $headsup_actions = $this->renderHeadsupActionList($commit, $repository);
 
       $commit_properties = $this->loadCommitProperties(
         $commit,
         $commit_data,
         $parents,
         $audit_requests);
       $property_list = id(new PHUIPropertyListView())
         ->setHasKeyboardShortcuts(true)
         ->setUser($user)
         ->setObject($commit);
       foreach ($commit_properties as $key => $value) {
         $property_list->addProperty($key, $value);
       }
 
       $message = $commit_data->getCommitMessage();
 
       $revision = $commit->getCommitIdentifier();
       $message = $this->linkBugtraq($message);
 
       $message = $engine->markupText($message);
 
       $property_list->invokeWillRenderEvent();
       $property_list->setActionList($headsup_actions);
 
       $detail_list = new PHUIPropertyListView();
       $detail_list->addSectionHeader(
         pht('Description'),
         PHUIPropertyListView::ICON_SUMMARY);
       $detail_list->addTextContent(
         phutil_tag(
           'div',
           array(
             'class' => 'diffusion-commit-message phabricator-remarkup',
           ),
           $message));
       $content[] = $top_anchor;
 
       $object_box = id(new PHUIObjectBoxView())
         ->setHeader($headsup_view)
         ->addPropertyList($property_list)
         ->addPropertyList($detail_list);
 
       $content[] = $object_box;
     }
 
     $content[] = $this->buildComments($commit);
 
     $hard_limit = 1000;
 
     if ($commit->isImported()) {
       $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest(
         $drequest);
       $change_query->setLimit($hard_limit + 1);
       $changes = $change_query->loadChanges();
     } else {
       $changes = array();
     }
 
     $was_limited = (count($changes) > $hard_limit);
     if ($was_limited) {
       $changes = array_slice($changes, 0, $hard_limit);
     }
 
     $content[] = $this->buildMergesTable($commit);
 
     $highlighted_audits = $commit->getAuthorityAudits(
       $user,
       $this->auditAuthorityPHIDs);
 
     $owners_paths = array();
     if ($highlighted_audits) {
       $packages = id(new PhabricatorOwnersPackage())->loadAllWhere(
         'phid IN (%Ls)',
         mpull($highlighted_audits, 'getAuditorPHID'));
       if ($packages) {
         $owners_paths = id(new PhabricatorOwnersPath())->loadAllWhere(
           'repositoryPHID = %s AND packageID IN (%Ld)',
           $repository->getPHID(),
           mpull($packages, 'getID'));
       }
     }
 
     $change_table = new DiffusionCommitChangeTableView();
     $change_table->setDiffusionRequest($drequest);
     $change_table->setPathChanges($changes);
     $change_table->setOwnersPaths($owners_paths);
 
     $count = count($changes);
 
     $bad_commit = null;
     if ($count == 0) {
       $bad_commit = queryfx_one(
         id(new PhabricatorRepository())->establishConnection('r'),
         'SELECT * FROM %T WHERE fullCommitName = %s',
         PhabricatorRepository::TABLE_BADCOMMIT,
         'r'.$callsign.$commit->getCommitIdentifier());
     }
 
     if ($bad_commit) {
       $content[] = $this->renderStatusMessage(
         pht('Bad Commit'),
         $bad_commit['description']);
     } else if ($is_foreign) {
       // Don't render anything else.
     } else if (!$commit->isImported()) {
       $content[] = $this->renderStatusMessage(
         pht('Still Importing...'),
         pht(
           'This commit is still importing. Changes will be visible once '.
           'the import finishes.'));
     } else if (!count($changes)) {
       $content[] = $this->renderStatusMessage(
         pht('Empty Commit'),
         pht(
           'This commit is empty and does not affect any paths.'));
     } else if ($was_limited) {
       $content[] = $this->renderStatusMessage(
         pht('Enormous Commit'),
         pht(
           'This commit is enormous, and affects more than %d files. '.
           'Changes are not shown.',
           $hard_limit));
     } else {
       // The user has clicked "Show All Changes", and we should show all the
       // changes inline even if there are more than the soft limit.
       $show_all_details = $request->getBool('show_all');
 
       $change_panel = new PHUIObjectBoxView();
       $header = new PHUIHeaderView();
       $header->setHeader('Changes ('.number_format($count).')');
       $change_panel->setID('toc');
       if ($count > self::CHANGES_LIMIT && !$show_all_details) {
 
         $icon = id(new PHUIIconView())
           ->setIconFont('fa-files-o');
 
         $button = id(new PHUIButtonView())
           ->setText(pht('Show All Changes'))
           ->setHref('?show_all=true')
           ->setTag('a')
           ->setIcon($icon);
 
         $warning_view = id(new AphrontErrorView())
           ->setSeverity(AphrontErrorView::SEVERITY_WARNING)
           ->setTitle('Very Large Commit')
           ->appendChild(
             pht('This commit is very large. Load each file individually.'));
 
         $change_panel->setErrorView($warning_view);
         $header->addActionLink($button);
       }
 
       $change_panel->appendChild($change_table);
       $change_panel->setHeader($header);
 
       $content[] = $change_panel;
 
       $changesets = DiffusionPathChange::convertToDifferentialChangesets(
         $user,
         $changes);
 
       $vcs = $repository->getVersionControlSystem();
       switch ($vcs) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
           $vcs_supports_directory_changes = true;
           break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
           $vcs_supports_directory_changes = false;
           break;
         default:
           throw new Exception('Unknown VCS.');
       }
 
       $references = array();
       foreach ($changesets as $key => $changeset) {
         $file_type = $changeset->getFileType();
         if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
           if (!$vcs_supports_directory_changes) {
             unset($changesets[$key]);
             continue;
           }
         }
 
         $references[$key] = $drequest->generateURI(
           array(
             'action' => 'rendering-ref',
             'path'   => $changeset->getFilename(),
           ));
       }
 
       // TODO: Some parts of the views still rely on properties of the
       // DifferentialChangeset. Make the objects ephemeral to make sure we don't
       // accidentally save them, and then set their ID to the appropriate ID for
       // this application (the path IDs).
       $path_ids = array_flip(mpull($changes, 'getPath'));
       foreach ($changesets as $changeset) {
         $changeset->makeEphemeral();
         $changeset->setID($path_ids[$changeset->getFilename()]);
       }
 
       if ($count <= self::CHANGES_LIMIT || $show_all_details) {
         $visible_changesets = $changesets;
       } else {
         $visible_changesets = array();
         $inlines = PhabricatorAuditInlineComment::loadDraftAndPublishedComments(
           $user,
           $commit->getPHID());
         $path_ids = mpull($inlines, null, 'getPathID');
         foreach ($changesets as $key => $changeset) {
           if (array_key_exists($changeset->getID(), $path_ids)) {
             $visible_changesets[$key] = $changeset;
           }
         }
       }
 
       $change_list_title = DiffusionView::nameCommit(
         $repository,
         $commit->getCommitIdentifier());
       $change_list = new DifferentialChangesetListView();
       $change_list->setTitle($change_list_title);
       $change_list->setChangesets($changesets);
       $change_list->setVisibleChangesets($visible_changesets);
       $change_list->setRenderingReferences($references);
       $change_list->setRenderURI('/diffusion/'.$callsign.'/diff/');
       $change_list->setRepository($repository);
       $change_list->setUser($user);
 
       // TODO: Try to setBranch() to something reasonable here?
 
       $change_list->setStandaloneURI(
         '/diffusion/'.$callsign.'/diff/');
       $change_list->setRawFileURIs(
         // TODO: Implement this, somewhat tricky if there's an octopus merge
         // or whatever?
         null,
         '/diffusion/'.$callsign.'/diff/?view=r');
 
       $change_list->setInlineCommentControllerURI(
         '/diffusion/inline/edit/'.phutil_escape_uri($commit->getPHID()).'/');
 
       $change_references = array();
       foreach ($changesets as $key => $changeset) {
         $change_references[$changeset->getID()] = $references[$key];
       }
       $change_table->setRenderingReferences($change_references);
 
       $content[] = $change_list->render();
     }
 
     $content[] = $this->renderAddCommentPanel($commit, $audit_requests);
 
     $commit_id = 'r'.$callsign.$commit->getCommitIdentifier();
     $short_name = DiffusionView::nameCommit(
       $repository,
       $commit->getCommitIdentifier());
 
     $prefs = $user->loadPreferences();
     $pref_filetree = PhabricatorUserPreferences::PREFERENCE_DIFF_FILETREE;
     $pref_collapse = PhabricatorUserPreferences::PREFERENCE_NAV_COLLAPSED;
     $show_filetree = $prefs->getPreference($pref_filetree);
     $collapsed = $prefs->getPreference($pref_collapse);
 
     if ($changesets && $show_filetree) {
       $nav = id(new DifferentialChangesetFileTreeSideNavBuilder())
         ->setAnchorName('top')
         ->setTitle($short_name)
         ->setBaseURI(new PhutilURI('/'.$commit_id))
         ->build($changesets)
         ->setCrumbs($crumbs)
         ->setCollapsed((bool)$collapsed)
         ->appendChild($content);
       $content = $nav;
     } else {
       $content = array($crumbs, $content);
     }
 
     return $this->buildApplicationPage(
       $content,
       array(
         'title' => $commit_id,
         'pageObjects' => array($commit->getPHID()),
       ));
   }
 
   private function loadCommitProperties(
     PhabricatorRepositoryCommit $commit,
     PhabricatorRepositoryCommitData $data,
     array $parents,
     array $audit_requests) {
 
     assert_instances_of($parents, 'PhabricatorRepositoryCommit');
     $viewer = $this->getRequest()->getUser();
     $commit_phid = $commit->getPHID();
     $drequest = $this->getDiffusionRequest();
     $repository = $drequest->getRepository();
 
     $edge_query = id(new PhabricatorEdgeQuery())
       ->withSourcePHIDs(array($commit_phid))
       ->withEdgeTypes(array(
         DiffusionCommitHasTaskEdgeType::EDGECONST,
         PhabricatorEdgeConfig::TYPE_COMMIT_HAS_DREV,
       ));
 
     $edges = $edge_query->execute();
 
     $task_phids = array_keys(
       $edges[$commit_phid][DiffusionCommitHasTaskEdgeType::EDGECONST]);
     $revision_phid = key(
       $edges[$commit_phid][PhabricatorEdgeConfig::TYPE_COMMIT_HAS_DREV]);
 
     $phids = $edge_query->getDestinationPHIDs(array($commit_phid));
 
     if ($data->getCommitDetail('authorPHID')) {
       $phids[] = $data->getCommitDetail('authorPHID');
     }
     if ($data->getCommitDetail('reviewerPHID')) {
       $phids[] = $data->getCommitDetail('reviewerPHID');
     }
     if ($data->getCommitDetail('committerPHID')) {
       $phids[] = $data->getCommitDetail('committerPHID');
     }
     if ($parents) {
       foreach ($parents as $parent) {
         $phids[] = $parent->getPHID();
       }
     }
 
     // NOTE: We should never normally have more than a single push log, but
     // it can occur naturally if a commit is pushed, then the branch it was
     // on is deleted, then the commit is pushed again (or through other similar
     // chains of events). This should be rare, but does not indicate a bug
     // or data issue.
 
     // NOTE: We never query push logs in SVN because the commiter is always
     // the pusher and the commit time is always the push time; the push log
     // is redundant and we save a query by skipping it.
 
     $push_logs = array();
     if ($repository->isHosted() && !$repository->isSVN()) {
       $push_logs = id(new PhabricatorRepositoryPushLogQuery())
         ->setViewer($viewer)
         ->withRepositoryPHIDs(array($repository->getPHID()))
         ->withNewRefs(array($commit->getCommitIdentifier()))
         ->withRefTypes(array(PhabricatorRepositoryPushLog::REFTYPE_COMMIT))
         ->execute();
       foreach ($push_logs as $log) {
         $phids[] = $log->getPusherPHID();
       }
     }
 
     $handles = array();
     if ($phids) {
       $handles = $this->loadViewerHandles($phids);
     }
 
     $props = array();
 
     if ($commit->getAuditStatus()) {
       $status = PhabricatorAuditCommitStatusConstants::getStatusName(
         $commit->getAuditStatus());
       $tag = id(new PHUITagView())
         ->setType(PHUITagView::TYPE_STATE)
         ->setName($status);
 
       switch ($commit->getAuditStatus()) {
         case PhabricatorAuditCommitStatusConstants::NEEDS_AUDIT:
           $tag->setBackgroundColor(PHUITagView::COLOR_ORANGE);
           break;
         case PhabricatorAuditCommitStatusConstants::CONCERN_RAISED:
           $tag->setBackgroundColor(PHUITagView::COLOR_RED);
           break;
         case PhabricatorAuditCommitStatusConstants::PARTIALLY_AUDITED:
           $tag->setBackgroundColor(PHUITagView::COLOR_BLUE);
           break;
         case PhabricatorAuditCommitStatusConstants::FULLY_AUDITED:
           $tag->setBackgroundColor(PHUITagView::COLOR_GREEN);
           break;
       }
 
       $props['Status'] = $tag;
     }
 
     if ($audit_requests) {
       $user_requests = array();
       $other_requests = array();
       foreach ($audit_requests as $audit_request) {
         if ($audit_request->isUser()) {
           $user_requests[] = $audit_request;
         } else {
           $other_requests[] = $audit_request;
         }
       }
 
       if ($user_requests) {
         $props['Auditors'] = $this->renderAuditStatusView(
           $user_requests);
       }
 
       if ($other_requests) {
         $props['Project/Package Auditors'] = $this->renderAuditStatusView(
           $other_requests);
       }
     }
 
     $author_phid = $data->getCommitDetail('authorPHID');
     $author_name = $data->getAuthorName();
 
     if (!$repository->isSVN()) {
       $authored_info = id(new PHUIStatusItemView());
       // TODO: In Git, a distinct authorship date is available. When present,
       // we should show it here.
 
       if ($author_phid) {
         $authored_info->setTarget($handles[$author_phid]->renderLink());
       } else if (strlen($author_name)) {
         $authored_info->setTarget($author_name);
       }
 
       $props['Authored'] = id(new PHUIStatusListView())
         ->addItem($authored_info);
     }
 
     $committed_info = id(new PHUIStatusItemView())
       ->setNote(phabricator_datetime($commit->getEpoch(), $viewer));
 
     $committer_phid = $data->getCommitDetail('committerPHID');
     $committer_name = $data->getCommitDetail('committer');
     if ($committer_phid) {
       $committed_info->setTarget($handles[$committer_phid]->renderLink());
     } else if (strlen($committer_name)) {
       $committed_info->setTarget($committer_name);
     } else if ($author_phid) {
       $committed_info->setTarget($handles[$author_phid]->renderLink());
     } else if (strlen($author_name)) {
       $committed_info->setTarget($author_name);
     }
 
     $props['Committed'] = id(new PHUIStatusListView())
       ->addItem($committed_info);
 
     if ($push_logs) {
       $pushed_list = new PHUIStatusListView();
 
       foreach ($push_logs as $push_log) {
         $pushed_item = id(new PHUIStatusItemView())
           ->setTarget($handles[$push_log->getPusherPHID()]->renderLink())
           ->setNote(phabricator_datetime($push_log->getEpoch(), $viewer));
         $pushed_list->addItem($pushed_item);
       }
 
       $props['Pushed'] = $pushed_list;
     }
 
     $reviewer_phid = $data->getCommitDetail('reviewerPHID');
     if ($reviewer_phid) {
       $props['Reviewer'] = $handles[$reviewer_phid]->renderLink();
     }
 
     if ($revision_phid) {
       $props['Differential Revision'] = $handles[$revision_phid]->renderLink();
     }
 
     if ($parents) {
       $parent_links = array();
       foreach ($parents as $parent) {
         $parent_links[] = $handles[$parent->getPHID()]->renderLink();
       }
       $props['Parents'] = phutil_implode_html(" \xC2\xB7 ", $parent_links);
     }
 
     $props['Branches'] = phutil_tag(
       'span',
       array(
         'id' => 'commit-branches',
       ),
       pht('Unknown'));
     $props['Tags'] = phutil_tag(
       'span',
       array(
         'id' => 'commit-tags',
       ),
       pht('Unknown'));
 
     $callsign = $repository->getCallsign();
     $root = '/diffusion/'.$callsign.'/commit/'.$commit->getCommitIdentifier();
     Javelin::initBehavior(
       'diffusion-commit-branches',
       array(
         $root.'/branches/' => 'commit-branches',
         $root.'/tags/' => 'commit-tags',
       ));
 
     $refs = $this->buildRefs($drequest);
     if ($refs) {
       $props['References'] = $refs;
     }
 
     if ($task_phids) {
       $task_list = array();
       foreach ($task_phids as $phid) {
         $task_list[] = $handles[$phid]->renderLink();
       }
       $task_list = phutil_implode_html(phutil_tag('br'), $task_list);
       $props['Tasks'] = $task_list;
     }
 
     return $props;
   }
 
   private function buildComments(PhabricatorRepositoryCommit $commit) {
-    $viewer = $this->getRequest()->getUser();
-
-    $xactions = id(new PhabricatorAuditTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($commit->getPHID()))
-      ->needComments(true)
-      ->execute();
+    $timeline = $this->buildTransactionTimeline(
+      $commit,
+      new PhabricatorAuditTransactionQuery());
+    $xactions = $timeline->getTransactions();
 
     $path_ids = array();
     foreach ($xactions as $xaction) {
       if ($xaction->hasComment()) {
         $path_id = $xaction->getComment()->getPathID();
         if ($path_id) {
           $path_ids[] = $path_id;
         }
       }
     }
 
     $path_map = array();
     if ($path_ids) {
       $path_map = id(new DiffusionPathQuery())
         ->withPathIDs($path_ids)
         ->execute();
       $path_map = ipull($path_map, 'path', 'id');
     }
 
-    return id(new PhabricatorAuditTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($commit->getPHID())
-      ->setPathMap($path_map)
-      ->setTransactions($xactions);
+    return $timeline->setPathMap($path_map);
   }
 
   private function renderAddCommentPanel(
     PhabricatorRepositoryCommit $commit,
     array $audit_requests) {
     assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest');
 
     $request = $this->getRequest();
     $user = $request->getUser();
 
     if (!$user->isLoggedIn()) {
       return id(new PhabricatorApplicationTransactionCommentView())
         ->setUser($user)
         ->setRequestURI($request->getRequestURI());
     }
 
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
 
     $pane_id = celerity_generate_unique_node_id();
     Javelin::initBehavior(
       'differential-keyboard-navigation',
       array(
         'haunt' => $pane_id,
       ));
 
     $draft = id(new PhabricatorDraft())->loadOneWhere(
       'authorPHID = %s AND draftKey = %s',
       $user->getPHID(),
       'diffusion-audit-'.$commit->getID());
     if ($draft) {
       $draft = $draft->getDraft();
     } else {
       $draft = null;
     }
 
     $actions = $this->getAuditActions($commit, $audit_requests);
 
     $form = id(new AphrontFormView())
       ->setUser($user)
       ->setAction('/audit/addcomment/')
       ->addHiddenInput('commit', $commit->getPHID())
       ->appendChild(
         id(new AphrontFormSelectControl())
           ->setLabel(pht('Action'))
           ->setName('action')
           ->setID('audit-action')
           ->setOptions($actions))
       ->appendChild(
         id(new AphrontFormTokenizerControl())
           ->setLabel(pht('Add Auditors'))
           ->setName('auditors')
           ->setControlID('add-auditors')
           ->setControlStyle('display: none')
           ->setID('add-auditors-tokenizer')
           ->setDisableBehavior(true))
       ->appendChild(
         id(new AphrontFormTokenizerControl())
           ->setLabel(pht('Add CCs'))
           ->setName('ccs')
           ->setControlID('add-ccs')
           ->setControlStyle('display: none')
           ->setID('add-ccs-tokenizer')
           ->setDisableBehavior(true))
       ->appendChild(
         id(new PhabricatorRemarkupControl())
           ->setLabel(pht('Comments'))
           ->setName('content')
           ->setValue($draft)
           ->setID('audit-content')
           ->setUser($user))
       ->appendChild(
         id(new AphrontFormSubmitControl())
           ->setValue(pht('Submit')));
 
     $header = new PHUIHeaderView();
     $header->setHeader(
       $is_serious ? pht('Audit Commit') : pht('Creative Accounting'));
 
     require_celerity_resource('phabricator-transaction-view-css');
 
     $mailable_source = new PhabricatorMetaMTAMailableDatasource();
     $auditor_source = new DiffusionAuditorDatasource();
 
     Javelin::initBehavior(
       'differential-add-reviewers-and-ccs',
       array(
         'dynamic' => array(
           'add-auditors-tokenizer' => array(
             'actions' => array('add_auditors' => 1),
             'src' => $auditor_source->getDatasourceURI(),
             'row' => 'add-auditors',
             'placeholder' => $auditor_source->getPlaceholderText(),
           ),
           'add-ccs-tokenizer' => array(
             'actions' => array('add_ccs' => 1),
             'src' => $mailable_source->getDatasourceURI(),
             'row' => 'add-ccs',
             'placeholder' => $mailable_source->getPlaceholderText(),
           ),
         ),
         'select' => 'audit-action',
       ));
 
     Javelin::initBehavior('differential-feedback-preview', array(
       'uri'       => '/audit/preview/'.$commit->getID().'/',
       'preview'   => 'audit-preview',
       'content'   => 'audit-content',
       'action'    => 'audit-action',
       'previewTokenizers' => array(
         'auditors' => 'add-auditors-tokenizer',
         'ccs'      => 'add-ccs-tokenizer',
       ),
       'inline'     => 'inline-comment-preview',
       'inlineuri'  => '/diffusion/inline/preview/'.$commit->getPHID().'/',
     ));
 
     $loading = phutil_tag_div(
       'aphront-panel-preview-loading-text',
       pht('Loading preview...'));
 
     $preview_panel = phutil_tag_div(
       'aphront-panel-preview aphront-panel-flush',
       array(
         phutil_tag('div', array('id' => 'audit-preview'), $loading),
         phutil_tag('div', array('id' => 'inline-comment-preview')),
       ));
 
     // TODO: This is pretty awkward, unify the CSS between Diffusion and
     // Differential better.
     require_celerity_resource('differential-core-view-css');
 
     $anchor = id(new PhabricatorAnchorView())
       ->setAnchorName('comment')
       ->setNavigationMarker(true)
       ->render();
 
     $comment_box = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->appendChild($form);
 
     return phutil_tag(
       'div',
       array(
         'id' => $pane_id,
       ),
       phutil_tag_div(
         'differential-add-comment-panel',
         array($anchor, $comment_box, $preview_panel)));
   }
 
   /**
    * Return a map of available audit actions for rendering into a <select />.
    * This shows the user valid actions, and does not show nonsense/invalid
    * actions (like closing an already-closed commit, or resigning from a commit
    * you have no association with).
    */
   private function getAuditActions(
     PhabricatorRepositoryCommit $commit,
     array $audit_requests) {
     assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest');
     $user = $this->getRequest()->getUser();
 
     $user_is_author = ($commit->getAuthorPHID() == $user->getPHID());
 
     $user_request = null;
     foreach ($audit_requests as $audit_request) {
       if ($audit_request->getAuditorPHID() == $user->getPHID()) {
         $user_request = $audit_request;
         break;
       }
     }
 
     $actions = array();
     $actions[PhabricatorAuditActionConstants::COMMENT] = true;
     $actions[PhabricatorAuditActionConstants::ADD_CCS] = true;
     $actions[PhabricatorAuditActionConstants::ADD_AUDITORS] = true;
 
     // We allow you to accept your own commits. A use case here is that you
     // notice an issue with your own commit and "Raise Concern" as an indicator
     // to other auditors that you're on top of the issue, then later resolve it
     // and "Accept". You can not accept on behalf of projects or packages,
     // however.
     $actions[PhabricatorAuditActionConstants::ACCEPT]  = true;
     $actions[PhabricatorAuditActionConstants::CONCERN] = true;
 
 
     // To resign, a user must have authority on some request and not be the
     // commit's author.
     if (!$user_is_author) {
       $may_resign = false;
 
       $authority_map = array_fill_keys($this->auditAuthorityPHIDs, true);
       foreach ($audit_requests as $request) {
         if (empty($authority_map[$request->getAuditorPHID()])) {
           continue;
         }
         $may_resign = true;
         break;
       }
 
       // If the user has already resigned, don't show "Resign...".
       $status_resigned = PhabricatorAuditStatusConstants::RESIGNED;
       if ($user_request) {
         if ($user_request->getAuditStatus() == $status_resigned) {
           $may_resign = false;
         }
       }
 
       if ($may_resign) {
         $actions[PhabricatorAuditActionConstants::RESIGN] = true;
       }
     }
 
     $status_concern = PhabricatorAuditCommitStatusConstants::CONCERN_RAISED;
     $concern_raised = ($commit->getAuditStatus() == $status_concern);
     $can_close_option = PhabricatorEnv::getEnvConfig(
       'audit.can-author-close-audit');
     if ($can_close_option && $user_is_author && $concern_raised) {
       $actions[PhabricatorAuditActionConstants::CLOSE] = true;
     }
 
     foreach ($actions as $constant => $ignored) {
       $actions[$constant] =
         PhabricatorAuditActionConstants::getActionName($constant);
     }
 
     return $actions;
   }
 
   private function buildMergesTable(PhabricatorRepositoryCommit $commit) {
     $drequest = $this->getDiffusionRequest();
     $limit = 50;
 
     $merges = array();
     try {
       $merges = $this->callConduitWithDiffusionRequest(
         'diffusion.mergedcommitsquery',
         array(
           'commit' => $drequest->getCommit(),
           'limit' => $limit + 1,
         ));
     } catch (ConduitException $ex) {
       if ($ex->getMessage() != 'ERR-UNSUPPORTED-VCS') {
         throw $ex;
       }
     }
 
     if (!$merges) {
       return null;
     }
 
     $caption = null;
     if (count($merges) > $limit) {
       $merges = array_slice($merges, 0, $limit);
       $caption =
         "This commit merges more than {$limit} changes. Only the first ".
         "{$limit} are shown.";
     }
 
     $history_table = new DiffusionHistoryTableView();
     $history_table->setUser($this->getRequest()->getUser());
     $history_table->setDiffusionRequest($drequest);
     $history_table->setHistory($merges);
     $history_table->loadRevisions();
 
     $phids = $history_table->getRequiredHandlePHIDs();
     $handles = $this->loadViewerHandles($phids);
     $history_table->setHandles($handles);
 
     $panel = new AphrontPanelView();
     $panel->setHeader(pht('Merged Changes'));
     $panel->setCaption($caption);
     $panel->appendChild($history_table);
     $panel->setNoBackground();
 
     return $panel;
   }
 
   private function renderHeadsupActionList(
     PhabricatorRepositoryCommit $commit,
     PhabricatorRepository $repository) {
 
     $request = $this->getRequest();
     $user = $request->getUser();
 
     $actions = id(new PhabricatorActionListView())
       ->setUser($user)
       ->setObject($commit)
       ->setObjectURI($request->getRequestURI());
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $user,
       $commit,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $uri = '/diffusion/'.$repository->getCallsign().'/commit/'.
            $commit->getCommitIdentifier().'/edit/';
 
     $action = id(new PhabricatorActionView())
       ->setName(pht('Edit Commit'))
       ->setHref($uri)
       ->setIcon('fa-pencil')
       ->setDisabled(!$can_edit)
       ->setWorkflow(!$can_edit);
     $actions->addAction($action);
 
     require_celerity_resource('phabricator-object-selector-css');
     require_celerity_resource('javelin-behavior-phabricator-object-selector');
 
     $maniphest = 'PhabricatorManiphestApplication';
     if (PhabricatorApplication::isClassInstalled($maniphest)) {
       $action = id(new PhabricatorActionView())
         ->setName(pht('Edit Maniphest Tasks'))
         ->setIcon('fa-anchor')
         ->setHref('/search/attach/'.$commit->getPHID().'/TASK/edge/')
         ->setWorkflow(true)
         ->setDisabled(!$can_edit);
       $actions->addAction($action);
     }
 
     $action = id(new PhabricatorActionView())
       ->setName(pht('Download Raw Diff'))
       ->setHref($request->getRequestURI()->alter('diff', true))
       ->setIcon('fa-download');
     $actions->addAction($action);
 
     return $actions;
   }
 
   private function buildRefs(DiffusionRequest $request) {
     // this is git-only, so save a conduit round trip and just get out of
     // here if the repository isn't git
     $type_git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
     $repository = $request->getRepository();
     if ($repository->getVersionControlSystem() != $type_git) {
       return null;
     }
 
     $results = $this->callConduitWithDiffusionRequest(
       'diffusion.refsquery',
       array('commit' => $request->getCommit()));
     $ref_links = array();
     foreach ($results as $ref_data) {
       $ref_links[] = phutil_tag('a',
         array('href' => $ref_data['href']),
         $ref_data['ref']);
     }
     return phutil_implode_html(', ', $ref_links);
   }
 
   private function buildRawDiffResponse(DiffusionRequest $drequest) {
     $raw_diff = $this->callConduitWithDiffusionRequest(
       'diffusion.rawdiffquery',
       array(
         'commit' => $drequest->getCommit(),
         'path' => $drequest->getPath(),
       ));
 
     $file = PhabricatorFile::buildFromFileDataOrHash(
       $raw_diff,
       array(
         'name' => $drequest->getCommit().'.diff',
         'ttl' => (60 * 60 * 24),
         'viewPolicy' => PhabricatorPolicies::POLICY_NOONE,
       ));
 
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
       $file->attachToObject($drequest->getRepository()->getPHID());
     unset($unguarded);
 
     return $file->getRedirectResponse();
   }
 
   private function renderAuditStatusView(array $audit_requests) {
     assert_instances_of($audit_requests, 'PhabricatorRepositoryAuditRequest');
 
     $phids = mpull($audit_requests, 'getAuditorPHID');
     $this->loadHandles($phids);
 
     $authority_map = array_fill_keys($this->auditAuthorityPHIDs, true);
 
     $view = new PHUIStatusListView();
     foreach ($audit_requests as $request) {
       $code = $request->getAuditStatus();
       $item = new PHUIStatusItemView();
       $item->setIcon(
         PhabricatorAuditStatusConstants::getStatusIcon($code),
         PhabricatorAuditStatusConstants::getStatusColor($code),
         PhabricatorAuditStatusConstants::getStatusName($code));
 
       $note = array();
       foreach ($request->getAuditReasons() as $reason) {
         $note[] = phutil_tag('div', array(), $reason);
       }
       $item->setNote($note);
 
       $auditor_phid = $request->getAuditorPHID();
       $target = $this->getHandle($auditor_phid)->renderLink();
       $item->setTarget($target);
 
       if (isset($authority_map[$auditor_phid])) {
         $item->setHighlighted(true);
       }
 
       $view->addItem($item);
     }
 
     return $view;
   }
 
   private function linkBugtraq($corpus) {
     $url = PhabricatorEnv::getEnvConfig('bugtraq.url');
     if (!strlen($url)) {
       return $corpus;
     }
 
     $regexes = PhabricatorEnv::getEnvConfig('bugtraq.logregex');
     if (!$regexes) {
       return $corpus;
     }
 
     $parser = id(new PhutilBugtraqParser())
       ->setBugtraqPattern("[[ {$url} | %BUGID% ]]")
       ->setBugtraqCaptureExpression(array_shift($regexes));
 
     $select = array_shift($regexes);
     if ($select) {
       $parser->setBugtraqSelectExpression($select);
     }
 
     return $parser->processCorpus($corpus);
   }
 
 }
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
index 8cf00006f8..d955b13a08 100644
--- a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
@@ -1,1156 +1,1139 @@
 <?php
 
 final class DiffusionRepositoryEditMainController
   extends DiffusionRepositoryEditController {
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $drequest = $this->diffusionRequest;
     $repository = $drequest->getRepository();
 
     PhabricatorPolicyFilter::requireCapability(
       $viewer,
       $repository,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $is_svn = false;
     $is_git = false;
     $is_hg = false;
     switch ($repository->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         $is_git = true;
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         $is_svn = true;
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         $is_hg = true;
         break;
     }
 
     $has_branches = ($is_git || $is_hg);
     $has_local = $repository->usesLocalWorkingCopy();
 
     $crumbs = $this->buildApplicationCrumbs($is_main = true);
 
     $title = pht('Edit %s', $repository->getName());
 
     $header = id(new PHUIHeaderView())
       ->setHeader($title);
     if ($repository->isTracked()) {
       $header->setStatus('fa-check', 'bluegrey', pht('Active'));
     } else {
       $header->setStatus('fa-ban', 'dark', pht('Inactive'));
     }
 
     $basic_actions = $this->buildBasicActions($repository);
     $basic_properties =
       $this->buildBasicProperties($repository, $basic_actions);
 
     $policy_actions = $this->buildPolicyActions($repository);
     $policy_properties =
       $this->buildPolicyProperties($repository, $policy_actions);
 
     $remote_properties = null;
     if (!$repository->isHosted()) {
       $remote_properties = $this->buildRemoteProperties(
         $repository,
         $this->buildRemoteActions($repository));
     }
 
     $encoding_actions = $this->buildEncodingActions($repository);
     $encoding_properties =
       $this->buildEncodingProperties($repository, $encoding_actions);
 
     $hosting_properties = $this->buildHostingProperties(
       $repository,
       $this->buildHostingActions($repository));
 
 
     $branches_properties = null;
     if ($has_branches) {
       $branches_properties = $this->buildBranchesProperties(
         $repository,
         $this->buildBranchesActions($repository));
     }
 
     $subversion_properties = null;
     if ($is_svn) {
       $subversion_properties = $this->buildSubversionProperties(
         $repository,
         $this->buildSubversionActions($repository));
     }
 
     $local_properties = null;
     if ($has_local) {
       $local_properties = $this->buildLocalProperties(
         $repository,
         $this->buildLocalActions($repository));
     }
 
     $actions_properties = $this->buildActionsProperties(
       $repository,
       $this->buildActionsActions($repository));
 
-    $xactions = id(new PhabricatorRepositoryTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($repository->getPHID()))
-      ->execute();
-
-    $engine = id(new PhabricatorMarkupEngine())
-      ->setViewer($viewer);
-    foreach ($xactions as $xaction) {
-      if ($xaction->getComment()) {
-        $engine->addObject(
-          $xaction->getComment(),
-          PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
-      }
-    }
-    $engine->process();
-
-    $xaction_view = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($repository->getPHID())
-      ->setTransactions($xactions)
-      ->setMarkupEngine($engine);
+    $timeline = $this->buildTransactionTimeline(
+      $repository,
+      new PhabricatorRepositoryTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     $boxes = array();
 
     $boxes[] = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->addPropertyList($basic_properties);
 
     $boxes[] = id(new PHUIObjectBoxView())
       ->setHeaderText(pht('Policies'))
       ->addPropertyList($policy_properties);
 
     $boxes[] = id(new PHUIObjectBoxView())
       ->setHeaderText(pht('Hosting'))
       ->addPropertyList($hosting_properties);
 
     if ($repository->canMirror()) {
       $mirror_actions = $this->buildMirrorActions($repository);
       $mirror_properties = $this->buildMirrorProperties(
         $repository,
         $mirror_actions);
 
       $mirrors = id(new PhabricatorRepositoryMirrorQuery())
         ->setViewer($viewer)
         ->withRepositoryPHIDs(array($repository->getPHID()))
         ->execute();
 
       $mirror_list = $this->buildMirrorList($repository, $mirrors);
 
       $boxes[] = id(new PhabricatorAnchorView())->setAnchorName('mirrors');
 
       $boxes[] = id(new PHUIObjectBoxView())
         ->setHeaderText(pht('Mirrors'))
         ->addPropertyList($mirror_properties);
 
       $boxes[] = $mirror_list;
     }
 
     if ($remote_properties) {
       $boxes[] = id(new PHUIObjectBoxView())
         ->setHeaderText(pht('Remote'))
         ->addPropertyList($remote_properties);
     }
 
     if ($local_properties) {
       $boxes[] = id(new PHUIObjectBoxView())
         ->setHeaderText(pht('Local'))
         ->addPropertyList($local_properties);
     }
 
     $boxes[] = id(new PHUIObjectBoxView())
       ->setHeaderText(pht('Text Encoding'))
       ->addPropertyList($encoding_properties);
 
     if ($branches_properties) {
       $boxes[] = id(new PHUIObjectBoxView())
         ->setHeaderText(pht('Branches'))
         ->addPropertyList($branches_properties);
     }
 
     if ($subversion_properties) {
       $boxes[] = id(new PHUIObjectBoxView())
         ->setHeaderText(pht('Subversion'))
         ->addPropertyList($subversion_properties);
     }
 
     $boxes[] = id(new PHUIObjectBoxView())
       ->setHeaderText(pht('Actions'))
       ->addPropertyList($actions_properties);
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $boxes,
-        $xaction_view,
+        $timeline,
       ),
       array(
         'title' => $title,
       ));
   }
 
   private function buildBasicActions(PhabricatorRepository $repository) {
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($viewer);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Basic Information'))
       ->setHref($this->getRepositoryControllerURI($repository, 'edit/basic/'));
     $view->addAction($edit);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-refresh')
       ->setName(pht('Update Now'))
       ->setWorkflow(true)
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/update/'));
     $view->addAction($edit);
 
     $activate = id(new PhabricatorActionView())
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/activate/'))
       ->setWorkflow(true);
 
     if ($repository->isTracked()) {
       $activate
         ->setIcon('fa-pause')
         ->setName(pht('Deactivate Repository'));
     } else {
       $activate
         ->setIcon('fa-play')
         ->setName(pht('Activate Repository'));
     }
 
     $view->addAction($activate);
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Delete Repository'))
         ->setIcon('fa-times')
         ->setHref(
           $this->getRepositoryControllerURI($repository, 'edit/delete/'))
         ->setDisabled(true)
         ->setWorkflow(true));
 
     return $view;
   }
 
   private function buildBasicProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setActionList($actions);
 
     $type = PhabricatorRepositoryType::getNameForRepositoryType(
       $repository->getVersionControlSystem());
 
     $view->addProperty(pht('Type'), $type);
     $view->addProperty(pht('Callsign'), $repository->getCallsign());
 
 
     $clone_name = $repository->getDetail('clone-name');
 
     if ($repository->isHosted()) {
       $view->addProperty(
         pht('Clone/Checkout As'),
         $clone_name
           ? $clone_name.'/'
           : phutil_tag('em', array(), $repository->getCloneName().'/'));
     }
 
     $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
       $repository->getPHID(),
       PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
     if ($project_phids) {
       $this->loadHandles($project_phids);
       $project_text = $this->renderHandlesForPHIDs($project_phids);
     } else {
       $project_text = phutil_tag('em', array(), pht('None'));
     }
     $view->addProperty(
       pht('Projects'),
       $project_text);
 
     $view->addProperty(
       pht('Status'),
       $this->buildRepositoryStatus($repository));
 
     $view->addProperty(
       pht('Update Frequency'),
       $this->buildRepositoryUpdateInterval($repository));
 
     $description = $repository->getDetail('description');
     $view->addSectionHeader(pht('Description'));
     if (!strlen($description)) {
       $description = phutil_tag('em', array(), pht('No description provided.'));
     } else {
       $description = PhabricatorMarkupEngine::renderOneObject(
         $repository,
         'description',
         $viewer);
     }
     $view->addTextContent($description);
 
     return $view;
   }
 
   private function buildEncodingActions(PhabricatorRepository $repository) {
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($viewer);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Text Encoding'))
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/encoding/'));
     $view->addAction($edit);
 
     return $view;
   }
 
   private function buildEncodingProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setActionList($actions);
 
     $encoding = $repository->getDetail('encoding');
     if (!$encoding) {
       $encoding = phutil_tag('em', array(), pht('Use Default (UTF-8)'));
     }
 
     $view->addProperty(pht('Encoding'), $encoding);
 
     return $view;
   }
 
   private function buildPolicyActions(PhabricatorRepository $repository) {
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($viewer);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Policies'))
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/policy/'));
     $view->addAction($edit);
 
     return $view;
   }
 
   private function buildPolicyProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setActionList($actions);
 
     $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
       $viewer,
       $repository);
 
     $view->addProperty(
       pht('Visible To'),
       $descriptions[PhabricatorPolicyCapability::CAN_VIEW]);
 
     $view->addProperty(
       pht('Editable By'),
       $descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
 
     $pushable = $repository->isHosted()
       ? $descriptions[DiffusionPushCapability::CAPABILITY]
       : phutil_tag('em', array(), pht('Not a Hosted Repository'));
     $view->addProperty(pht('Pushable By'), $pushable);
 
     return $view;
   }
 
   private function buildBranchesActions(PhabricatorRepository $repository) {
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($viewer);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Branches'))
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/branches/'));
     $view->addAction($edit);
 
     return $view;
   }
 
   private function buildBranchesProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setActionList($actions);
 
     $default_branch = nonempty(
       $repository->getHumanReadableDetail('default-branch'),
       phutil_tag('em', array(), $repository->getDefaultBranch()));
     $view->addProperty(pht('Default Branch'), $default_branch);
 
     $track_only = nonempty(
       $repository->getHumanReadableDetail('branch-filter', array()),
       phutil_tag('em', array(), pht('Track All Branches')));
     $view->addProperty(pht('Track Only'), $track_only);
 
     $autoclose_only = nonempty(
       $repository->getHumanReadableDetail('close-commits-filter', array()),
       phutil_tag('em', array(), pht('Autoclose On All Branches')));
 
     if ($repository->getDetail('disable-autoclose')) {
       $autoclose_only = phutil_tag('em', array(), pht('Disabled'));
     }
 
     $view->addProperty(pht('Autoclose Only'), $autoclose_only);
 
     return $view;
   }
 
   private function buildSubversionActions(PhabricatorRepository $repository) {
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($viewer);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Subversion Info'))
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/subversion/'));
     $view->addAction($edit);
 
     return $view;
   }
 
   private function buildSubversionProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setActionList($actions);
 
     $svn_uuid = nonempty(
       $repository->getUUID(),
       phutil_tag('em', array(), pht('Not Configured')));
     $view->addProperty(pht('Subversion UUID'), $svn_uuid);
 
     $svn_subpath = nonempty(
       $repository->getHumanReadableDetail('svn-subpath'),
       phutil_tag('em', array(), pht('Import Entire Repository')));
     $view->addProperty(pht('Import Only'), $svn_subpath);
 
     return $view;
   }
 
   private function buildActionsActions(PhabricatorRepository $repository) {
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($viewer);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Actions'))
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/actions/'));
     $view->addAction($edit);
 
     return $view;
   }
 
   private function buildActionsProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setActionList($actions);
 
     $notify = $repository->getDetail('herald-disabled')
       ? pht('Off')
       : pht('On');
     $notify = phutil_tag('em', array(), $notify);
     $view->addProperty(pht('Publish/Notify'), $notify);
 
     $autoclose = $repository->getDetail('disable-autoclose')
       ? pht('Off')
       : pht('On');
     $autoclose = phutil_tag('em', array(), $autoclose);
     $view->addProperty(pht('Autoclose'), $autoclose);
 
     return $view;
   }
 
   private function buildRemoteActions(PhabricatorRepository $repository) {
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($viewer);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Remote'))
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/remote/'));
     $view->addAction($edit);
 
     return $view;
   }
 
   private function buildRemoteProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setActionList($actions);
 
     $view->addProperty(
       pht('Remote URI'),
       $repository->getHumanReadableDetail('remote-uri'));
 
     $credential_phid = $repository->getCredentialPHID();
     if ($credential_phid) {
       $this->loadHandles(array($credential_phid));
       $view->addProperty(
         pht('Credential'),
         $this->getHandle($credential_phid)->renderLink());
     }
 
     return $view;
   }
 
   private function buildLocalActions(PhabricatorRepository $repository) {
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($viewer);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Local'))
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/local/'));
     $view->addAction($edit);
 
     return $view;
   }
 
   private function buildLocalProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setActionList($actions);
 
     $view->addProperty(
       pht('Local Path'),
       $repository->getHumanReadableDetail('local-path'));
 
     return $view;
   }
 
   private function buildHostingActions(PhabricatorRepository $repository) {
     $user = $this->getRequest()->getUser();
 
     $view = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($user);
 
     $edit = id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Hosting'))
       ->setHref(
         $this->getRepositoryControllerURI($repository, 'edit/hosting/'));
     $view->addAction($edit);
 
     if ($repository->canAllowDangerousChanges()) {
       if ($repository->shouldAllowDangerousChanges()) {
         $changes = id(new PhabricatorActionView())
           ->setIcon('fa-shield')
           ->setName(pht('Prevent Dangerous Changes'))
           ->setHref(
             $this->getRepositoryControllerURI($repository, 'edit/dangerous/'))
           ->setWorkflow(true);
       } else {
         $changes = id(new PhabricatorActionView())
           ->setIcon('fa-bullseye')
           ->setName(pht('Allow Dangerous Changes'))
           ->setHref(
             $this->getRepositoryControllerURI($repository, 'edit/dangerous/'))
           ->setWorkflow(true);
       }
       $view->addAction($changes);
     }
 
     return $view;
   }
 
   private function buildHostingProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $user = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($user)
       ->setActionList($actions);
 
     $hosting = $repository->isHosted()
       ? pht('Hosted on Phabricator')
       : pht('Hosted Elsewhere');
     $view->addProperty(pht('Hosting'), phutil_tag('em', array(), $hosting));
 
     $view->addProperty(
       pht('Serve over HTTP'),
       phutil_tag(
         'em',
         array(),
         PhabricatorRepository::getProtocolAvailabilityName(
           $repository->getServeOverHTTP())));
 
     $view->addProperty(
       pht('Serve over SSH'),
       phutil_tag(
         'em',
         array(),
         PhabricatorRepository::getProtocolAvailabilityName(
           $repository->getServeOverSSH())));
 
     if ($repository->canAllowDangerousChanges()) {
       if ($repository->shouldAllowDangerousChanges()) {
         $description = pht('Allowed');
       } else {
         $description = pht('Not Allowed');
       }
 
       $view->addProperty(
         pht('Dangerous Changes'),
         $description);
     }
 
     return $view;
   }
 
   private function buildRepositoryStatus(
     PhabricatorRepository $repository) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = new PHUIStatusListView();
 
     $messages = id(new PhabricatorRepositoryStatusMessage())
       ->loadAllWhere('repositoryID = %d', $repository->getID());
     $messages = mpull($messages, null, 'getStatusType');
 
     if ($repository->isTracked()) {
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
           ->setTarget(pht('Repository Active')));
     } else {
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey')
           ->setTarget(pht('Repository Inactive'))
           ->setNote(
             pht('Activate this repository to begin or resume import.')));
       return $view;
     }
 
     $binaries = array();
     $svnlook_check = false;
     switch ($repository->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         $binaries[] = 'git';
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         $binaries[] = 'svn';
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         $binaries[] = 'hg';
         break;
     }
 
     if ($repository->isHosted()) {
       if ($repository->getServeOverHTTP() != PhabricatorRepository::SERVE_OFF) {
         switch ($repository->getVersionControlSystem()) {
           case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
             $binaries[] = 'git-http-backend';
             break;
           case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
             $binaries[] = 'svnserve';
             $binaries[] = 'svnadmin';
             $binaries[] = 'svnlook';
             $svnlook_check = true;
             break;
           case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
             $binaries[] = 'hg';
             break;
         }
       }
       if ($repository->getServeOverSSH() != PhabricatorRepository::SERVE_OFF) {
         switch ($repository->getVersionControlSystem()) {
           case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
             $binaries[] = 'git-receive-pack';
             $binaries[] = 'git-upload-pack';
             break;
           case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
             $binaries[] = 'svnserve';
             $binaries[] = 'svnadmin';
             $binaries[] = 'svnlook';
             $svnlook_check = true;
             break;
           case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
             $binaries[] = 'hg';
             break;
         }
       }
     }
 
     $binaries = array_unique($binaries);
     foreach ($binaries as $binary) {
       $where = Filesystem::resolveBinary($binary);
       if (!$where) {
         $view->addItem(
           id(new PHUIStatusItemView())
             ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
             ->setTarget(
               pht('Missing Binary %s', phutil_tag('tt', array(), $binary)))
             ->setNote(pht(
               "Unable to find this binary in the webserver's PATH. You may ".
               "need to configure %s.",
               $this->getEnvConfigLink())));
       } else {
         $view->addItem(
           id(new PHUIStatusItemView())
             ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
             ->setTarget(
               pht('Found Binary %s', phutil_tag('tt', array(), $binary)))
             ->setNote(phutil_tag('tt', array(), $where)));
       }
     }
 
     // This gets checked generically above. However, for svn commit hooks, we
     // need this to be in environment.append-paths because subversion strips
     // PATH.
     if ($svnlook_check) {
       $where = Filesystem::resolveBinary('svnlook');
       if ($where) {
         $path = substr($where, 0, strlen($where) - strlen('svnlook'));
         $dirs = PhabricatorEnv::getEnvConfig('environment.append-paths');
         $in_path = false;
         foreach ($dirs as $dir) {
           if (Filesystem::isDescendant($path, $dir)) {
             $in_path = true;
             break;
           }
         }
         if (!$in_path) {
           $view->addItem(
             id(new PHUIStatusItemView())
             ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
             ->setTarget(
               pht('Missing Binary %s', phutil_tag('tt', array(), $binary)))
             ->setNote(pht(
                 'Unable to find this binary in `environment.append-paths`. '.
                 'You need to configure %s and include %s.',
                 $this->getEnvConfigLink(),
                 $path)));
         }
       }
     }
 
     $doc_href = PhabricatorEnv::getDocLink('Managing Daemons with phd');
 
     $daemon_instructions = pht(
       'Use %s to start daemons. See %s.',
       phutil_tag('tt', array(), 'bin/phd start'),
       phutil_tag(
         'a',
         array(
           'href' => $doc_href,
         ),
         pht('Managing Daemons with phd')));
 
 
     $pull_daemon = id(new PhabricatorDaemonLogQuery())
       ->setViewer(PhabricatorUser::getOmnipotentUser())
       ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
       ->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon'))
       ->setLimit(1)
       ->execute();
 
     if ($pull_daemon) {
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
           ->setTarget(pht('Pull Daemon Running')));
     } else {
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
           ->setTarget(pht('Pull Daemon Not Running'))
           ->setNote($daemon_instructions));
     }
 
 
     $task_daemon = id(new PhabricatorDaemonLogQuery())
       ->setViewer(PhabricatorUser::getOmnipotentUser())
       ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
       ->withDaemonClasses(array('PhabricatorTaskmasterDaemon'))
       ->setLimit(1)
       ->execute();
     if ($task_daemon) {
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
           ->setTarget(pht('Task Daemon Running')));
     } else {
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
           ->setTarget(pht('Task Daemon Not Running'))
           ->setNote($daemon_instructions));
     }
 
     if ($repository->usesLocalWorkingCopy()) {
       $local_parent = dirname($repository->getLocalPath());
       if (Filesystem::pathExists($local_parent)) {
         $view->addItem(
           id(new PHUIStatusItemView())
             ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
             ->setTarget(pht('Storage Directory OK'))
             ->setNote(phutil_tag('tt', array(), $local_parent)));
       } else {
         $view->addItem(
           id(new PHUIStatusItemView())
             ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
             ->setTarget(pht('No Storage Directory'))
             ->setNote(
               pht(
                 'Storage directory %s does not exist, or is not readable by '.
                 'the webserver. Create this directory or make it readable.',
                 phutil_tag('tt', array(), $local_parent))));
         return $view;
       }
 
       $local_path = $repository->getLocalPath();
       $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT);
       if ($message) {
         switch ($message->getStatusCode()) {
           case PhabricatorRepositoryStatusMessage::CODE_ERROR:
             $view->addItem(
               id(new PHUIStatusItemView())
               ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
                 ->setTarget(pht('Initialization Error'))
                 ->setNote($message->getParameter('message')));
             return $view;
           case PhabricatorRepositoryStatusMessage::CODE_OKAY:
               if (Filesystem::pathExists($local_path)) {
                 $view->addItem(
                   id(new PHUIStatusItemView())
                     ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
                     ->setTarget(pht('Working Copy OK'))
                     ->setNote(phutil_tag('tt', array(), $local_path)));
               } else {
                 $view->addItem(
                   id(new PHUIStatusItemView())
                     ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
                     ->setTarget(pht('Working Copy Error'))
                     ->setNote(
                       pht(
                         'Working copy %s has been deleted, or is not '.
                         'readable by the webserver. Make this directory '.
                         'readable. If it has been deleted, the daemons should '.
                         'restore it automatically.',
                         phutil_tag('tt', array(), $local_path))));
                 return $view;
               }
             break;
           case PhabricatorRepositoryStatusMessage::CODE_WORKING:
             $view->addItem(
               id(new PHUIStatusItemView())
                 ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
                 ->setTarget(pht('Initializing Working Copy'))
                 ->setNote(pht('Daemons are initializing the working copy.')));
             return $view;
           default:
             $view->addItem(
               id(new PHUIStatusItemView())
                 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
                 ->setTarget(pht('Unknown Init Status'))
                 ->setNote($message->getStatusCode()));
             return $view;
         }
       } else {
         $view->addItem(
           id(new PHUIStatusItemView())
             ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
             ->setTarget(pht('No Working Copy Yet'))
             ->setNote(
               pht('Waiting for daemons to build a working copy.')));
         return $view;
       }
     }
 
     $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH);
     if ($message) {
       switch ($message->getStatusCode()) {
         case PhabricatorRepositoryStatusMessage::CODE_ERROR:
           $view->addItem(
             id(new PHUIStatusItemView())
               ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
               ->setTarget(pht('Update Error'))
               ->setNote($message->getParameter('message')));
           return $view;
         case PhabricatorRepositoryStatusMessage::CODE_OKAY:
           $ago = (PhabricatorTime::getNow() - $message->getEpoch());
           $view->addItem(
             id(new PHUIStatusItemView())
               ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
               ->setTarget(pht('Updates OK'))
               ->setNote(
                 pht(
                   'Last updated %s (%s ago).',
                   phabricator_datetime($message->getEpoch(), $viewer),
                   phutil_format_relative_time_detailed($ago))));
           break;
       }
     } else {
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
           ->setTarget(pht('Waiting For Update'))
           ->setNote(
             pht('Waiting for daemons to read updates.')));
     }
 
     if ($repository->isImporting()) {
       $progress = queryfx_all(
         $repository->establishConnection('r'),
         'SELECT importStatus, count(*) N FROM %T WHERE repositoryID = %d
           GROUP BY importStatus',
         id(new PhabricatorRepositoryCommit())->getTableName(),
         $repository->getID());
 
       $done = 0;
       $total = 0;
       foreach ($progress as $row) {
         $total += $row['N'] * 4;
         $status = $row['importStatus'];
         if ($status & PhabricatorRepositoryCommit::IMPORTED_MESSAGE) {
           $done += $row['N'];
         }
         if ($status & PhabricatorRepositoryCommit::IMPORTED_CHANGE) {
           $done += $row['N'];
         }
         if ($status & PhabricatorRepositoryCommit::IMPORTED_OWNERS) {
           $done += $row['N'];
         }
         if ($status & PhabricatorRepositoryCommit::IMPORTED_HERALD) {
           $done += $row['N'];
         }
       }
 
       if ($total) {
         $percentage = 100 * ($done / $total);
       } else {
         $percentage = 0;
       }
 
       // Cap this at "99.99%", because it's confusing to users when the actual
       // fraction is "99.996%" and it rounds up to "100.00%".
       if ($percentage > 99.99) {
         $percentage = 99.99;
       }
 
       $percentage = sprintf('%.2f%%', $percentage);
 
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
           ->setTarget(pht('Importing'))
           ->setNote(
             pht('%s Complete', $percentage)));
     } else {
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
           ->setTarget(pht('Fully Imported')));
     }
 
     if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) {
       $view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_UP, 'indigo')
           ->setTarget(pht('Prioritized'))
           ->setNote(pht('This repository will be updated soon!')));
     }
 
     return $view;
   }
 
   private function buildRepositoryUpdateInterval(
     PhabricatorRepository $repository) {
 
     $smart_wait = $repository->loadUpdateInterval();
 
     $doc_href = PhabricatorEnv::getDoclink(
       'Diffusion User Guide: Repository Updates');
 
     return array(
       phutil_format_relative_time_detailed($smart_wait),
       " \xC2\xB7 ",
       phutil_tag(
         'a',
         array(
           'href' => $doc_href,
           'target' => '_blank',
         ),
         pht('Learn More')),
     );
   }
 
 
   private function buildMirrorActions(
     PhabricatorRepository $repository) {
 
     $viewer = $this->getRequest()->getUser();
 
     $mirror_actions = id(new PhabricatorActionListView())
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setUser($viewer);
 
     $new_mirror_uri = $this->getRepositoryControllerURI(
       $repository,
       'mirror/edit/');
 
     $mirror_actions->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Add Mirror'))
         ->setIcon('fa-plus')
         ->setHref($new_mirror_uri)
         ->setWorkflow(true));
 
     return $mirror_actions;
   }
 
   private function buildMirrorProperties(
     PhabricatorRepository $repository,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
 
     $mirror_properties = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setActionList($actions);
 
     $mirror_properties->addProperty(
       '',
       phutil_tag(
         'em',
         array(),
         pht('Automatically push changes into other remotes.')));
 
     return $mirror_properties;
   }
 
   private function buildMirrorList(
     PhabricatorRepository $repository,
     array $mirrors) {
     assert_instances_of($mirrors, 'PhabricatorRepositoryMirror');
 
     $mirror_list = id(new PHUIObjectItemListView())
       ->setNoDataString(pht('This repository has no configured mirrors.'));
 
     foreach ($mirrors as $mirror) {
       $item = id(new PHUIObjectItemView())
         ->setHeader($mirror->getRemoteURI());
 
       $edit_uri = $this->getRepositoryControllerURI(
         $repository,
         'mirror/edit/'.$mirror->getID().'/');
 
       $delete_uri = $this->getRepositoryControllerURI(
         $repository,
         'mirror/delete/'.$mirror->getID().'/');
 
       $item->addAction(
         id(new PHUIListItemView())
           ->setIcon('fa-pencil')
           ->setHref($edit_uri)
           ->setWorkflow(true));
 
       $item->addAction(
         id(new PHUIListItemView())
           ->setIcon('fa-times')
           ->setHref($delete_uri)
           ->setWorkflow(true));
 
       $mirror_list->addItem($item);
     }
 
     return $mirror_list;
   }
 
   private function getEnvConfigLink() {
     $config_href = '/config/edit/environment.append-paths/';
     return phutil_tag(
       'a',
       array(
         'href' => $config_href,
       ),
       'environment.append-paths');
   }
 
 }
diff --git a/src/applications/fund/controller/FundInitiativeViewController.php b/src/applications/fund/controller/FundInitiativeViewController.php
index c3c64b7556..f8e367f1a1 100644
--- a/src/applications/fund/controller/FundInitiativeViewController.php
+++ b/src/applications/fund/controller/FundInitiativeViewController.php
@@ -1,194 +1,190 @@
 <?php
 
 final class FundInitiativeViewController
   extends FundController {
 
   private $id;
 
   public function shouldAllowPublic() {
     return true;
   }
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $initiative = id(new FundInitiativeQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->id))
       ->executeOne();
     if (!$initiative) {
       return new Aphront404Response();
     }
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($initiative->getMonogram());
 
     $title = pht(
       '%s %s',
       $initiative->getMonogram(),
       $initiative->getName());
 
     if ($initiative->isClosed()) {
       $status_icon = 'fa-times';
       $status_color = 'bluegrey';
     } else {
       $status_icon = 'fa-check';
       $status_color = 'bluegrey';
     }
     $status_name = idx(
       FundInitiative::getStatusNameMap(),
       $initiative->getStatus());
 
     $header = id(new PHUIHeaderView())
       ->setObjectName($initiative->getMonogram())
       ->setHeader($initiative->getName())
       ->setUser($viewer)
       ->setPolicyObject($initiative)
       ->setStatus($status_icon, $status_color, $status_name);
 
     $properties = $this->buildPropertyListView($initiative);
     $actions = $this->buildActionListView($initiative);
     $properties->setActionList($actions);
     $crumbs->setActionList($actions);
 
     $box = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->appendChild($properties);
 
-    $xactions = id(new FundInitiativeTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($initiative->getPHID()))
-      ->execute();
 
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($initiative->getPHID())
-      ->setTransactions($xactions)
+    $timeline = $this->buildTransactionTimeline(
+      $initiative,
+      new FundInitiativeTransactionQuery());
+    $timeline
       ->setShouldTerminate(true);
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $box,
         $timeline,
       ),
       array(
         'title' => $title,
         'pageObjects' => array($initiative->getPHID()),
       ));
   }
 
   private function buildPropertyListView(FundInitiative $initiative) {
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($initiative);
 
     $owner_phid = $initiative->getOwnerPHID();
     $merchant_phid = $initiative->getMerchantPHID();
     $this->loadHandles(
       array(
         $owner_phid,
         $merchant_phid,
       ));
 
     $view->addProperty(
       pht('Owner'),
       $this->getHandle($owner_phid)->renderLink());
 
     $view->addProperty(
       pht('Payable to Merchant'),
       $this->getHandle($merchant_phid)->renderLink());
 
     $view->addProperty(
       pht('Total Funding'),
       $initiative->getTotalAsCurrency()->formatForDisplay());
 
     $view->invokeWillRenderEvent();
 
     $description = $initiative->getDescription();
     if (strlen($description)) {
       $description = PhabricatorMarkupEngine::renderOneObject(
         id(new PhabricatorMarkupOneOff())->setContent($description),
         'default',
         $viewer);
 
       $view->addSectionHeader(pht('Description'));
       $view->addTextContent($description);
     }
 
     $risks = $initiative->getRisks();
     if (strlen($risks)) {
       $risks = PhabricatorMarkupEngine::renderOneObject(
         id(new PhabricatorMarkupOneOff())->setContent($risks),
         'default',
         $viewer);
 
       $view->addSectionHeader(pht('Risks/Challenges'));
       $view->addTextContent($risks);
     }
 
     return $view;
   }
 
   private function buildActionListView(FundInitiative $initiative) {
     $viewer = $this->getRequest()->getUser();
     $id = $initiative->getID();
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $initiative,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $view = id(new PhabricatorActionListView())
       ->setUser($viewer)
       ->setObject($initiative);
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Edit Initiative'))
         ->setIcon('fa-pencil')
         ->setDisabled(!$can_edit)
         ->setWorkflow(!$can_edit)
         ->setHref($this->getApplicationURI("/edit/{$id}/")));
 
     if ($initiative->isClosed()) {
       $close_name = pht('Reopen Initiative');
       $close_icon = 'fa-check';
     } else {
       $close_name = pht('Close Initiative');
       $close_icon = 'fa-times';
     }
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName($close_name)
         ->setIcon($close_icon)
         ->setDisabled(!$can_edit)
         ->setWorkflow(true)
         ->setHref($this->getApplicationURI("/close/{$id}/")));
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Back Initiative'))
         ->setIcon('fa-money')
         ->setDisabled($initiative->isClosed())
         ->setWorkflow(true)
         ->setHref($this->getApplicationURI("/back/{$id}/")));
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('View Backers'))
         ->setIcon('fa-bank')
         ->setHref($this->getApplicationURI("/backers/{$id}/")));
 
     return $view;
   }
 
 }
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
index 6a3b3f9cd1..9fd6b0d2ef 100644
--- a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
@@ -1,537 +1,533 @@
 <?php
 
 final class HarbormasterBuildViewController
   extends HarbormasterController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $id = $this->id;
     $generation = $request->getInt('g');
 
     $build = id(new HarbormasterBuildQuery())
       ->setViewer($viewer)
       ->withIDs(array($id))
       ->executeOne();
     if (!$build) {
       return new Aphront404Response();
     }
 
     require_celerity_resource('harbormaster-css');
 
     $title = pht('Build %d', $id);
 
     $header = id(new PHUIHeaderView())
       ->setHeader($title)
       ->setUser($viewer)
       ->setPolicyObject($build);
 
     if ($build->isRestarting()) {
       $header->setStatus('fa-exclamation-triangle', 'red', pht('Restarting'));
     } else if ($build->isStopping()) {
       $header->setStatus('fa-exclamation-triangle', 'red', pht('Pausing'));
     } else if ($build->isResuming()) {
       $header->setStatus('fa-exclamation-triangle', 'red', pht('Resuming'));
     }
 
     $box = id(new PHUIObjectBoxView())
       ->setHeader($header);
 
     $actions = $this->buildActionList($build);
     $this->buildPropertyLists($box, $build, $actions);
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(
       $build->getBuildable()->getMonogram(),
       '/'.$build->getBuildable()->getMonogram());
     $crumbs->addTextCrumb($title);
 
     if ($generation === null || $generation > $build->getBuildGeneration() ||
       $generation < 0) {
       $generation = $build->getBuildGeneration();
     }
 
     $build_targets = id(new HarbormasterBuildTargetQuery())
       ->setViewer($viewer)
       ->needBuildSteps(true)
       ->withBuildPHIDs(array($build->getPHID()))
       ->withBuildGenerations(array($generation))
       ->execute();
 
     if ($build_targets) {
       $messages = id(new HarbormasterBuildMessageQuery())
         ->setViewer($viewer)
         ->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))
         ->execute();
       $messages = mgroup($messages, 'getBuildTargetPHID');
     } else {
       $messages = array();
     }
 
     $targets = array();
     foreach ($build_targets as $build_target) {
       $header = id(new PHUIHeaderView())
         ->setHeader($build_target->getName())
         ->setUser($viewer);
 
       $target_box = id(new PHUIObjectBoxView())
         ->setHeader($header);
 
       $properties = new PHUIPropertyListView();
       $status_view = new PHUIStatusListView();
 
       $item = new PHUIStatusItemView();
 
       $status = $build_target->getTargetStatus();
       $status_name =
         HarbormasterBuildTarget::getBuildTargetStatusName($status);
       $icon = HarbormasterBuildTarget::getBuildTargetStatusIcon($status);
       $color = HarbormasterBuildTarget::getBuildTargetStatusColor($status);
 
       $item->setTarget($status_name);
       $item->setIcon($icon, $color);
       $status_view->addItem($item);
 
       $properties->addProperty(pht('Name'), $build_target->getName());
 
       if ($build_target->getDateStarted() !== null) {
         $properties->addProperty(
           pht('Started'),
           phabricator_datetime($build_target->getDateStarted(), $viewer));
         if ($build_target->isComplete()) {
           $properties->addProperty(
             pht('Completed'),
             phabricator_datetime($build_target->getDateCompleted(), $viewer));
           $properties->addProperty(
             pht('Duration'),
             phutil_format_relative_time_detailed(
               $build_target->getDateCompleted() -
               $build_target->getDateStarted()));
         } else {
           $properties->addProperty(
             pht('Elapsed'),
             phutil_format_relative_time_detailed(
               time() - $build_target->getDateStarted()));
         }
       }
 
       $properties->addProperty(pht('Status'), $status_view);
 
       $target_box->addPropertyList($properties, pht('Overview'));
 
       $step = $build_target->getBuildStep();
 
       if ($step) {
         $description = $step->getDescription();
         if ($description) {
           $rendered = PhabricatorMarkupEngine::renderOneObject(
             id(new PhabricatorMarkupOneOff())
               ->setContent($description)
               ->setPreserveLinebreaks(true),
             'default',
             $viewer);
 
           $properties->addSectionHeader(pht('Description'));
           $properties->addTextContent($rendered);
         }
       } else {
         $target_box->setFormErrors(
           array(
             pht(
               'This build step has since been deleted on the build plan.  '.
               'Some information may be omitted.'),
           ));
       }
 
       $details = $build_target->getDetails();
       if ($details) {
         $properties = new PHUIPropertyListView();
         foreach ($details as $key => $value) {
           $properties->addProperty($key, $value);
         }
         $target_box->addPropertyList($properties, pht('Configuration'));
       }
 
       $variables = $build_target->getVariables();
       if ($variables) {
         $properties = new PHUIPropertyListView();
         foreach ($variables as $key => $value) {
           $properties->addProperty($key, $value);
         }
         $target_box->addPropertyList($properties, pht('Variables'));
       }
 
       $artifacts = $this->buildArtifacts($build_target);
       if ($artifacts) {
         $properties = new PHUIPropertyListView();
         $properties->addRawContent($artifacts);
         $target_box->addPropertyList($properties, pht('Artifacts'));
       }
 
       $build_messages = idx($messages, $build_target->getPHID(), array());
       if ($build_messages) {
         $properties = new PHUIPropertyListView();
         $properties->addRawContent($this->buildMessages($build_messages));
         $target_box->addPropertyList($properties, pht('Messages'));
       }
 
       $properties = new PHUIPropertyListView();
       $properties->addProperty('Build Target ID', $build_target->getID());
       $target_box->addPropertyList($properties, pht('Metadata'));
 
       $targets[] = $target_box;
 
       $targets[] = $this->buildLog($build, $build_target);
     }
 
-    $xactions = id(new HarbormasterBuildTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($build->getPHID()))
-      ->execute();
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($build->getPHID())
-      ->setTransactions($xactions);
+    $timeline = $this->buildTransactionTimeline(
+      $build,
+      new HarbormasterBuildTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $box,
         $targets,
         $timeline,
       ),
       array(
         'title' => $title,
       ));
   }
 
   private function buildArtifacts(
     HarbormasterBuildTarget $build_target) {
 
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $artifacts = id(new HarbormasterBuildArtifactQuery())
       ->setViewer($viewer)
       ->withBuildTargetPHIDs(array($build_target->getPHID()))
       ->execute();
 
     if (count($artifacts) === 0) {
       return null;
     }
 
     $list = id(new PHUIObjectItemListView())
       ->setFlush(true);
 
     foreach ($artifacts as $artifact) {
       $item = $artifact->getObjectItemView($viewer);
       if ($item !== null) {
         $list->addItem($item);
       }
     }
 
     return $list;
   }
 
   private function buildLog(
     HarbormasterBuild $build,
     HarbormasterBuildTarget $build_target) {
 
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $limit = $request->getInt('l', 25);
 
     $logs = id(new HarbormasterBuildLogQuery())
       ->setViewer($viewer)
       ->withBuildTargetPHIDs(array($build_target->getPHID()))
       ->execute();
 
     $empty_logs = array();
 
     $log_boxes = array();
     foreach ($logs as $log) {
       $start = 1;
       $lines = preg_split("/\r\n|\r|\n/", $log->getLogText());
       if ($limit !== 0) {
         $start = count($lines) - $limit;
         if ($start >= 1) {
           $lines = array_slice($lines, -$limit, $limit);
         } else {
           $start = 1;
         }
       }
 
       $id = null;
       $is_empty = false;
       if (count($lines) === 1 && trim($lines[0]) === '') {
         // Prevent Harbormaster from showing empty build logs.
         $id = celerity_generate_unique_node_id();
         $empty_logs[] = $id;
         $is_empty = true;
       }
 
       $log_view = new ShellLogView();
       $log_view->setLines($lines);
       $log_view->setStart($start);
 
       $header = id(new PHUIHeaderView())
         ->setHeader(pht(
           'Build Log %d (%s - %s)',
           $log->getID(),
           $log->getLogSource(),
           $log->getLogType()))
         ->setSubheader($this->createLogHeader($build, $log))
         ->setUser($viewer);
 
       $log_box = id(new PHUIObjectBoxView())
         ->setHeader($header)
         ->setForm($log_view);
 
       if ($is_empty) {
         $log_box = phutil_tag(
           'div',
           array(
             'style' => 'display: none',
             'id' => $id,
           ),
           $log_box);
       }
 
       $log_boxes[] = $log_box;
     }
 
     if ($empty_logs) {
       $hide_id = celerity_generate_unique_node_id();
 
       Javelin::initBehavior('phabricator-reveal-content');
 
       $expand = phutil_tag(
         'div',
         array(
           'id' => $hide_id,
           'class' => 'harbormaster-empty-logs-are-hidden mlr mlt mll',
         ),
         array(
           pht(
             '%s empty logs are hidden.',
             new PhutilNumber(count($empty_logs))),
           ' ',
           javelin_tag(
             'a',
             array(
               'href' => '#',
               'sigil' => 'reveal-content',
               'meta' => array(
                 'showIDs' => $empty_logs,
                 'hideIDs' => array($hide_id),
               ),
             ),
             pht('Show all logs.')),
         ));
 
       array_unshift($log_boxes, $expand);
     }
 
     return $log_boxes;
   }
 
   private function createLogHeader($build, $log) {
     $request = $this->getRequest();
     $limit = $request->getInt('l', 25);
 
     $lines_25 = $this->getApplicationURI('/build/'.$build->getID().'/?l=25');
     $lines_50 = $this->getApplicationURI('/build/'.$build->getID().'/?l=50');
     $lines_100 =
       $this->getApplicationURI('/build/'.$build->getID().'/?l=100');
     $lines_0 = $this->getApplicationURI('/build/'.$build->getID().'/?l=0');
 
     $link_25 = phutil_tag('a', array('href' => $lines_25), pht('25'));
     $link_50 = phutil_tag('a', array('href' => $lines_50), pht('50'));
     $link_100 = phutil_tag('a', array('href' => $lines_100), pht('100'));
     $link_0 = phutil_tag('a', array('href' => $lines_0), pht('Unlimited'));
 
     if ($limit === 25) {
       $link_25 = phutil_tag('strong', array(), $link_25);
     } else if ($limit === 50) {
       $link_50 = phutil_tag('strong', array(), $link_50);
     } else if ($limit === 100) {
       $link_100 = phutil_tag('strong', array(), $link_100);
     } else if ($limit === 0) {
       $link_0 = phutil_tag('strong', array(), $link_0);
     }
 
     return phutil_tag(
       'span',
       array(),
       array(
         $link_25,
         ' - ',
         $link_50,
         ' - ',
         $link_100,
         ' - ',
         $link_0,
         ' Lines',
       ));
   }
 
   private function buildActionList(HarbormasterBuild $build) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $id = $build->getID();
 
     $list = id(new PhabricatorActionListView())
       ->setUser($viewer)
       ->setObject($build)
       ->setObjectURI("/build/{$id}");
 
     $can_restart = $build->canRestartBuild();
     $can_stop = $build->canStopBuild();
     $can_resume = $build->canResumeBuild();
 
     $list->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Restart Build'))
         ->setIcon('fa-repeat')
         ->setHref($this->getApplicationURI('/build/restart/'.$id.'/'))
         ->setDisabled(!$can_restart)
         ->setWorkflow(true));
 
     if ($build->canResumeBuild()) {
       $list->addAction(
         id(new PhabricatorActionView())
           ->setName(pht('Resume Build'))
           ->setIcon('fa-play')
           ->setHref($this->getApplicationURI('/build/resume/'.$id.'/'))
           ->setDisabled(!$can_resume)
           ->setWorkflow(true));
     } else {
       $list->addAction(
         id(new PhabricatorActionView())
           ->setName(pht('Pause Build'))
           ->setIcon('fa-pause')
           ->setHref($this->getApplicationURI('/build/stop/'.$id.'/'))
           ->setDisabled(!$can_stop)
           ->setWorkflow(true));
     }
 
     return $list;
   }
 
   private function buildPropertyLists(
     PHUIObjectBoxView $box,
     HarbormasterBuild $build,
     PhabricatorActionListView $actions) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $properties = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($build)
       ->setActionList($actions);
     $box->addPropertyList($properties);
 
     $handles = id(new PhabricatorHandleQuery())
       ->setViewer($viewer)
       ->withPHIDs(array(
         $build->getBuildablePHID(),
         $build->getBuildPlanPHID(),
       ))
       ->execute();
 
     $properties->addProperty(
       pht('Buildable'),
       $handles[$build->getBuildablePHID()]->renderLink());
 
     $properties->addProperty(
       pht('Build Plan'),
       $handles[$build->getBuildPlanPHID()]->renderLink());
 
     $properties->addProperty(
       pht('Restarts'),
       $build->getBuildGeneration());
 
     $properties->addProperty(
       pht('Status'),
       $this->getStatus($build));
   }
 
   private function getStatus(HarbormasterBuild $build) {
     $status_view = new PHUIStatusListView();
 
     $item = new PHUIStatusItemView();
 
     if ($build->isStopping()) {
       $status_name = pht('Pausing');
       $icon = PHUIStatusItemView::ICON_RIGHT;
       $color = 'dark';
     } else {
       $status = $build->getBuildStatus();
       $status_name =
         HarbormasterBuild::getBuildStatusName($status);
       $icon = HarbormasterBuild::getBuildStatusIcon($status);
       $color = HarbormasterBuild::getBuildStatusColor($status);
     }
 
     $item->setTarget($status_name);
     $item->setIcon($icon, $color);
     $status_view->addItem($item);
 
     return $status_view;
   }
 
   private function buildMessages(array $messages) {
     $viewer = $this->getRequest()->getUser();
 
     if ($messages) {
       $handles = id(new PhabricatorHandleQuery())
         ->setViewer($viewer)
         ->withPHIDs(mpull($messages, 'getAuthorPHID'))
         ->execute();
     } else {
       $handles = array();
     }
 
     $rows = array();
     foreach ($messages as $message) {
       $rows[] = array(
         $message->getID(),
         $handles[$message->getAuthorPHID()]->renderLink(),
         $message->getType(),
         $message->getIsConsumed() ? pht('Consumed') : null,
         phabricator_datetime($message->getDateCreated(), $viewer),
       );
     }
 
     $table = new AphrontTableView($rows);
     $table->setNoDataString(pht('No messages for this build target.'));
     $table->setHeaders(
       array(
         pht('ID'),
         pht('From'),
         pht('Type'),
         pht('Consumed'),
         pht('Received'),
       ));
     $table->setColumnClasses(
       array(
         '',
         '',
         'wide',
         '',
         'date',
       ));
 
     return $table;
   }
 
 
 
 }
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
index e75022914b..ecb7605657 100644
--- a/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildableViewController.php
@@ -1,258 +1,254 @@
 <?php
 
 final class HarbormasterBuildableViewController
   extends HarbormasterController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $id = $this->id;
 
     $buildable = id(new HarbormasterBuildableQuery())
       ->setViewer($viewer)
       ->withIDs(array($id))
       ->needBuildableHandles(true)
       ->needContainerHandles(true)
       ->executeOne();
     if (!$buildable) {
       return new Aphront404Response();
     }
 
     // Pull builds and build targets.
     $builds = id(new HarbormasterBuildQuery())
       ->setViewer($viewer)
       ->withBuildablePHIDs(array($buildable->getPHID()))
       ->needBuildTargets(true)
       ->execute();
 
     $buildable->attachBuilds($builds);
 
     $build_list = $this->buildBuildList($buildable);
 
     $title = pht('Buildable %d', $id);
 
     $header = id(new PHUIHeaderView())
       ->setHeader($title)
       ->setUser($viewer)
       ->setPolicyObject($buildable);
 
     $box = id(new PHUIObjectBoxView())
       ->setHeader($header);
 
-    $xactions = id(new HarbormasterBuildableTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($buildable->getPHID()))
-      ->execute();
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($buildable->getPHID())
-      ->setTransactions($xactions);
+    $timeline = $this->buildTransactionTimeline(
+      $buildable,
+      new HarbormasterBuildableTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     $actions = $this->buildActionList($buildable);
     $this->buildPropertyLists($box, $buildable, $actions);
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb("B{$id}");
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $box,
         $build_list,
         $timeline,
       ),
       array(
         'title' => $title,
       ));
   }
 
   private function buildActionList(HarbormasterBuildable $buildable) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $id = $buildable->getID();
 
     $list = id(new PhabricatorActionListView())
       ->setUser($viewer)
       ->setObject($buildable)
       ->setObjectURI($buildable->getMonogram());
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $buildable,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $can_restart = false;
     $can_resume = false;
     $can_stop = false;
 
     foreach ($buildable->getBuilds() as $build) {
       if ($build->canRestartBuild()) {
         $can_restart = true;
       }
       if ($build->canResumeBuild()) {
         $can_resume = true;
       }
       if ($build->canStopBuild()) {
         $can_stop = true;
       }
     }
 
     $restart_uri = "buildable/{$id}/restart/";
     $stop_uri = "buildable/{$id}/stop/";
     $resume_uri = "buildable/{$id}/resume/";
 
     $list->addAction(
       id(new PhabricatorActionView())
         ->setIcon('fa-repeat')
         ->setName(pht('Restart All Builds'))
         ->setHref($this->getApplicationURI($restart_uri))
         ->setWorkflow(true)
         ->setDisabled(!$can_restart || !$can_edit));
 
     $list->addAction(
       id(new PhabricatorActionView())
         ->setIcon('fa-pause')
         ->setName(pht('Pause All Builds'))
         ->setHref($this->getApplicationURI($stop_uri))
         ->setWorkflow(true)
         ->setDisabled(!$can_stop || !$can_edit));
 
     $list->addAction(
       id(new PhabricatorActionView())
         ->setIcon('fa-play')
         ->setName(pht('Resume All Builds'))
         ->setHref($this->getApplicationURI($resume_uri))
         ->setWorkflow(true)
         ->setDisabled(!$can_resume || !$can_edit));
 
     return $list;
   }
 
   private function buildPropertyLists(
     PHUIObjectBoxView $box,
     HarbormasterBuildable $buildable,
     PhabricatorActionListView $actions) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $properties = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($buildable)
       ->setActionList($actions);
     $box->addPropertyList($properties);
 
     $properties->addProperty(
       pht('Buildable'),
       $buildable->getBuildableHandle()->renderLink());
 
     if ($buildable->getContainerHandle() !== null) {
       $properties->addProperty(
         pht('Container'),
         $buildable->getContainerHandle()->renderLink());
     }
 
     $properties->addProperty(
       pht('Origin'),
       $buildable->getIsManualBuildable()
         ? pht('Manual Buildable')
         : pht('Automatic Buildable'));
 
   }
 
   private function buildBuildList(HarbormasterBuildable $buildable) {
     $viewer = $this->getRequest()->getUser();
 
     $build_list = id(new PHUIObjectItemListView())
       ->setUser($viewer);
     foreach ($buildable->getBuilds() as $build) {
       $view_uri = $this->getApplicationURI('/build/'.$build->getID().'/');
       $item = id(new PHUIObjectItemView())
         ->setObjectName(pht('Build %d', $build->getID()))
         ->setHeader($build->getName())
         ->setHref($view_uri);
 
       $status = $build->getBuildStatus();
       $item->setBarColor(HarbormasterBuild::getBuildStatusColor($status));
 
       $item->addAttribute(HarbormasterBuild::getBuildStatusName($status));
 
       if ($build->isRestarting()) {
         $item->addIcon('fa-repeat', pht('Restarting'));
       } else if ($build->isStopping()) {
         $item->addIcon('fa-pause', pht('Pausing'));
       } else if ($build->isResuming()) {
         $item->addIcon('fa-play', pht('Resuming'));
       }
 
       $build_id = $build->getID();
 
       $restart_uri = "build/restart/{$build_id}/buildable/";
       $resume_uri = "build/resume/{$build_id}/buildable/";
       $stop_uri = "build/stop/{$build_id}/buildable/";
 
       $item->addAction(
         id(new PHUIListItemView())
           ->setIcon('fa-repeat')
           ->setName(pht('Restart'))
           ->setHref($this->getApplicationURI($restart_uri))
           ->setWorkflow(true)
           ->setDisabled(!$build->canRestartBuild()));
 
       if ($build->canResumeBuild()) {
         $item->addAction(
           id(new PHUIListItemView())
             ->setIcon('fa-play')
             ->setName(pht('Resume'))
             ->setHref($this->getApplicationURI($resume_uri))
             ->setWorkflow(true));
       } else {
         $item->addAction(
           id(new PHUIListItemView())
             ->setIcon('fa-pause')
             ->setName(pht('Pause'))
             ->setHref($this->getApplicationURI($stop_uri))
             ->setWorkflow(true)
             ->setDisabled(!$build->canStopBuild()));
       }
 
       $targets = $build->getBuildTargets();
 
       if ($targets) {
         $target_list = id(new PHUIStatusListView());
         foreach ($targets as $target) {
           $status = $target->getTargetStatus();
           $icon = HarbormasterBuildTarget::getBuildTargetStatusIcon($status);
           $color = HarbormasterBuildTarget::getBuildTargetStatusColor($status);
           $status_name =
             HarbormasterBuildTarget::getBuildTargetStatusName($status);
 
           $name = $target->getName();
 
           $target_list->addItem(
             id(new PHUIStatusItemView())
               ->setIcon($icon, $color, $status_name)
               ->setTarget(pht('Target %d', $target->getID()))
               ->setNote($name));
         }
 
         $target_box = id(new PHUIBoxView())
           ->addPadding(PHUI::PADDING_SMALL)
           ->appendChild($target_list);
 
         $item->appendChild($target_box);
       }
 
       $build_list->addItem($item);
     }
 
     return $build_list;
   }
 
 }
diff --git a/src/applications/harbormaster/controller/HarbormasterPlanViewController.php b/src/applications/harbormaster/controller/HarbormasterPlanViewController.php
index 9f52e93a09..c6fd4a1155 100644
--- a/src/applications/harbormaster/controller/HarbormasterPlanViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterPlanViewController.php
@@ -1,481 +1,475 @@
 <?php
 
 final class HarbormasterPlanViewController extends HarbormasterPlanController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $id = $this->id;
 
     $plan = id(new HarbormasterBuildPlanQuery())
       ->setViewer($viewer)
       ->withIDs(array($id))
       ->executeOne();
     if (!$plan) {
       return new Aphront404Response();
     }
 
-    $xactions = id(new HarbormasterBuildPlanTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($plan->getPHID()))
-      ->execute();
-
-    $xaction_view = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($plan->getPHID())
-      ->setTransactions($xactions)
-      ->setShouldTerminate(true);
+    $timeline = $this->buildTransactionTimeline(
+      $plan,
+      new HarbormasterBuildPlanTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     $title = pht('Plan %d', $id);
 
     $header = id(new PHUIHeaderView())
       ->setHeader($title)
       ->setUser($viewer)
       ->setPolicyObject($plan);
 
     $box = id(new PHUIObjectBoxView())
       ->setHeader($header);
 
     $actions = $this->buildActionList($plan);
     $this->buildPropertyLists($box, $plan, $actions);
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Plan %d', $id));
 
     list($step_list, $has_any_conflicts, $would_deadlock) =
       $this->buildStepList($plan);
 
     if ($would_deadlock) {
       $box->setFormErrors(
         array(
           pht(
             'This build plan will deadlock when executed, due to '.
             'circular dependencies present in the build plan. '.
             'Examine the step list and resolve the deadlock.'),
         ));
     } else if ($has_any_conflicts) {
       // A deadlocking build will also cause all the artifacts to be
       // invalid, so we just skip showing this message if that's the
       // case.
       $box->setFormErrors(
         array(
           pht(
             'This build plan has conflicts in one or more build steps. '.
             'Examine the step list and resolve the listed errors.'),
         ));
     }
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $box,
         $step_list,
-        $xaction_view,
+        $timeline,
       ),
       array(
         'title' => $title,
       ));
   }
 
   private function buildStepList(HarbormasterBuildPlan $plan) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $run_order =
       HarbormasterBuildGraph::determineDependencyExecution($plan);
 
     $steps = id(new HarbormasterBuildStepQuery())
       ->setViewer($viewer)
       ->withBuildPlanPHIDs(array($plan->getPHID()))
       ->execute();
     $steps = mpull($steps, null, 'getPHID');
 
     $can_edit = $this->hasApplicationCapability(
       HarbormasterManagePlansCapability::CAPABILITY);
 
     $step_list = id(new PHUIObjectItemListView())
       ->setUser($viewer)
       ->setNoDataString(
         pht('This build plan does not have any build steps yet.'));
 
     $i = 1;
     $last_depth = 0;
     $has_any_conflicts = false;
     $is_deadlocking = false;
     foreach ($run_order as $run_ref) {
       $step = $steps[$run_ref['node']->getPHID()];
       $depth = $run_ref['depth'] + 1;
       if ($last_depth !== $depth) {
         $last_depth = $depth;
         $i = 1;
       } else {
         $i++;
       }
 
       $implementation = null;
       try {
         $implementation = $step->getStepImplementation();
       } catch (Exception $ex) {
         // We can't initialize the implementation. This might be because
         // it's been renamed or no longer exists.
         $item = id(new PHUIObjectItemView())
           ->setObjectName(pht('Step %d.%d', $depth, $i))
           ->setHeader(pht('Unknown Implementation'))
           ->setBarColor('red')
           ->addAttribute(pht(
             'This step has an invalid implementation (%s).',
             $step->getClassName()))
           ->addAction(
             id(new PHUIListItemView())
               ->setIcon('fa-times')
               ->addSigil('harbormaster-build-step-delete')
               ->setWorkflow(true)
               ->setRenderNameAsTooltip(true)
               ->setName(pht('Delete'))
               ->setHref(
                 $this->getApplicationURI('step/delete/'.$step->getID().'/')));
         $step_list->addItem($item);
         continue;
       }
       $item = id(new PHUIObjectItemView())
         ->setObjectName(pht('Step %d.%d', $depth, $i))
         ->setHeader($step->getName());
 
       $item->addAttribute($implementation->getDescription());
 
       $step_id = $step->getID();
       $edit_uri = $this->getApplicationURI("step/edit/{$step_id}/");
       $delete_uri = $this->getApplicationURI("step/delete/{$step_id}/");
 
       if ($can_edit) {
         $item->setHref($edit_uri);
       }
 
       $item
         ->setHref($edit_uri)
         ->addAction(
           id(new PHUIListItemView())
             ->setIcon('fa-times')
             ->addSigil('harbormaster-build-step-delete')
             ->setWorkflow(true)
             ->setDisabled(!$can_edit)
             ->setHref(
               $this->getApplicationURI('step/delete/'.$step->getID().'/')));
 
       $depends = $step->getStepImplementation()->getDependencies($step);
       $inputs = $step->getStepImplementation()->getArtifactInputs();
       $outputs = $step->getStepImplementation()->getArtifactOutputs();
 
       $has_conflicts = false;
       if ($depends || $inputs || $outputs) {
         $available_artifacts =
           HarbormasterBuildStepImplementation::getAvailableArtifacts(
             $plan,
             $step,
             null);
         $available_artifacts = ipull($available_artifacts, 'type');
 
         list($depends_ui, $has_conflicts) = $this->buildDependsOnList(
             $depends,
             pht('Depends On'),
             $steps);
 
         list($inputs_ui, $has_conflicts) = $this->buildArtifactList(
             $inputs,
             'in',
             pht('Input Artifacts'),
             $available_artifacts);
 
         list($outputs_ui) = $this->buildArtifactList(
             $outputs,
             'out',
             pht('Output Artifacts'),
             array());
 
         $item->appendChild(
           phutil_tag(
             'div',
             array(
               'class' => 'harbormaster-artifact-io',
             ),
             array(
               $depends_ui,
               $inputs_ui,
               $outputs_ui,
             )));
       }
 
       if ($has_conflicts) {
         $has_any_conflicts = true;
         $item->setBarColor('red');
       }
 
       if ($run_ref['cycle']) {
         $is_deadlocking = true;
       }
 
       if ($is_deadlocking) {
         $item->setBarColor('red');
       }
 
       $step_list->addItem($item);
     }
 
     return array($step_list, $has_any_conflicts, $is_deadlocking);
   }
 
   private function buildActionList(HarbormasterBuildPlan $plan) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $id = $plan->getID();
 
     $list = id(new PhabricatorActionListView())
       ->setUser($viewer)
       ->setObject($plan)
       ->setObjectURI($this->getApplicationURI("plan/{$id}/"));
 
     $can_edit = $this->hasApplicationCapability(
       HarbormasterManagePlansCapability::CAPABILITY);
 
     $list->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Edit Plan'))
         ->setHref($this->getApplicationURI("plan/edit/{$id}/"))
         ->setWorkflow(!$can_edit)
         ->setDisabled(!$can_edit)
         ->setIcon('fa-pencil'));
 
     if ($plan->isDisabled()) {
       $list->addAction(
         id(new PhabricatorActionView())
           ->setName(pht('Enable Plan'))
           ->setHref($this->getApplicationURI("plan/disable/{$id}/"))
           ->setWorkflow(true)
           ->setDisabled(!$can_edit)
           ->setIcon('fa-check'));
     } else {
       $list->addAction(
         id(new PhabricatorActionView())
           ->setName(pht('Disable Plan'))
           ->setHref($this->getApplicationURI("plan/disable/{$id}/"))
           ->setWorkflow(true)
           ->setDisabled(!$can_edit)
           ->setIcon('fa-ban'));
     }
 
     $list->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Add Build Step'))
         ->setHref($this->getApplicationURI("step/add/{$id}/"))
         ->setWorkflow(true)
         ->setDisabled(!$can_edit)
         ->setIcon('fa-plus'));
 
     $list->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Run Plan Manually'))
         ->setHref($this->getApplicationURI("plan/run/{$id}/"))
         ->setWorkflow(true)
         ->setDisabled(!$can_edit)
         ->setIcon('fa-play-circle'));
 
     return $list;
   }
 
   private function buildPropertyLists(
     PHUIObjectBoxView $box,
     HarbormasterBuildPlan $plan,
     PhabricatorActionListView $actions) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $properties = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($plan)
       ->setActionList($actions);
     $box->addPropertyList($properties);
 
     $properties->addProperty(
       pht('Created'),
       phabricator_datetime($plan->getDateCreated(), $viewer));
 
   }
 
   private function buildArtifactList(
     array $artifacts,
     $kind,
     $name,
     array $available_artifacts) {
     $has_conflicts = false;
 
     if (!$artifacts) {
       return array(null, $has_conflicts);
     }
 
     $this->requireResource('harbormaster-css');
 
     $header = phutil_tag(
       'div',
       array(
         'class' => 'harbormaster-artifact-summary-header',
       ),
       $name);
 
     $is_input = ($kind == 'in');
 
     $list = new PHUIStatusListView();
     foreach ($artifacts as $artifact) {
       $error = null;
 
       $key = idx($artifact, 'key');
       if (!strlen($key)) {
         $bound = phutil_tag('em', array(), pht('(null)'));
         if ($is_input) {
           // This is an unbound input. For now, all inputs are always required.
           $icon = PHUIStatusItemView::ICON_WARNING;
           $color = 'red';
           $icon_label = pht('Required Input');
           $has_conflicts = true;
           $error = pht('This input is required, but not configured.');
         } else {
           // This is an unnamed output. Outputs do not necessarily need to be
           // named.
           $icon = PHUIStatusItemView::ICON_OPEN;
           $color = 'bluegrey';
           $icon_label = pht('Unused Output');
         }
       } else {
         $bound = phutil_tag('strong', array(), $key);
         if ($is_input) {
           if (isset($available_artifacts[$key])) {
             if ($available_artifacts[$key] == idx($artifact, 'type')) {
               $icon = PHUIStatusItemView::ICON_ACCEPT;
               $color = 'green';
               $icon_label = pht('Valid Input');
             } else {
               $icon = PHUIStatusItemView::ICON_WARNING;
               $color = 'red';
               $icon_label = pht('Bad Input Type');
               $has_conflicts = true;
               $error = pht(
                 'This input is bound to the wrong artifact type. It is bound '.
                 'to a "%s" artifact, but should be bound to a "%s" artifact.',
                 $available_artifacts[$key],
                 idx($artifact, 'type'));
             }
           } else {
             $icon = PHUIStatusItemView::ICON_QUESTION;
             $color = 'red';
             $icon_label = pht('Unknown Input');
             $has_conflicts = true;
             $error = pht(
               'This input is bound to an artifact ("%s") which does not exist '.
               'at this stage in the build process.',
               $key);
           }
         } else {
           $icon = PHUIStatusItemView::ICON_DOWN;
           $color = 'green';
           $icon_label = pht('Valid Output');
         }
       }
 
       if ($error) {
         $note = array(
           phutil_tag('strong', array(), pht('ERROR:')),
           ' ',
           $error,
         );
       } else {
         $note = $bound;
       }
 
       $list->addItem(
         id(new PHUIStatusItemView())
           ->setIcon($icon, $color, $icon_label)
           ->setTarget($artifact['name'])
           ->setNote($note));
     }
 
     $ui = array(
       $header,
       $list,
     );
 
     return array($ui, $has_conflicts);
   }
 
   private function buildDependsOnList(
     array $step_phids,
     $name,
     array $steps) {
     $has_conflicts = false;
 
     if (count($step_phids) === 0) {
       return null;
     }
 
     $this->requireResource('harbormaster-css');
 
     $steps = mpull($steps, null, 'getPHID');
 
     $header = phutil_tag(
       'div',
       array(
         'class' => 'harbormaster-artifact-summary-header',
       ),
       $name);
 
     $list = new PHUIStatusListView();
     foreach ($step_phids as $step_phid) {
       $error = null;
 
       if (idx($steps, $step_phid) === null) {
         $icon = PHUIStatusItemView::ICON_WARNING;
         $color = 'red';
         $icon_label = pht('Missing Dependency');
         $has_conflicts = true;
         $error = pht(
           'This dependency specifies a build step which doesn\'t exist.');
       } else {
         $bound = phutil_tag(
           'strong',
           array(),
           idx($steps, $step_phid)->getName());
         $icon = PHUIStatusItemView::ICON_ACCEPT;
         $color = 'green';
         $icon_label = pht('Valid Input');
       }
 
       if ($error) {
         $note = array(
           phutil_tag('strong', array(), pht('ERROR:')),
           ' ',
           $error,
         );
       } else {
         $note = $bound;
       }
 
       $list->addItem(
         id(new PHUIStatusItemView())
           ->setIcon($icon, $color, $icon_label)
           ->setTarget(pht('Build Step'))
           ->setNote($note));
     }
 
     $ui = array(
       $header,
       $list,
     );
 
     return array($ui, $has_conflicts);
   }
 }
diff --git a/src/applications/harbormaster/controller/HarbormasterStepEditController.php b/src/applications/harbormaster/controller/HarbormasterStepEditController.php
index 12631db71a..403dfa8cce 100644
--- a/src/applications/harbormaster/controller/HarbormasterStepEditController.php
+++ b/src/applications/harbormaster/controller/HarbormasterStepEditController.php
@@ -1,244 +1,238 @@
 <?php
 
 final class HarbormasterStepEditController extends HarbormasterController {
 
   private $id;
   private $planID;
   private $className;
 
   public function willProcessRequest(array $data) {
     $this->id = idx($data, 'id');
     $this->planID = idx($data, 'plan');
     $this->className = idx($data, 'class');
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $this->requireApplicationCapability(
       HarbormasterManagePlansCapability::CAPABILITY);
 
     if ($this->id) {
       $step = id(new HarbormasterBuildStepQuery())
         ->setViewer($viewer)
         ->withIDs(array($this->id))
         ->executeOne();
       if (!$step) {
         return new Aphront404Response();
       }
       $plan = $step->getBuildPlan();
 
       $is_new = false;
     } else {
       $plan = id(new HarbormasterBuildPlanQuery())
           ->setViewer($viewer)
           ->withIDs(array($this->planID))
           ->executeOne();
       if (!$plan) {
         return new Aphront404Response();
       }
 
       $impl = HarbormasterBuildStepImplementation::getImplementation(
         $this->className);
       if (!$impl) {
         return new Aphront404Response();
       }
 
       $step = HarbormasterBuildStep::initializeNewStep($viewer)
         ->setBuildPlanPHID($plan->getPHID())
         ->setClassName($this->className);
 
       $is_new = true;
     }
 
     $plan_uri = $this->getApplicationURI('plan/'.$plan->getID().'/');
 
     $implementation = $step->getStepImplementation();
 
     $field_list = PhabricatorCustomField::getObjectFields(
       $step,
       PhabricatorCustomField::ROLE_EDIT);
     $field_list
       ->setViewer($viewer)
       ->readFieldsFromStorage($step);
 
     $e_name = true;
     $v_name = $step->getName();
     $e_description = true;
     $v_description = $step->getDescription();
     $e_depends_on = true;
     $raw_depends_on = $step->getDetail('dependsOn', array());
 
     $v_depends_on = id(new PhabricatorHandleQuery())
       ->setViewer($viewer)
       ->withPHIDs($raw_depends_on)
       ->execute();
 
     $errors = array();
     $validation_exception = null;
     if ($request->isFormPost()) {
       $e_name = null;
       $v_name = $request->getStr('name');
       $e_description = null;
       $v_description = $request->getStr('description');
       $e_depends_on = null;
       $v_depends_on = $request->getArr('dependsOn');
 
       $xactions = $field_list->buildFieldTransactionsFromRequest(
         new HarbormasterBuildStepTransaction(),
         $request);
 
       $editor = id(new HarbormasterBuildStepEditor())
         ->setActor($viewer)
         ->setContinueOnNoEffect(true)
         ->setContentSourceFromRequest($request);
 
       $name_xaction = id(new HarbormasterBuildStepTransaction())
         ->setTransactionType(HarbormasterBuildStepTransaction::TYPE_NAME)
         ->setNewValue($v_name);
       array_unshift($xactions, $name_xaction);
 
       $depends_on_xaction = id(new HarbormasterBuildStepTransaction())
         ->setTransactionType(
           HarbormasterBuildStepTransaction::TYPE_DEPENDS_ON)
         ->setNewValue($v_depends_on);
       array_unshift($xactions, $depends_on_xaction);
 
       $description_xaction = id(new HarbormasterBuildStepTransaction())
         ->setTransactionType(
           HarbormasterBuildStepTransaction::TYPE_DESCRIPTION)
         ->setNewValue($v_description);
       array_unshift($xactions, $description_xaction);
 
       if ($is_new) {
         // When creating a new step, make sure we have a create transaction
         // so we'll apply the transactions even if the step has no
         // configurable options.
         $create_xaction = id(new HarbormasterBuildStepTransaction())
           ->setTransactionType(HarbormasterBuildStepTransaction::TYPE_CREATE);
         array_unshift($xactions, $create_xaction);
       }
 
       try {
         $editor->applyTransactions($step, $xactions);
         return id(new AphrontRedirectResponse())->setURI($plan_uri);
       } catch (PhabricatorApplicationTransactionValidationException $ex) {
         $validation_exception = $ex;
       }
     }
 
     $form = id(new AphrontFormView())
       ->setUser($viewer)
       ->appendChild(
         id(new AphrontFormTextControl())
           ->setName('name')
           ->setLabel(pht('Name'))
           ->setError($e_name)
           ->setValue($v_name));
 
     $form
       ->appendChild(
         id(new AphrontFormTokenizerControl())
           ->setDatasource(id(new HarbormasterBuildDependencyDatasource())
             ->setParameters(array(
               'planPHID' => $plan->getPHID(),
               'stepPHID' => $is_new ? null : $step->getPHID(),
             )))
           ->setName('dependsOn')
           ->setLabel(pht('Depends On'))
           ->setError($e_depends_on)
           ->setValue($v_depends_on));
 
     $field_list->appendFieldsToForm($form);
 
     $form
       ->appendChild(
         id(new PhabricatorRemarkupControl())
           ->setUser($viewer)
           ->setName('description')
           ->setLabel(pht('Description'))
           ->setError($e_description)
           ->setValue($v_description));
 
     if ($is_new) {
       $submit = pht('Create Build Step');
       $header = pht('New Step: %s', $implementation->getName());
       $crumb = pht('Add Step');
     } else {
       $submit = pht('Save Build Step');
       $header = pht('Edit Step: %s', $implementation->getName());
       $crumb = pht('Edit Step');
     }
 
     $form->appendChild(
       id(new AphrontFormSubmitControl())
         ->setValue($submit)
         ->addCancelButton($plan_uri));
 
     $box = id(new PHUIObjectBoxView())
       ->setHeaderText($header)
       ->setValidationException($validation_exception)
       ->setForm($form);
 
     $crumbs = $this->buildApplicationCrumbs();
     $id = $plan->getID();
     $crumbs->addTextCrumb(pht('Plan %d', $id), $plan_uri);
     $crumbs->addTextCrumb($crumb);
 
     $variables = $this->renderBuildVariablesTable();
 
     if ($is_new) {
       $xaction_view = null;
     } else {
-      $xactions = id(new HarbormasterBuildStepTransactionQuery())
-        ->setViewer($viewer)
-        ->withObjectPHIDs(array($step->getPHID()))
-        ->execute();
-
-      $xaction_view = id(new PhabricatorApplicationTransactionView())
-        ->setUser($viewer)
-        ->setObjectPHID($step->getPHID())
-        ->setTransactions($xactions)
-        ->setShouldTerminate(true);
+      $timeline = $this->buildTransactionTimeline(
+        $step,
+        new HarbormasterBuildStepTransactionQuery());
+      $timeline->setShouldTerminate(true);
     }
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $box,
         $variables,
-        $xaction_view,
+        $timeline,
       ),
       array(
         'title' => $implementation->getName(),
       ));
   }
 
   private function renderBuildVariablesTable() {
     $viewer = $this->getRequest()->getUser();
 
     $variables = HarbormasterBuild::getAvailableBuildVariables();
     ksort($variables);
 
     $rows = array();
     $rows[] = pht(
       'The following variables can be used in most fields. To reference '.
       'a variable, use `${name}` in a field.');
     $rows[] = pht('| Variable | Description |');
     $rows[] = '|---|---|';
     foreach ($variables as $name => $description) {
       $rows[] = '| `'.$name.'` | '.$description.' |';
     }
     $rows = implode("\n", $rows);
 
     $form = id(new AphrontFormView())
       ->setUser($viewer)
       ->appendRemarkupInstructions($rows);
 
     return id(new PHUIObjectBoxView())
       ->setHeaderText(pht('Build Variables'))
       ->appendChild($form);
   }
 
 }
diff --git a/src/applications/harbormaster/storage/HarbormasterBuildable.php b/src/applications/harbormaster/storage/HarbormasterBuildable.php
index f7e6ab51f7..17cfd8350f 100644
--- a/src/applications/harbormaster/storage/HarbormasterBuildable.php
+++ b/src/applications/harbormaster/storage/HarbormasterBuildable.php
@@ -1,278 +1,295 @@
 <?php
 
 final class HarbormasterBuildable extends HarbormasterDAO
   implements
+    PhabricatorApplicationTransactionInterface,
     PhabricatorPolicyInterface,
     HarbormasterBuildableInterface {
 
   protected $buildablePHID;
   protected $containerPHID;
   protected $buildableStatus;
   protected $isManualBuildable;
 
   private $buildableObject = self::ATTACHABLE;
   private $containerObject = self::ATTACHABLE;
   private $buildableHandle = self::ATTACHABLE;
   private $containerHandle = self::ATTACHABLE;
   private $builds = self::ATTACHABLE;
 
   const STATUS_BUILDING = 'building';
   const STATUS_PASSED = 'passed';
   const STATUS_FAILED = 'failed';
 
   public static function getBuildableStatusName($status) {
     switch ($status) {
       case self::STATUS_BUILDING:
         return pht('Building');
       case self::STATUS_PASSED:
         return pht('Passed');
       case self::STATUS_FAILED:
         return pht('Failed');
       default:
         return pht('Unknown');
     }
   }
 
   public static function getBuildableStatusIcon($status) {
     switch ($status) {
       case self::STATUS_BUILDING:
         return PHUIStatusItemView::ICON_RIGHT;
       case self::STATUS_PASSED:
         return PHUIStatusItemView::ICON_ACCEPT;
       case self::STATUS_FAILED:
         return PHUIStatusItemView::ICON_REJECT;
       default:
         return PHUIStatusItemView::ICON_QUESTION;
     }
   }
 
   public static function getBuildableStatusColor($status) {
     switch ($status) {
       case self::STATUS_BUILDING:
         return 'blue';
       case self::STATUS_PASSED:
         return 'green';
       case self::STATUS_FAILED:
         return 'red';
       default:
         return 'bluegrey';
     }
   }
 
   public static function initializeNewBuildable(PhabricatorUser $actor) {
     return id(new HarbormasterBuildable())
       ->setIsManualBuildable(0)
       ->setBuildableStatus(self::STATUS_BUILDING);
   }
 
   public function getMonogram() {
     return 'B'.$this->getID();
   }
 
   /**
    * Returns an existing buildable for the object's PHID or creates a
    * new buildable implicitly if needed.
    */
   public static function createOrLoadExisting(
     PhabricatorUser $actor,
     $buildable_object_phid,
     $container_object_phid) {
 
     $buildable = id(new HarbormasterBuildableQuery())
       ->setViewer($actor)
       ->withBuildablePHIDs(array($buildable_object_phid))
       ->withManualBuildables(false)
       ->setLimit(1)
       ->executeOne();
     if ($buildable) {
       return $buildable;
     }
     $buildable = HarbormasterBuildable::initializeNewBuildable($actor)
       ->setBuildablePHID($buildable_object_phid)
       ->setContainerPHID($container_object_phid);
     $buildable->save();
     return $buildable;
   }
 
   /**
    * Looks up the plan PHIDs and applies the plans to the specified
    * object identified by it's PHID.
    */
   public static function applyBuildPlans(
     $phid,
     $container_phid,
     array $plan_phids) {
 
     if (count($plan_phids) === 0) {
       return;
     }
 
     // Skip all of this logic if the Harbormaster application
     // isn't currently installed.
 
     $harbormaster_app = 'PhabricatorHarbormasterApplication';
     if (!PhabricatorApplication::isClassInstalled($harbormaster_app)) {
       return;
     }
 
     $buildable = HarbormasterBuildable::createOrLoadExisting(
       PhabricatorUser::getOmnipotentUser(),
       $phid,
       $container_phid);
 
     $plans = id(new HarbormasterBuildPlanQuery())
       ->setViewer(PhabricatorUser::getOmnipotentUser())
       ->withPHIDs($plan_phids)
       ->execute();
     foreach ($plans as $plan) {
       if ($plan->isDisabled()) {
         // TODO: This should be communicated more clearly -- maybe we should
         // create the build but set the status to "disabled" or "derelict".
         continue;
       }
 
       $buildable->applyPlan($plan);
     }
   }
 
   public function applyPlan(HarbormasterBuildPlan $plan) {
     $viewer = PhabricatorUser::getOmnipotentUser();
     $build = HarbormasterBuild::initializeNewBuild($viewer)
       ->setBuildablePHID($this->getPHID())
       ->setBuildPlanPHID($plan->getPHID())
       ->setBuildStatus(HarbormasterBuild::STATUS_PENDING)
       ->save();
 
     PhabricatorWorker::scheduleTask(
       'HarbormasterBuildWorker',
       array(
         'buildID' => $build->getID(),
       ));
 
     return $build;
   }
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'containerPHID' => 'phid?',
         'buildableStatus' => 'text32',
         'isManualBuildable' => 'bool',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_buildable' => array(
           'columns' => array('buildablePHID'),
         ),
         'key_container' => array(
           'columns' => array('containerPHID'),
         ),
         'key_manual' => array(
           'columns' => array('isManualBuildable'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       HarbormasterBuildablePHIDType::TYPECONST);
   }
 
   public function attachBuildableObject($buildable_object) {
     $this->buildableObject = $buildable_object;
     return $this;
   }
 
   public function getBuildableObject() {
     return $this->assertAttached($this->buildableObject);
   }
 
   public function attachContainerObject($container_object) {
     $this->containerObject = $container_object;
     return $this;
   }
 
   public function getContainerObject() {
     return $this->assertAttached($this->containerObject);
   }
 
   public function attachContainerHandle($container_handle) {
     $this->containerHandle = $container_handle;
     return $this;
   }
 
   public function getContainerHandle() {
     return $this->assertAttached($this->containerHandle);
   }
 
   public function attachBuildableHandle($buildable_handle) {
     $this->buildableHandle = $buildable_handle;
     return $this;
   }
 
   public function getBuildableHandle() {
     return $this->assertAttached($this->buildableHandle);
   }
 
   public function attachBuilds(array $builds) {
     assert_instances_of($builds, 'HarbormasterBuild');
     $this->builds = $builds;
     return $this;
   }
 
   public function getBuilds() {
     return $this->assertAttached($this->builds);
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new HarbormasterBuildableTransactionEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new HarbormasterBuildableTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     return $this->getBuildableObject()->getPolicy($capability);
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return $this->getBuildableObject()->hasAutomaticCapability(
       $capability,
       $viewer);
   }
 
   public function describeAutomaticCapability($capability) {
     return pht('A buildable inherits policies from the underlying object.');
   }
 
 
 
 /* -(  HarbormasterBuildableInterface  )------------------------------------- */
 
 
   public function getHarbormasterBuildablePHID() {
     // NOTE: This is essentially just for convenience, as it allows you create
     // a copy of a buildable by specifying `B123` without bothering to go
     // look up the underlying object.
     return $this->getBuildablePHID();
   }
 
   public function getHarbormasterContainerPHID() {
     return $this->getContainerPHID();
   }
 
   public function getBuildVariables() {
     return array();
   }
 
   public function getAvailableBuildVariables() {
     return array();
   }
 
 
 }
diff --git a/src/applications/harbormaster/storage/build/HarbormasterBuild.php b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
index 4b05a5937a..db8cbd2818 100644
--- a/src/applications/harbormaster/storage/build/HarbormasterBuild.php
+++ b/src/applications/harbormaster/storage/build/HarbormasterBuild.php
@@ -1,429 +1,447 @@
 <?php
 
 final class HarbormasterBuild extends HarbormasterDAO
-  implements PhabricatorPolicyInterface {
+  implements
+    PhabricatorApplicationTransactionInterface,
+    PhabricatorPolicyInterface {
 
   protected $buildablePHID;
   protected $buildPlanPHID;
   protected $buildStatus;
   protected $buildGeneration;
 
   private $buildable = self::ATTACHABLE;
   private $buildPlan = self::ATTACHABLE;
   private $buildTargets = self::ATTACHABLE;
   private $unprocessedCommands = self::ATTACHABLE;
 
   /**
    * Not currently being built.
    */
   const STATUS_INACTIVE = 'inactive';
 
   /**
    * Pending pick up by the Harbormaster daemon.
    */
   const STATUS_PENDING = 'pending';
 
   /**
    * Current building the buildable.
    */
   const STATUS_BUILDING = 'building';
 
   /**
    * The build has passed.
    */
   const STATUS_PASSED = 'passed';
 
   /**
    * The build has failed.
    */
   const STATUS_FAILED = 'failed';
 
   /**
    * The build encountered an unexpected error.
    */
   const STATUS_ERROR = 'error';
 
   /**
    * The build has been stopped.
    */
   const STATUS_STOPPED = 'stopped';
 
   /**
    * The build has been deadlocked.
    */
   const STATUS_DEADLOCKED = 'deadlocked';
 
 
   /**
    * Get a human readable name for a build status constant.
    *
    * @param  const  Build status constant.
    * @return string Human-readable name.
    */
   public static function getBuildStatusName($status) {
     switch ($status) {
       case self::STATUS_INACTIVE:
         return pht('Inactive');
       case self::STATUS_PENDING:
         return pht('Pending');
       case self::STATUS_BUILDING:
         return pht('Building');
       case self::STATUS_PASSED:
         return pht('Passed');
       case self::STATUS_FAILED:
         return pht('Failed');
       case self::STATUS_ERROR:
         return pht('Unexpected Error');
       case self::STATUS_STOPPED:
         return pht('Paused');
       case self::STATUS_DEADLOCKED:
         return pht('Deadlocked');
       default:
         return pht('Unknown');
     }
   }
 
   public static function getBuildStatusIcon($status) {
     switch ($status) {
       case self::STATUS_INACTIVE:
       case self::STATUS_PENDING:
         return PHUIStatusItemView::ICON_OPEN;
       case self::STATUS_BUILDING:
         return PHUIStatusItemView::ICON_RIGHT;
       case self::STATUS_PASSED:
         return PHUIStatusItemView::ICON_ACCEPT;
       case self::STATUS_FAILED:
         return PHUIStatusItemView::ICON_REJECT;
       case self::STATUS_ERROR:
         return PHUIStatusItemView::ICON_MINUS;
       case self::STATUS_STOPPED:
         return PHUIStatusItemView::ICON_MINUS;
       case self::STATUS_DEADLOCKED:
         return PHUIStatusItemView::ICON_WARNING;
       default:
         return PHUIStatusItemView::ICON_QUESTION;
     }
   }
 
   public static function getBuildStatusColor($status) {
     switch ($status) {
       case self::STATUS_INACTIVE:
         return 'dark';
       case self::STATUS_PENDING:
       case self::STATUS_BUILDING:
         return 'blue';
       case self::STATUS_PASSED:
         return 'green';
       case self::STATUS_FAILED:
       case self::STATUS_ERROR:
       case self::STATUS_DEADLOCKED:
         return 'red';
       case self::STATUS_STOPPED:
         return 'dark';
       default:
         return 'bluegrey';
     }
   }
 
   public static function initializeNewBuild(PhabricatorUser $actor) {
     return id(new HarbormasterBuild())
       ->setBuildStatus(self::STATUS_INACTIVE)
       ->setBuildGeneration(0);
   }
 
   public function delete() {
     $this->openTransaction();
       $this->deleteUnprocessedCommands();
       $result = parent::delete();
     $this->saveTransaction();
 
     return $result;
   }
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'buildStatus' => 'text32',
         'buildGeneration' => 'uint32',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_buildable' => array(
           'columns' => array('buildablePHID'),
         ),
         'key_plan' => array(
           'columns' => array('buildPlanPHID'),
         ),
         'key_status' => array(
           'columns' => array('buildStatus'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       HarbormasterBuildPHIDType::TYPECONST);
   }
 
   public function attachBuildable(HarbormasterBuildable $buildable) {
     $this->buildable = $buildable;
     return $this;
   }
 
   public function getBuildable() {
     return $this->assertAttached($this->buildable);
   }
 
   public function getName() {
     if ($this->getBuildPlan()) {
       return $this->getBuildPlan()->getName();
     }
     return pht('Build');
   }
 
   public function attachBuildPlan(
     HarbormasterBuildPlan $build_plan = null) {
     $this->buildPlan = $build_plan;
     return $this;
   }
 
   public function getBuildPlan() {
     return $this->assertAttached($this->buildPlan);
   }
 
   public function getBuildTargets() {
     return $this->assertAttached($this->buildTargets);
   }
 
   public function attachBuildTargets(array $targets) {
     $this->buildTargets = $targets;
     return $this;
   }
 
   public function isBuilding() {
     return $this->getBuildStatus() === self::STATUS_PENDING ||
       $this->getBuildStatus() === self::STATUS_BUILDING;
   }
 
   public function createLog(
     HarbormasterBuildTarget $build_target,
     $log_source,
     $log_type) {
 
     $log_source = id(new PhutilUTF8StringTruncator())
       ->setMaximumCodepoints(250)
       ->truncateString($log_source);
 
     $log = HarbormasterBuildLog::initializeNewBuildLog($build_target)
       ->setLogSource($log_source)
       ->setLogType($log_type)
       ->save();
 
     return $log;
   }
 
   public function createArtifact(
     HarbormasterBuildTarget $build_target,
     $artifact_key,
     $artifact_type) {
 
     $artifact =
       HarbormasterBuildArtifact::initializeNewBuildArtifact($build_target);
     $artifact->setArtifactKey(
       $this->getPHID(),
       $this->getBuildGeneration(),
       $artifact_key);
     $artifact->setArtifactType($artifact_type);
     $artifact->save();
     return $artifact;
   }
 
   public function loadArtifact($name) {
     $artifact = id(new HarbormasterBuildArtifactQuery())
       ->setViewer(PhabricatorUser::getOmnipotentUser())
       ->withArtifactKeys(
         $this->getPHID(),
         $this->getBuildGeneration(),
         array($name))
       ->executeOne();
     if ($artifact === null) {
       throw new Exception('Artifact not found!');
     }
     return $artifact;
   }
 
   public function retrieveVariablesFromBuild() {
     $results = array(
       'buildable.diff' => null,
       'buildable.revision' => null,
       'buildable.commit' => null,
       'repository.callsign' => null,
       'repository.vcs' => null,
       'repository.uri' => null,
       'step.timestamp' => null,
       'build.id' => null,
     );
 
     $buildable = $this->getBuildable();
     $object = $buildable->getBuildableObject();
 
     $object_variables = $object->getBuildVariables();
 
     $results = $object_variables + $results;
 
     $results['step.timestamp'] = time();
     $results['build.id'] = $this->getID();
 
     return $results;
   }
 
   public static function getAvailableBuildVariables() {
     $objects = id(new PhutilSymbolLoader())
       ->setAncestorClass('HarbormasterBuildableInterface')
       ->loadObjects();
 
     $variables = array();
     $variables[] = array(
       'step.timestamp' => pht('The current UNIX timestamp.'),
       'build.id' => pht('The ID of the current build.'),
       'target.phid' => pht('The PHID of the current build target.'),
     );
 
     foreach ($objects as $object) {
       $variables[] = $object->getAvailableBuildVariables();
     }
 
     $variables = array_mergev($variables);
     return $variables;
   }
 
   public function isComplete() {
     switch ($this->getBuildStatus()) {
       case self::STATUS_PASSED:
       case self::STATUS_FAILED:
       case self::STATUS_ERROR:
       case self::STATUS_STOPPED:
         return true;
     }
 
     return false;
   }
 
   public function isStopped() {
     return ($this->getBuildStatus() == self::STATUS_STOPPED);
   }
 
 
 /* -(  Build Commands  )----------------------------------------------------- */
 
 
   private function getUnprocessedCommands() {
     return $this->assertAttached($this->unprocessedCommands);
   }
 
   public function attachUnprocessedCommands(array $commands) {
     $this->unprocessedCommands = $commands;
     return $this;
   }
 
   public function canRestartBuild() {
     return !$this->isRestarting();
   }
 
   public function canStopBuild() {
     return !$this->isComplete() &&
            !$this->isStopped() &&
            !$this->isStopping();
   }
 
   public function canResumeBuild() {
     return $this->isStopped() &&
            !$this->isResuming();
   }
 
   public function isStopping() {
     $is_stopping = false;
     foreach ($this->getUnprocessedCommands() as $command_object) {
       $command = $command_object->getCommand();
       switch ($command) {
         case HarbormasterBuildCommand::COMMAND_STOP:
           $is_stopping = true;
           break;
         case HarbormasterBuildCommand::COMMAND_RESUME:
         case HarbormasterBuildCommand::COMMAND_RESTART:
           $is_stopping = false;
           break;
       }
     }
 
     return $is_stopping;
   }
 
   public function isResuming() {
     $is_resuming = false;
     foreach ($this->getUnprocessedCommands() as $command_object) {
       $command = $command_object->getCommand();
       switch ($command) {
         case HarbormasterBuildCommand::COMMAND_RESTART:
         case HarbormasterBuildCommand::COMMAND_RESUME:
           $is_resuming = true;
           break;
         case HarbormasterBuildCommand::COMMAND_STOP:
           $is_resuming = false;
           break;
       }
     }
 
     return $is_resuming;
   }
 
   public function isRestarting() {
     $is_restarting = false;
     foreach ($this->getUnprocessedCommands() as $command_object) {
       $command = $command_object->getCommand();
       switch ($command) {
         case HarbormasterBuildCommand::COMMAND_RESTART:
           $is_restarting = true;
           break;
       }
     }
 
     return $is_restarting;
   }
 
   public function deleteUnprocessedCommands() {
     foreach ($this->getUnprocessedCommands() as $key => $command_object) {
       $command_object->delete();
       unset($this->unprocessedCommands[$key]);
     }
 
     return $this;
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new HarbormasterBuildTransactionEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new HarbormasterBuildTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     return $this->getBuildable()->getPolicy($capability);
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return $this->getBuildable()->hasAutomaticCapability(
       $capability,
       $viewer);
   }
 
   public function describeAutomaticCapability($capability) {
     return pht('A build inherits policies from its buildable.');
   }
 
 }
diff --git a/src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php b/src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php
index abf9db331e..3475f00a4f 100644
--- a/src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php
+++ b/src/applications/harbormaster/storage/configuration/HarbormasterBuildPlan.php
@@ -1,95 +1,112 @@
 <?php
 
 final class HarbormasterBuildPlan extends HarbormasterDAO
   implements
+    PhabricatorApplicationTransactionInterface,
     PhabricatorPolicyInterface,
     PhabricatorSubscribableInterface {
 
   protected $name;
   protected $planStatus;
 
   const STATUS_ACTIVE   = 'active';
   const STATUS_DISABLED = 'disabled';
 
   private $buildSteps = self::ATTACHABLE;
 
   public static function initializeNewBuildPlan(PhabricatorUser $actor) {
     return id(new HarbormasterBuildPlan())
       ->setPlanStatus(self::STATUS_ACTIVE);
   }
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'text255',
         'planStatus' => 'text32',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_status' => array(
           'columns' => array('planStatus'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       HarbormasterBuildPlanPHIDType::TYPECONST);
   }
 
   public function attachBuildSteps(array $steps) {
     assert_instances_of($steps, 'HarbormasterBuildStep');
     $this->buildSteps = $steps;
     return $this;
   }
 
   public function getBuildSteps() {
     return $this->assertAttached($this->buildSteps);
   }
 
   public function isDisabled() {
     return ($this->getPlanStatus() == self::STATUS_DISABLED);
   }
 
 
 /* -(  PhabricatorSubscribableInterface  )----------------------------------- */
 
 
   public function isAutomaticallySubscribed($phid) {
     return false;
   }
 
   public function shouldShowSubscribersProperty() {
     return true;
   }
 
   public function shouldAllowSubscription($phid) {
     return true;
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new HarbormasterBuildPlanEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new HarbormasterBuildPlanTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return PhabricatorPolicies::getMostOpenPolicy();
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     return null;
   }
 }
diff --git a/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php b/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
index 82f61ad9e0..858b57abc8 100644
--- a/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
+++ b/src/applications/harbormaster/storage/configuration/HarbormasterBuildStep.php
@@ -1,134 +1,151 @@
 <?php
 
 final class HarbormasterBuildStep extends HarbormasterDAO
   implements
+    PhabricatorApplicationTransactionInterface,
     PhabricatorPolicyInterface,
     PhabricatorCustomFieldInterface {
 
   protected $name;
   protected $description;
   protected $buildPlanPHID;
   protected $className;
   protected $details = array();
   protected $sequence = 0;
 
   private $buildPlan = self::ATTACHABLE;
   private $customFields = self::ATTACHABLE;
   private $implementation;
 
   public static function initializeNewStep(PhabricatorUser $actor) {
     return id(new HarbormasterBuildStep());
   }
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'details' => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'className' => 'text255',
         'sequence' => 'uint32',
         'description' => 'text',
 
         // T6203/NULLABILITY
         // This should not be nullable. Current `null` values indicate steps
         // which predated editable names. These should be backfilled with
         // default names, then the code for handling `null` shoudl be removed.
         'name' => 'text255?',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_plan' => array(
           'columns' => array('buildPlanPHID'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       HarbormasterBuildStepPHIDType::TYPECONST);
   }
 
   public function attachBuildPlan(HarbormasterBuildPlan $plan) {
     $this->buildPlan = $plan;
     return $this;
   }
 
   public function getBuildPlan() {
     return $this->assertAttached($this->buildPlan);
   }
 
   public function getDetail($key, $default = null) {
     return idx($this->details, $key, $default);
   }
 
   public function setDetail($key, $value) {
     $this->details[$key] = $value;
     return $this;
   }
 
   public function getName() {
     if (strlen($this->name)) {
       return $this->name;
     }
 
     return $this->getStepImplementation()->getName();
   }
 
   public function getStepImplementation() {
     if ($this->implementation === null) {
       $obj = HarbormasterBuildStepImplementation::requireImplementation(
         $this->className);
       $obj->loadSettings($this);
       $this->implementation = $obj;
     }
 
     return $this->implementation;
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new HarbormasterBuildStepEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new HarbormasterBuildStepTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
     );
   }
 
   public function getPolicy($capability) {
     return $this->getBuildPlan()->getPolicy($capability);
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return $this->getBuildPlan()->hasAutomaticCapability($capability, $viewer);
   }
 
   public function describeAutomaticCapability($capability) {
     return pht('A build step has the same policies as its build plan.');
   }
 
 
 /* -(  PhabricatorCustomFieldInterface  )------------------------------------ */
 
 
   public function getCustomFieldSpecificationForRole($role) {
     return array();
   }
 
   public function getCustomFieldBaseClass() {
     return 'HarbormasterBuildStepCustomField';
   }
 
   public function getCustomFields() {
     return $this->assertAttached($this->customFields);
   }
 
   public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) {
     $this->customFields = $fields;
     return $this;
   }
 
 
 }
diff --git a/src/applications/legalpad/controller/LegalpadDocumentManageController.php b/src/applications/legalpad/controller/LegalpadDocumentManageController.php
index 21ebf1399b..f4d974d440 100644
--- a/src/applications/legalpad/controller/LegalpadDocumentManageController.php
+++ b/src/applications/legalpad/controller/LegalpadDocumentManageController.php
@@ -1,234 +1,219 @@
 <?php
 
 final class LegalpadDocumentManageController extends LegalpadController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $user = $request->getUser();
 
     // NOTE: We require CAN_EDIT to view this page.
 
     $document = id(new LegalpadDocumentQuery())
       ->setViewer($user)
       ->withIDs(array($this->id))
       ->needDocumentBodies(true)
       ->needContributors(true)
       ->requireCapabilities(
         array(
           PhabricatorPolicyCapability::CAN_VIEW,
           PhabricatorPolicyCapability::CAN_EDIT,
         ))
       ->executeOne();
     if (!$document) {
       return new Aphront404Response();
     }
 
-    $xactions = id(new LegalpadTransactionQuery())
-      ->setViewer($user)
-      ->withObjectPHIDs(array($document->getPHID()))
-      ->execute();
-
     $subscribers = PhabricatorSubscribersQuery::loadSubscribersForPHID(
       $document->getPHID());
 
     $document_body = $document->getDocumentBody();
     $phids = array();
     $phids[] = $document_body->getCreatorPHID();
     foreach ($subscribers as $subscriber) {
       $phids[] = $subscriber;
     }
     foreach ($document->getContributors() as $contributor) {
       $phids[] = $contributor;
     }
     $this->loadHandles($phids);
 
     $engine = id(new PhabricatorMarkupEngine())
       ->setViewer($user);
     $engine->addObject(
       $document_body,
       LegalpadDocumentBody::MARKUP_FIELD_TEXT);
-    foreach ($xactions as $xaction) {
-      if ($xaction->getComment()) {
-        $engine->addObject(
-          $xaction->getComment(),
-          PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
-      }
-    }
-    $engine->process();
+    $timeline = $this->buildTransactionTimeline(
+      $document,
+      new LegalpadTransactionQuery(),
+      $engine);
 
     $title = $document_body->getTitle();
 
     $header = id(new PHUIHeaderView())
       ->setHeader($title)
       ->setUser($user)
       ->setPolicyObject($document);
 
     $actions = $this->buildActionView($document);
     $properties = $this->buildPropertyView($document, $engine, $actions);
 
     $comment_form_id = celerity_generate_unique_node_id();
 
-    $xaction_view = id(new LegalpadTransactionView())
-      ->setUser($this->getRequest()->getUser())
-      ->setObjectPHID($document->getPHID())
-      ->setTransactions($xactions)
-      ->setMarkupEngine($engine);
-
     $add_comment = $this->buildAddCommentView($document, $comment_form_id);
 
     $crumbs = $this->buildApplicationCrumbs($this->buildSideNav());
     $crumbs->setActionList($actions);
     $crumbs->addTextCrumb(
       $document->getMonogram(),
       '/'.$document->getMonogram());
     $crumbs->addTextCrumb(pht('Manage'));
 
     $object_box = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->addPropertyList($properties)
       ->addPropertyList($this->buildDocument($engine, $document_body));
 
     $content = array(
       $crumbs,
       $object_box,
-      $xaction_view,
+      $timeline,
       $add_comment,
     );
 
     return $this->buildApplicationPage(
       $content,
       array(
         'title' => $title,
         'pageObjects' => array($document->getPHID()),
       ));
   }
 
   private function buildDocument(
     PhabricatorMarkupEngine
     $engine, LegalpadDocumentBody $body) {
 
     $view = new PHUIPropertyListView();
     $view->addClass('legalpad');
     $view->addSectionHeader(pht('Document'));
     $view->addTextContent(
       $engine->getOutput($body, LegalpadDocumentBody::MARKUP_FIELD_TEXT));
 
     return $view;
 
   }
 
   private function buildActionView(LegalpadDocument $document) {
     $user = $this->getRequest()->getUser();
 
     $actions = id(new PhabricatorActionListView())
       ->setUser($user)
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setObject($document);
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $user,
       $document,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $doc_id = $document->getID();
 
     $actions->addAction(
       id(new PhabricatorActionView())
       ->setIcon('fa-pencil-square')
       ->setName(pht('View/Sign Document'))
       ->setHref('/'.$document->getMonogram()));
 
     $actions->addAction(
       id(new PhabricatorActionView())
         ->setIcon('fa-pencil')
         ->setName(pht('Edit Document'))
         ->setHref($this->getApplicationURI('/edit/'.$doc_id.'/'))
         ->setDisabled(!$can_edit)
         ->setWorkflow(!$can_edit));
 
     $actions->addAction(
       id(new PhabricatorActionView())
       ->setIcon('fa-terminal')
       ->setName(pht('View Signatures'))
       ->setHref($this->getApplicationURI('/signatures/'.$doc_id.'/')));
 
     return $actions;
   }
 
   private function buildPropertyView(
     LegalpadDocument $document,
     PhabricatorMarkupEngine $engine,
     PhabricatorActionListView $actions) {
 
     $user = $this->getRequest()->getUser();
 
     $properties = id(new PHUIPropertyListView())
       ->setUser($user)
       ->setObject($document)
       ->setActionList($actions);
 
     $properties->addProperty(
       pht('Signature Type'),
       $document->getSignatureTypeName());
 
     $properties->addProperty(
       pht('Last Updated'),
       phabricator_datetime($document->getDateModified(), $user));
 
     $properties->addProperty(
       pht('Updated By'),
       $this->getHandle(
         $document->getDocumentBody()->getCreatorPHID())->renderLink());
 
     $properties->addProperty(
       pht('Versions'),
       $document->getVersions());
 
     $contributor_view = array();
     foreach ($document->getContributors() as $contributor) {
       $contributor_view[] = $this->getHandle($contributor)->renderLink();
     }
     $contributor_view = phutil_implode_html(', ', $contributor_view);
     $properties->addProperty(
       pht('Contributors'),
       $contributor_view);
 
     $properties->invokeWillRenderEvent();
 
     return $properties;
   }
 
   private function buildAddCommentView(
     LegalpadDocument $document,
     $comment_form_id) {
     $user = $this->getRequest()->getUser();
 
     $draft = PhabricatorDraft::newFromUserAndKey($user, $document->getPHID());
 
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
 
     $title = $is_serious
       ? pht('Add Comment')
       : pht('Debate Legislation');
 
     $form = id(new PhabricatorApplicationTransactionCommentView())
       ->setUser($user)
       ->setObjectPHID($document->getPHID())
       ->setFormID($comment_form_id)
       ->setHeaderText($title)
       ->setDraft($draft)
       ->setSubmitButtonName(pht('Add Comment'))
       ->setAction($this->getApplicationURI('/comment/'.$document->getID().'/'))
       ->setRequestURI($this->getRequest()->getRequestURI());
 
     return $form;
 
   }
 
 }
diff --git a/src/applications/nuance/controller/NuanceSourceViewController.php b/src/applications/nuance/controller/NuanceSourceViewController.php
index 781185e2c2..60487582d1 100644
--- a/src/applications/nuance/controller/NuanceSourceViewController.php
+++ b/src/applications/nuance/controller/NuanceSourceViewController.php
@@ -1,133 +1,125 @@
 <?php
 
 final class NuanceSourceViewController extends NuanceController {
 
   private $sourceID;
 
   public function setSourceID($source_id) {
     $this->sourceID = $source_id;
     return $this;
   }
   public function getSourceID() {
     return $this->sourceID;
   }
 
   public function willProcessRequest(array $data) {
     $this->setSourceID($data['id']);
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $source_id = $this->getSourceID();
     $source = id(new NuanceSourceQuery())
       ->setViewer($viewer)
       ->withIDs(array($source_id))
       ->executeOne();
 
     if (!$source) {
       return new Aphront404Response();
     }
 
     $source_phid = $source->getPHID();
-    $xactions = id(new NuanceSourceTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($source_phid))
-      ->execute();
-
-    $engine = id(new PhabricatorMarkupEngine())
-      ->setViewer($viewer);
 
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($source_phid)
-      ->setMarkupEngine($engine)
-      ->setTransactions($xactions);
+    $timeline = $this->buildTransactionTimeline(
+      $source,
+      new NuanceSourceTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     $title = pht('%s', $source->getName());
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($title);
 
     $header = $this->buildHeaderView($source);
     $actions = $this->buildActionView($source);
     $properties = $this->buildPropertyView($source, $actions);
 
     $box = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->addPropertyList($properties);
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $box,
         $timeline,
       ),
       array(
         'title' => $title,
       ));
 
   }
 
 
  private function buildHeaderView(NuanceSource $source) {
     $viewer = $this->getRequest()->getUser();
 
     $header = id(new PHUIHeaderView())
       ->setUser($viewer)
       ->setHeader($source->getName())
       ->setPolicyObject($source);
 
     return $header;
   }
 
   private function buildActionView(NuanceSource $source) {
     $viewer = $this->getRequest()->getUser();
     $id = $source->getID();
 
     $actions = id(new PhabricatorActionListView())
       ->setObjectURI($source->getURI())
       ->setUser($viewer);
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $source,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $actions->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Edit Source'))
         ->setIcon('fa-pencil')
         ->setHref($this->getApplicationURI("source/edit/{$id}/"))
         ->setDisabled(!$can_edit)
         ->setWorkflow(!$can_edit));
 
     return $actions;
   }
 
   private function buildPropertyView(
     NuanceSource $source,
     PhabricatorActionListView $actions) {
     $viewer = $this->getRequest()->getUser();
 
     $properties = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($source)
       ->setActionList($actions);
 
     $definition = NuanceSourceDefinition::getDefinitionForSource($source);
     $properties->addProperty(
       pht('Source Type'),
       $definition->getName());
 
     $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
       $viewer,
       $source);
 
     $properties->addProperty(
       pht('Editable By'),
       $descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
 
     return $properties;
   }
 }
diff --git a/src/applications/nuance/storage/NuanceSource.php b/src/applications/nuance/storage/NuanceSource.php
index 025a60dd89..0bf955a875 100644
--- a/src/applications/nuance/storage/NuanceSource.php
+++ b/src/applications/nuance/storage/NuanceSource.php
@@ -1,91 +1,110 @@
 <?php
 
 final class NuanceSource extends NuanceDAO
-  implements PhabricatorPolicyInterface {
+  implements
+    PhabricatorApplicationTransactionInterface,
+    PhabricatorPolicyInterface {
 
   protected $name;
   protected $type;
   protected $data;
   protected $mailKey;
   protected $viewPolicy;
   protected $editPolicy;
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'data' => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'text255?',
         'type' => 'text32',
         'mailKey' => 'bytes20',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_type' => array(
           'columns' => array('type', 'dateModified'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(NuanceSourcePHIDType::TYPECONST);
   }
 
   public function save() {
     if (!$this->getMailKey()) {
       $this->setMailKey(Filesystem::readRandomCharacters(20));
     }
     return parent::save();
   }
 
   public function getURI() {
     return '/nuance/source/view/'.$this->getID().'/';
   }
 
   public static function initializeNewSource(PhabricatorUser $actor) {
     $app = id(new PhabricatorApplicationQuery())
       ->setViewer($actor)
       ->withClasses(array('PhabricatorNuanceApplication'))
       ->executeOne();
 
     $view_policy = $app->getPolicy(
       NuanceSourceDefaultViewCapability::CAPABILITY);
     $edit_policy = $app->getPolicy(
       NuanceSourceDefaultEditCapability::CAPABILITY);
 
     $definitions = NuanceSourceDefinition::getAllDefinitions();
     $lucky_definition = head($definitions);
 
     return id(new NuanceSource())
       ->setViewPolicy($view_policy)
       ->setEditPolicy($edit_policy)
       ->setType($lucky_definition->getSourceTypeConstant());
   }
 
+
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new NuanceSourceEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new NuanceSourceTransaction();
+  }
+
+
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return $this->getViewPolicy();
       case PhabricatorPolicyCapability::CAN_EDIT:
         return $this->getEditPolicy();
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     return null;
   }
 
 }
diff --git a/src/applications/phortune/controller/PhortuneAccountViewController.php b/src/applications/phortune/controller/PhortuneAccountViewController.php
index 4d6198cf5b..b0eb23fc36 100644
--- a/src/applications/phortune/controller/PhortuneAccountViewController.php
+++ b/src/applications/phortune/controller/PhortuneAccountViewController.php
@@ -1,290 +1,276 @@
 <?php
 
 final class PhortuneAccountViewController extends PhortuneController {
 
   private $accountID;
 
   public function willProcessRequest(array $data) {
     $this->accountID = $data['accountID'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $user = $request->getUser();
 
     // TODO: Currently, you must be able to edit an account to view the detail
     // page, because the account must be broadly visible so merchants can
     // process orders but merchants should not be able to see all the details
     // of an account. Ideally this page should be visible to merchants, too,
     // just with less information.
     $can_edit = true;
 
     $account = id(new PhortuneAccountQuery())
       ->setViewer($user)
       ->withIDs(array($this->accountID))
       ->requireCapabilities(
         array(
           PhabricatorPolicyCapability::CAN_VIEW,
           PhabricatorPolicyCapability::CAN_EDIT,
         ))
       ->executeOne();
     if (!$account) {
       return new Aphront404Response();
     }
 
     $title = $account->getName();
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(
       $account->getName(),
       $request->getRequestURI());
 
     $header = id(new PHUIHeaderView())
       ->setHeader($title);
 
     $edit_uri = $this->getApplicationURI('account/edit/'.$account->getID().'/');
 
     $actions = id(new PhabricatorActionListView())
       ->setUser($user)
       ->setObjectURI($request->getRequestURI())
       ->addAction(
         id(new PhabricatorActionView())
           ->setName(pht('Edit Account'))
           ->setIcon('fa-pencil')
           ->setHref($edit_uri)
           ->setDisabled(!$can_edit)
           ->setWorkflow(!$can_edit));
 
     $crumbs->setActionList($actions);
 
     $properties = id(new PHUIPropertyListView())
       ->setObject($account)
       ->setUser($user);
 
     $this->loadHandles($account->getMemberPHIDs());
 
     $properties->addProperty(
       pht('Members'),
       $this->renderHandlesForPHIDs($account->getMemberPHIDs()));
 
     $properties->setActionList($actions);
 
     $payment_methods = $this->buildPaymentMethodsSection($account);
     $purchase_history = $this->buildPurchaseHistorySection($account);
     $charge_history = $this->buildChargeHistorySection($account);
-    $account_history = $this->buildAccountHistorySection($account);
+    $timeline = $this->buildTransactionTimeline(
+      $account,
+      new PhortuneAccountTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     $object_box = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->addPropertyList($properties);
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $object_box,
         $payment_methods,
         $purchase_history,
         $charge_history,
-        $account_history,
+        $timeline,
       ),
       array(
         'title' => $title,
       ));
   }
 
   private function buildPaymentMethodsSection(PhortuneAccount $account) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $account,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $id = $account->getID();
 
     $header = id(new PHUIHeaderView())
       ->setHeader(pht('Payment Methods'));
 
     $list = id(new PHUIObjectItemListView())
       ->setUser($viewer)
       ->setNoDataString(
         pht('No payment methods associated with this account.'));
 
     $methods = id(new PhortunePaymentMethodQuery())
       ->setViewer($viewer)
       ->withAccountPHIDs(array($account->getPHID()))
       ->execute();
 
     if ($methods) {
       $this->loadHandles(mpull($methods, 'getAuthorPHID'));
     }
 
     foreach ($methods as $method) {
       $id = $method->getID();
 
       $item = new PHUIObjectItemView();
       $item->setHeader($method->getFullDisplayName());
 
       switch ($method->getStatus()) {
         case PhortunePaymentMethod::STATUS_ACTIVE:
           $item->setBarColor('green');
 
           $disable_uri = $this->getApplicationURI('card/'.$id.'/disable/');
           $item->addAction(
             id(new PHUIListItemView())
               ->setIcon('fa-times')
               ->setHref($disable_uri)
               ->setDisabled(!$can_edit)
               ->setWorkflow(true));
           break;
         case PhortunePaymentMethod::STATUS_DISABLED:
           $item->setDisabled(true);
           break;
       }
 
       $provider = $method->buildPaymentProvider();
       $item->addAttribute($provider->getPaymentMethodProviderDescription());
 
       $edit_uri = $this->getApplicationURI('card/'.$id.'/edit/');
 
       $item->addAction(
         id(new PHUIListItemView())
           ->setIcon('fa-pencil')
           ->setHref($edit_uri)
           ->setDisabled(!$can_edit)
           ->setWorkflow(!$can_edit));
 
       $list->addItem($item);
     }
 
     return id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->appendChild($list);
   }
 
   private function buildPurchaseHistorySection(PhortuneAccount $account) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $carts = id(new PhortuneCartQuery())
       ->setViewer($viewer)
       ->withAccountPHIDs(array($account->getPHID()))
       ->needPurchases(true)
       ->withStatuses(
         array(
           PhortuneCart::STATUS_PURCHASING,
           PhortuneCart::STATUS_CHARGED,
           PhortuneCart::STATUS_HOLD,
           PhortuneCart::STATUS_REVIEW,
           PhortuneCart::STATUS_PURCHASED,
         ))
       ->setLimit(10)
       ->execute();
 
     $phids = array();
     foreach ($carts as $cart) {
       $phids[] = $cart->getPHID();
       foreach ($cart->getPurchases() as $purchase) {
         $phids[] = $purchase->getPHID();
       }
     }
     $handles = $this->loadViewerHandles($phids);
 
     $orders_uri = $this->getApplicationURI($account->getID().'/order/');
 
     $table = id(new PhortuneOrderTableView())
       ->setUser($viewer)
       ->setCarts($carts)
       ->setHandles($handles);
 
     $header = id(new PHUIHeaderView())
       ->setHeader(pht('Recent Orders'))
       ->addActionLink(
         id(new PHUIButtonView())
           ->setTag('a')
           ->setIcon(
             id(new PHUIIconView())
               ->setIconFont('fa-list'))
           ->setHref($orders_uri)
           ->setText(pht('View All Orders')));
 
     return id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->appendChild($table);
   }
 
   private function buildChargeHistorySection(PhortuneAccount $account) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $charges = id(new PhortuneChargeQuery())
       ->setViewer($viewer)
       ->withAccountPHIDs(array($account->getPHID()))
       ->needCarts(true)
       ->setLimit(10)
       ->execute();
 
     $phids = array();
     foreach ($charges as $charge) {
       $phids[] = $charge->getProviderPHID();
       $phids[] = $charge->getCartPHID();
       $phids[] = $charge->getMerchantPHID();
       $phids[] = $charge->getPaymentMethodPHID();
     }
 
     $handles = $this->loadViewerHandles($phids);
 
     $charges_uri = $this->getApplicationURI($account->getID().'/charge/');
 
     $table = id(new PhortuneChargeTableView())
       ->setUser($viewer)
       ->setCharges($charges)
       ->setHandles($handles);
 
     $header = id(new PHUIHeaderView())
       ->setHeader(pht('Recent Charges'))
       ->addActionLink(
         id(new PHUIButtonView())
           ->setTag('a')
           ->setIcon(
             id(new PHUIIconView())
               ->setIconFont('fa-list'))
           ->setHref($charges_uri)
           ->setText(pht('View All Charges')));
 
     return id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->appendChild($table);
   }
 
-  private function buildAccountHistorySection(PhortuneAccount $account) {
-    $request = $this->getRequest();
-    $user = $request->getUser();
-
-    $xactions = id(new PhortuneAccountTransactionQuery())
-      ->setViewer($user)
-      ->withObjectPHIDs(array($account->getPHID()))
-      ->execute();
-
-    $xaction_view = id(new PhabricatorApplicationTransactionView())
-      ->setUser($user)
-      ->setObjectPHID($account->getPHID())
-      ->setTransactions($xactions);
-
-    return $xaction_view;
-  }
-
   protected function buildApplicationCrumbs() {
     $crumbs = parent::buildApplicationCrumbs();
 
     $crumbs->addAction(
       id(new PHUIListItemView())
         ->setIcon('fa-exchange')
         ->setHref($this->getApplicationURI('account/'))
         ->setName(pht('Switch Accounts')));
 
     return $crumbs;
   }
 
 }
diff --git a/src/applications/phortune/controller/PhortuneCartViewController.php b/src/applications/phortune/controller/PhortuneCartViewController.php
index d02182ac36..580f92b2c4 100644
--- a/src/applications/phortune/controller/PhortuneCartViewController.php
+++ b/src/applications/phortune/controller/PhortuneCartViewController.php
@@ -1,288 +1,283 @@
 <?php
 
 final class PhortuneCartViewController
   extends PhortuneCartController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $cart = id(new PhortuneCartQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->id))
       ->needPurchases(true)
       ->executeOne();
     if (!$cart) {
       return new Aphront404Response();
     }
 
     $can_admin = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $cart->getMerchant(),
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $cart_table = $this->buildCartContentTable($cart);
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $cart,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $errors = array();
     $error_view = null;
     $resume_uri = null;
     switch ($cart->getStatus()) {
       case PhortuneCart::STATUS_PURCHASING:
         if ($can_edit) {
           $resume_uri = $cart->getMetadataValue('provider.checkoutURI');
           if ($resume_uri) {
             $errors[] = pht(
               'The checkout process has been started, but not yet completed. '.
               'You can continue checking out by clicking %s, or cancel the '.
               'order, or contact the merchant for assistance.',
               phutil_tag('strong', array(), pht('Continue Checkout')));
           } else {
             $errors[] = pht(
               'The checkout process has been started, but an error occurred. '.
               'You can cancel the order or contact the merchant for '.
               'assistance.');
           }
         }
         break;
       case PhortuneCart::STATUS_CHARGED:
         if ($can_edit) {
           $errors[] = pht(
             'You have been charged, but processing could not be completed. '.
             'You can cancel your order, or contact the merchant for '.
             'assistance.');
         }
         break;
       case PhortuneCart::STATUS_HOLD:
         if ($can_edit) {
           $errors[] = pht(
             'Payment for this order is on hold. You can click %s to check '.
             'for updates, cancel the order, or contact the merchant for '.
             'assistance.',
             phutil_tag('strong', array(), pht('Update Status')));
         }
         break;
       case PhortuneCart::STATUS_REVIEW:
         if ($can_admin) {
           $errors[] = pht(
             'This order has been flagged for manual review. Review the order '.
             'and choose %s to accept it or %s to reject it.',
             phutil_tag('strong', array(), pht('Accept Order')),
             phutil_tag('strong', array(), pht('Refund Order')));
         } else if ($can_edit) {
           $errors[] = pht(
             'This order requires manual processing and will complete once '.
             'the merchant accepts it.');
         }
         break;
       case PhortuneCart::STATUS_PURCHASED:
         $error_view = id(new AphrontErrorView())
           ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
           ->appendChild(pht('This purchase has been completed.'));
 
         break;
     }
 
     $properties = $this->buildPropertyListView($cart);
     $actions = $this->buildActionListView(
       $cart,
       $can_edit,
       $can_admin,
       $resume_uri);
     $properties->setActionList($actions);
 
     $header = id(new PHUIHeaderView())
       ->setUser($viewer)
       ->setHeader(pht('Order Detail'));
 
     if ($cart->getStatus() == PhortuneCart::STATUS_PURCHASED) {
       $done_uri = $cart->getDoneURI();
       if ($done_uri) {
         $header->addActionLink(
           id(new PHUIButtonView())
             ->setTag('a')
             ->setHref($done_uri)
             ->setIcon(id(new PHUIIconView())
               ->setIconFont('fa-check-square green'))
             ->setText($cart->getDoneActionName()));
       }
     }
 
     $cart_box = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->appendChild($properties)
       ->appendChild($cart_table);
 
     if ($errors) {
       $cart_box->setFormErrors($errors);
     } else if ($error_view) {
       $cart_box->setErrorView($error_view);
     }
 
     $charges = id(new PhortuneChargeQuery())
       ->setViewer($viewer)
       ->withCartPHIDs(array($cart->getPHID()))
       ->needCarts(true)
       ->execute();
 
     $phids = array();
     foreach ($charges as $charge) {
       $phids[] = $charge->getProviderPHID();
       $phids[] = $charge->getCartPHID();
       $phids[] = $charge->getMerchantPHID();
       $phids[] = $charge->getPaymentMethodPHID();
     }
     $handles = $this->loadViewerHandles($phids);
 
     $charges_table = id(new PhortuneChargeTableView())
       ->setUser($viewer)
       ->setHandles($handles)
       ->setCharges($charges)
       ->setShowOrder(false);
 
     $charges = id(new PHUIObjectBoxView())
       ->setHeaderText(pht('Charges'))
       ->appendChild($charges_table);
 
     $account = $cart->getAccount();
 
     $crumbs = $this->buildApplicationCrumbs();
     $this->addAccountCrumb($crumbs, $cart->getAccount());
     $crumbs->addTextCrumb(pht('Cart %d', $cart->getID()));
     $crumbs->setActionList($actions);
 
-    $xactions = id(new PhortuneCartTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($cart->getPHID()))
-      ->execute();
-
-    $xaction_view = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($cart->getPHID())
-      ->setTransactions($xactions)
-      ->setShouldTerminate(true);
+    $timeline = $this->buildTransactionTimeline(
+      $cart,
+      new PhortuneCartTransactionQuery());
+    $timeline
+     ->setShouldTerminate(true);
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $cart_box,
         $charges,
-        $xaction_view,
+        $timeline,
       ),
       array(
         'title' => pht('Cart'),
       ));
 
   }
 
   private function buildPropertyListView(PhortuneCart $cart) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($cart);
 
     $handles = $this->loadViewerHandles(
       array(
         $cart->getAccountPHID(),
         $cart->getAuthorPHID(),
         $cart->getMerchantPHID(),
       ));
 
     $view->addProperty(
       pht('Order Name'),
       $cart->getName());
     $view->addProperty(
       pht('Account'),
       $handles[$cart->getAccountPHID()]->renderLink());
     $view->addProperty(
       pht('Authorized By'),
       $handles[$cart->getAuthorPHID()]->renderLink());
     $view->addProperty(
       pht('Merchant'),
       $handles[$cart->getMerchantPHID()]->renderLink());
     $view->addProperty(
       pht('Status'),
       PhortuneCart::getNameForStatus($cart->getStatus()));
     $view->addProperty(
       pht('Updated'),
       phabricator_datetime($cart->getDateModified(), $viewer));
 
     return $view;
   }
 
   private function buildActionListView(
     PhortuneCart $cart,
     $can_edit,
     $can_admin,
     $resume_uri) {
 
     $viewer = $this->getRequest()->getUser();
     $id = $cart->getID();
 
     $view = id(new PhabricatorActionListView())
       ->setUser($viewer)
       ->setObject($cart);
 
     $can_cancel = ($can_edit && $cart->canCancelOrder());
 
     $cancel_uri = $this->getApplicationURI("cart/{$id}/cancel/");
     $refund_uri = $this->getApplicationURI("cart/{$id}/refund/");
     $update_uri = $this->getApplicationURI("cart/{$id}/update/");
     $accept_uri = $this->getApplicationURI("cart/{$id}/accept/");
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Cancel Order'))
         ->setIcon('fa-times')
         ->setDisabled(!$can_cancel)
         ->setWorkflow(true)
         ->setHref($cancel_uri));
 
     if ($can_admin) {
       if ($cart->getStatus() == PhortuneCart::STATUS_REVIEW) {
         $view->addAction(
           id(new PhabricatorActionView())
             ->setName(pht('Accept Order'))
             ->setIcon('fa-check')
             ->setWorkflow(true)
             ->setHref($accept_uri));
       }
 
       $view->addAction(
         id(new PhabricatorActionView())
           ->setName(pht('Refund Order'))
           ->setIcon('fa-reply')
           ->setWorkflow(true)
           ->setHref($refund_uri));
     }
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Update Status'))
         ->setIcon('fa-refresh')
         ->setHref($update_uri));
 
     if ($can_edit && $resume_uri) {
       $view->addAction(
         id(new PhabricatorActionView())
           ->setName(pht('Continue Checkout'))
           ->setIcon('fa-shopping-cart')
           ->setHref($resume_uri));
     }
 
     return $view;
   }
 
 }
diff --git a/src/applications/phortune/controller/PhortuneLandingController.php b/src/applications/phortune/controller/PhortuneLandingController.php
index a44790df88..ddff75f9ec 100644
--- a/src/applications/phortune/controller/PhortuneLandingController.php
+++ b/src/applications/phortune/controller/PhortuneLandingController.php
@@ -1,29 +1,31 @@
 <?php
 
 final class PhortuneLandingController extends PhortuneController {
 
   public function processRequest() {
     $request = $this->getRequest();
     $user = $request->getUser();
 
     $accounts = id(new PhortuneAccountQuery())
       ->setViewer($user)
       ->withMemberPHIDs(array($user->getPHID()))
       ->execute();
 
     if (!$accounts) {
-      $account = $this->createUserAccount($user);
+      $account = PhortuneAccount::createNewAccount(
+        $user,
+        PhabricatorContentSource::newFromRequest($request));
       $accounts = array($account);
     }
 
     if (count($accounts) == 1) {
       $account = head($accounts);
       $next_uri = $this->getApplicationURI($account->getID().'/');
     } else {
       $next_uri = $this->getApplicationURI('account/');
     }
 
     return id(new AphrontRedirectResponse())->setURI($next_uri);
   }
 
 }
diff --git a/src/applications/phortune/controller/PhortuneMerchantViewController.php b/src/applications/phortune/controller/PhortuneMerchantViewController.php
index 2fe2b76716..01557a6fb9 100644
--- a/src/applications/phortune/controller/PhortuneMerchantViewController.php
+++ b/src/applications/phortune/controller/PhortuneMerchantViewController.php
@@ -1,291 +1,286 @@
 <?php
 
 final class PhortuneMerchantViewController
   extends PhortuneMerchantController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $merchant = id(new PhortuneMerchantQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->id))
       ->executeOne();
     if (!$merchant) {
       return new Aphront404Response();
     }
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($merchant->getName());
 
     $title = pht(
       'Merchant %d %s',
       $merchant->getID(),
       $merchant->getName());
 
     $header = id(new PHUIHeaderView())
       ->setObjectName(pht('Merchant %d', $merchant->getID()))
       ->setHeader($merchant->getName())
       ->setUser($viewer)
       ->setPolicyObject($merchant);
 
     $providers = id(new PhortunePaymentProviderConfigQuery())
       ->setViewer($viewer)
       ->withMerchantPHIDs(array($merchant->getPHID()))
       ->execute();
 
     $properties = $this->buildPropertyListView($merchant, $providers);
     $actions = $this->buildActionListView($merchant);
     $properties->setActionList($actions);
     $crumbs->setActionList($actions);
 
     $provider_list = $this->buildProviderList(
       $merchant,
       $providers);
 
     $box = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->appendChild($properties);
 
-    $xactions = id(new PhortuneMerchantTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($merchant->getPHID()))
-      ->execute();
-
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($merchant->getPHID())
-      ->setTransactions($xactions);
+    $timeline = $this->buildTransactionTimeline(
+      $merchant,
+      new PhortuneMerchantTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $box,
         $provider_list,
         $timeline,
       ),
       array(
         'title' => $title,
       ));
   }
 
   private function buildPropertyListView(
     PhortuneMerchant $merchant,
     array $providers) {
 
     $viewer = $this->getRequest()->getUser();
 
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($merchant);
 
     $status_view = new PHUIStatusListView();
 
     $have_any = false;
     $any_test = false;
     foreach ($providers as $provider_config) {
       $provider = $provider_config->buildProvider();
       if ($provider->isEnabled()) {
         $have_any = true;
       }
       if (!$provider->isAcceptingLivePayments()) {
         $any_test = true;
       }
     }
 
     if ($have_any) {
       $status_view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
           ->setTarget(pht('Accepts Payments'))
           ->setNote(pht('This merchant can accept payments.')));
 
       if ($any_test) {
         $status_view->addItem(
           id(new PHUIStatusItemView())
             ->setIcon(PHUIStatusItemView::ICON_WARNING, 'yellow')
             ->setTarget(pht('Test Mode'))
             ->setNote(pht('This merchant is accepting test payments.')));
       } else {
         $status_view->addItem(
           id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
             ->setTarget(pht('Live Mode'))
             ->setNote(pht('This merchant is accepting live payments.')));
       }
     } else if ($providers) {
       $status_view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_REJECT, 'red')
           ->setTarget(pht('No Enabled Providers'))
           ->setNote(
             pht(
               'All of the payment providers for this merchant are '.
               'disabled.')));
     } else {
       $status_view->addItem(
         id(new PHUIStatusItemView())
           ->setIcon(PHUIStatusItemView::ICON_WARNING, 'yellow')
           ->setTarget(pht('No Providers'))
           ->setNote(
             pht(
               'This merchant does not have any payment providers configured '.
               'yet, so it can not accept payments. Add a provider.')));
     }
 
     $view->addProperty(pht('Status'), $status_view);
 
     $this->loadHandles($merchant->getMemberPHIDs());
 
     $view->addProperty(
       pht('Members'),
       $this->renderHandlesForPHIDs($merchant->getMemberPHIDs()));
 
     $view->invokeWillRenderEvent();
 
     $description = $merchant->getDescription();
     if (strlen($description)) {
       $description = PhabricatorMarkupEngine::renderOneObject(
         id(new PhabricatorMarkupOneOff())->setContent($description),
         'default',
         $viewer);
 
       $view->addSectionHeader(pht('Description'));
       $view->addTextContent($description);
     }
 
     return $view;
   }
 
   private function buildActionListView(PhortuneMerchant $merchant) {
     $viewer = $this->getRequest()->getUser();
     $id = $merchant->getID();
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $merchant,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $view = id(new PhabricatorActionListView())
       ->setUser($viewer)
       ->setObject($merchant);
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('Edit Merchant'))
         ->setIcon('fa-pencil')
         ->setDisabled(!$can_edit)
         ->setWorkflow(!$can_edit)
         ->setHref($this->getApplicationURI("merchant/edit/{$id}/")));
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName(pht('View Orders'))
         ->setIcon('fa-shopping-cart')
         ->setHref($this->getApplicationURI("merchant/orders/{$id}/"))
         ->setDisabled(!$can_edit)
         ->setWorkflow(!$can_edit));
 
     return $view;
   }
 
   private function buildProviderList(
     PhortuneMerchant $merchant,
     array $providers) {
 
     $viewer = $this->getRequest()->getUser();
     $id = $merchant->getID();
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $merchant,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $provider_list = id(new PHUIObjectItemListView())
       ->setNoDataString(pht('This merchant has no payment providers.'));
 
     foreach ($providers as $provider_config) {
       $provider = $provider_config->buildProvider();
       $provider_id = $provider_config->getID();
 
       $item = id(new PHUIObjectItemView())
         ->setHeader($provider->getName());
 
       if ($provider->isEnabled()) {
         if ($provider->isAcceptingLivePayments()) {
           $item->setBarColor('green');
         } else {
           $item->setBarColor('yellow');
           $item->addIcon('fa-exclamation-triangle', pht('Test Mode'));
         }
 
         $item->addAttribute($provider->getConfigureProvidesDescription());
       } else {
         // Don't show disabled providers to users who can't manage the merchant
         // account.
         if (!$can_edit) {
           continue;
         }
         $item->setDisabled(true);
         $item->addAttribute(
           phutil_tag('em', array(), pht('This payment provider is disabled.')));
       }
 
 
       if ($can_edit) {
         $edit_uri = $this->getApplicationURI(
           "/provider/edit/{$provider_id}/");
         $disable_uri = $this->getApplicationURI(
           "/provider/disable/{$provider_id}/");
 
         if ($provider->isEnabled()) {
           $disable_icon = 'fa-times';
           $disable_name = pht('Disable');
         } else {
           $disable_icon = 'fa-check';
           $disable_name = pht('Enable');
         }
 
         $item->addAction(
           id(new PHUIListItemView())
             ->setIcon($disable_icon)
             ->setHref($disable_uri)
             ->setName($disable_name)
             ->setWorkflow(true));
 
         $item->addAction(
           id(new PHUIListItemView())
             ->setIcon('fa-pencil')
             ->setHref($edit_uri)
             ->setName(pht('Edit')));
       }
 
       $provider_list->addItem($item);
     }
 
     $add_action = id(new PHUIButtonView())
       ->setTag('a')
       ->setHref($this->getApplicationURI('provider/edit/?merchantID='.$id))
       ->setText(pht('Add Payment Provider'))
       ->setDisabled(!$can_edit)
       ->setWorkflow(!$can_edit)
       ->setIcon(id(new PHUIIconView())->setIconFont('fa-plus'));
 
     $header = id(new PHUIHeaderView())
       ->setHeader(pht('Payment Providers'))
       ->addActionLink($add_action);
 
     return id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->appendChild($provider_list);
   }
 
 
 
 }
diff --git a/src/applications/phortune/storage/PhortuneAccount.php b/src/applications/phortune/storage/PhortuneAccount.php
index 316e9c3d62..30f9027eea 100644
--- a/src/applications/phortune/storage/PhortuneAccount.php
+++ b/src/applications/phortune/storage/PhortuneAccount.php
@@ -1,135 +1,153 @@
 <?php
 
 /**
  * An account represents a purchasing entity. An account may have multiple users
  * on it (e.g., several employees of a company have access to the company
  * account), and a user may have several accounts (e.g., a company account and
  * a personal account).
  */
 final class PhortuneAccount extends PhortuneDAO
-  implements PhabricatorPolicyInterface {
+  implements
+    PhabricatorApplicationTransactionInterface,
+    PhabricatorPolicyInterface {
 
   protected $name;
 
   private $memberPHIDs = self::ATTACHABLE;
 
   public static function initializeNewAccount(PhabricatorUser $actor) {
     $account = id(new PhortuneAccount());
 
     $account->memberPHIDs = array();
 
     return $account;
   }
 
   public static function createNewAccount(
     PhabricatorUser $actor,
     PhabricatorContentSource $content_source) {
 
     $account = PhortuneAccount::initializeNewAccount($actor);
 
     $xactions = array();
     $xactions[] = id(new PhortuneAccountTransaction())
       ->setTransactionType(PhortuneAccountTransaction::TYPE_NAME)
       ->setNewValue(pht('Personal Account'));
 
     $xactions[] = id(new PhortuneAccountTransaction())
       ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
       ->setMetadataValue(
         'edge:type',
         PhortuneAccountHasMemberEdgeType::EDGECONST)
       ->setNewValue(
         array(
           '=' => array($actor->getPHID() => $actor->getPHID()),
         ));
 
     $editor = id(new PhortuneAccountEditor())
       ->setActor($actor)
       ->setContentSource($content_source);
 
     // We create an account for you the first time you visit Phortune.
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
 
       $editor->applyTransactions($account, $xactions);
 
     unset($unguarded);
 
     return $account;
   }
 
   public function newCart(
     PhabricatorUser $actor,
     PhortuneCartImplementation $implementation,
     PhortuneMerchant $merchant) {
 
     $cart = PhortuneCart::initializeNewCart($actor, $this, $merchant);
 
     $cart->setCartClass(get_class($implementation));
     $cart->attachImplementation($implementation);
 
     $implementation->willCreateCart($actor, $cart);
 
     return $cart->save();
   }
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'text255',
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       PhortuneAccountPHIDType::TYPECONST);
   }
 
   public function getMemberPHIDs() {
     return $this->assertAttached($this->memberPHIDs);
   }
 
   public function attachMemberPHIDs(array $phids) {
     $this->memberPHIDs = $phids;
     return $this;
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new PhortuneAccountEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new PhortuneAccountTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         // Accounts are technically visible to all users, because merchant
         // controllers need to be able to see accounts in order to process
         // orders. We lock things down more tightly at the application level.
         return PhabricatorPolicies::POLICY_USER;
       case PhabricatorPolicyCapability::CAN_EDIT:
         if ($this->getPHID() === null) {
           // Allow a user to create an account for themselves.
           return PhabricatorPolicies::POLICY_USER;
         } else {
           return PhabricatorPolicies::POLICY_NOONE;
         }
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     $members = array_fuse($this->getMemberPHIDs());
     return isset($members[$viewer->getPHID()]);
   }
 
   public function describeAutomaticCapability($capability) {
     return pht('Members of an account can always view and edit it.');
   }
 
 
 }
diff --git a/src/applications/phortune/storage/PhortuneCart.php b/src/applications/phortune/storage/PhortuneCart.php
index 4edd523a5e..b90223253b 100644
--- a/src/applications/phortune/storage/PhortuneCart.php
+++ b/src/applications/phortune/storage/PhortuneCart.php
@@ -1,645 +1,663 @@
 <?php
 
 final class PhortuneCart extends PhortuneDAO
-  implements PhabricatorPolicyInterface {
+  implements
+    PhabricatorApplicationTransactionInterface,
+    PhabricatorPolicyInterface {
 
   const STATUS_BUILDING = 'cart:building';
   const STATUS_READY = 'cart:ready';
   const STATUS_PURCHASING = 'cart:purchasing';
   const STATUS_CHARGED = 'cart:charged';
   const STATUS_HOLD = 'cart:hold';
   const STATUS_REVIEW = 'cart:review';
   const STATUS_PURCHASED = 'cart:purchased';
 
   protected $accountPHID;
   protected $authorPHID;
   protected $merchantPHID;
   protected $cartClass;
   protected $status;
   protected $metadata = array();
   protected $mailKey;
 
   private $account = self::ATTACHABLE;
   private $purchases = self::ATTACHABLE;
   private $implementation = self::ATTACHABLE;
   private $merchant = self::ATTACHABLE;
 
   public static function initializeNewCart(
     PhabricatorUser $actor,
     PhortuneAccount $account,
     PhortuneMerchant $merchant) {
     $cart = id(new PhortuneCart())
       ->setAuthorPHID($actor->getPHID())
       ->setStatus(self::STATUS_BUILDING)
       ->setAccountPHID($account->getPHID())
       ->setMerchantPHID($merchant->getPHID());
 
     $cart->account = $account;
     $cart->purchases = array();
 
     return $cart;
   }
 
   public function newPurchase(
     PhabricatorUser $actor,
     PhortuneProduct $product) {
 
     $purchase = PhortunePurchase::initializeNewPurchase($actor, $product)
       ->setAccountPHID($this->getAccount()->getPHID())
       ->setCartPHID($this->getPHID())
       ->save();
 
     $this->purchases[] = $purchase;
 
     return $purchase;
   }
 
   public static function getStatusNameMap() {
     return array(
       self::STATUS_BUILDING => pht('Building'),
       self::STATUS_READY => pht('Ready'),
       self::STATUS_PURCHASING => pht('Purchasing'),
       self::STATUS_CHARGED => pht('Charged'),
       self::STATUS_HOLD => pht('Hold'),
       self::STATUS_REVIEW => pht('Review'),
       self::STATUS_PURCHASED => pht('Purchased'),
     );
   }
 
   public static function getNameForStatus($status) {
     return idx(self::getStatusNameMap(), $status, $status);
   }
 
   public function activateCart() {
     $this->openTransaction();
       $this->beginReadLocking();
 
         $copy = clone $this;
         $copy->reload();
 
         if ($copy->getStatus() !== self::STATUS_BUILDING) {
           throw new Exception(
             pht(
               'Cart has wrong status ("%s") to call willApplyCharge().',
               $copy->getStatus()));
         }
 
         $this->setStatus(self::STATUS_READY)->save();
 
       $this->endReadLocking();
     $this->saveTransaction();
 
     $this->recordCartTransaction(PhortuneCartTransaction::TYPE_CREATED);
 
     return $this;
   }
 
   public function willApplyCharge(
     PhabricatorUser $actor,
     PhortunePaymentProvider $provider,
     PhortunePaymentMethod $method = null) {
 
     $account = $this->getAccount();
 
     $charge = PhortuneCharge::initializeNewCharge()
       ->setAccountPHID($account->getPHID())
       ->setCartPHID($this->getPHID())
       ->setAuthorPHID($actor->getPHID())
       ->setMerchantPHID($this->getMerchant()->getPHID())
       ->setProviderPHID($provider->getProviderConfig()->getPHID())
       ->setAmountAsCurrency($this->getTotalPriceAsCurrency());
 
     if ($method) {
       $charge->setPaymentMethodPHID($method->getPHID());
     }
 
     $this->openTransaction();
       $this->beginReadLocking();
 
         $copy = clone $this;
         $copy->reload();
 
         if ($copy->getStatus() !== self::STATUS_READY) {
           throw new Exception(
             pht(
               'Cart has wrong status ("%s") to call willApplyCharge(), '.
               'expected "%s".',
               $copy->getStatus(),
               self::STATUS_READY));
         }
 
         $charge->save();
         $this->setStatus(PhortuneCart::STATUS_PURCHASING)->save();
 
       $this->endReadLocking();
     $this->saveTransaction();
 
     return $charge;
   }
 
   public function didHoldCharge(PhortuneCharge $charge) {
     $charge->setStatus(PhortuneCharge::STATUS_HOLD);
 
     $this->openTransaction();
       $this->beginReadLocking();
 
         $copy = clone $this;
         $copy->reload();
 
         if ($copy->getStatus() !== self::STATUS_PURCHASING) {
           throw new Exception(
             pht(
               'Cart has wrong status ("%s") to call didHoldCharge(), '.
               'expected "%s".',
               $copy->getStatus(),
               self::STATUS_PURCHASING));
         }
 
         $charge->save();
         $this->setStatus(self::STATUS_HOLD)->save();
 
       $this->endReadLocking();
     $this->saveTransaction();
 
     $this->recordCartTransaction(PhortuneCartTransaction::TYPE_HOLD);
   }
 
   public function didApplyCharge(PhortuneCharge $charge) {
     $charge->setStatus(PhortuneCharge::STATUS_CHARGED);
 
     $this->openTransaction();
       $this->beginReadLocking();
 
         $copy = clone $this;
         $copy->reload();
 
         if (($copy->getStatus() !== self::STATUS_PURCHASING) &&
             ($copy->getStatus() !== self::STATUS_HOLD)) {
           throw new Exception(
             pht(
               'Cart has wrong status ("%s") to call didApplyCharge().',
               $copy->getStatus()));
         }
 
         $charge->save();
         $this->setStatus(self::STATUS_CHARGED)->save();
 
       $this->endReadLocking();
     $this->saveTransaction();
 
     // TODO: Perform purchase review. Here, we would apply rules to determine
     // whether the charge needs manual review (maybe making the decision via
     // Herald, configuration, or by examining provider fraud data). For now,
     // always require review.
     $needs_review = true;
 
     if ($needs_review) {
       $this->willReviewCart();
     } else {
       $this->didReviewCart();
     }
 
     return $this;
   }
 
   public function willReviewCart() {
     $this->openTransaction();
       $this->beginReadLocking();
 
         $copy = clone $this;
         $copy->reload();
 
         if (($copy->getStatus() !== self::STATUS_CHARGED)) {
           throw new Exception(
             pht(
               'Cart has wrong status ("%s") to call willReviewCart()!',
               $copy->getStatus()));
         }
 
         $this->setStatus(self::STATUS_REVIEW)->save();
 
       $this->endReadLocking();
     $this->saveTransaction();
 
     $this->recordCartTransaction(PhortuneCartTransaction::TYPE_REVIEW);
 
     return $this;
   }
 
   public function didReviewCart() {
     $this->openTransaction();
       $this->beginReadLocking();
 
         $copy = clone $this;
         $copy->reload();
 
         if (($copy->getStatus() !== self::STATUS_CHARGED) &&
             ($copy->getStatus() !== self::STATUS_REVIEW)) {
           throw new Exception(
             pht(
               'Cart has wrong status ("%s") to call didReviewCart()!',
               $copy->getStatus()));
         }
 
         foreach ($this->purchases as $purchase) {
           $purchase->getProduct()->didPurchaseProduct($purchase);
         }
 
         $this->setStatus(self::STATUS_PURCHASED)->save();
 
       $this->endReadLocking();
     $this->saveTransaction();
 
     $this->recordCartTransaction(PhortuneCartTransaction::TYPE_PURCHASED);
 
     return $this;
   }
 
   public function didFailCharge(PhortuneCharge $charge) {
     $charge->setStatus(PhortuneCharge::STATUS_FAILED);
 
     $this->openTransaction();
       $this->beginReadLocking();
 
         $copy = clone $this;
         $copy->reload();
 
         if (($copy->getStatus() !== self::STATUS_PURCHASING) &&
             ($copy->getStatus() !== self::STATUS_HOLD)) {
           throw new Exception(
             pht(
               'Cart has wrong status ("%s") to call didFailCharge().',
               $copy->getStatus()));
         }
 
         $charge->save();
 
         // Move the cart back into STATUS_READY so the user can try
         // making the purchase again.
         $this->setStatus(self::STATUS_READY)->save();
 
       $this->endReadLocking();
     $this->saveTransaction();
 
     return $this;
   }
 
 
   public function willRefundCharge(
     PhabricatorUser $actor,
     PhortunePaymentProvider $provider,
     PhortuneCharge $charge,
     PhortuneCurrency $amount) {
 
     if (!$amount->isPositive()) {
       throw new Exception(
         pht('Trying to refund nonpositive amount of money!'));
     }
 
     if ($amount->isGreaterThan($charge->getAmountRefundableAsCurrency())) {
       throw new Exception(
         pht('Trying to refund more money than remaining on charge!'));
     }
 
     if ($charge->getRefundedChargePHID()) {
       throw new Exception(
         pht('Trying to refund a refund!'));
     }
 
     if (($charge->getStatus() !== PhortuneCharge::STATUS_CHARGED) &&
         ($charge->getStatus() !== PhortuneCharge::STATUS_HOLD)) {
       throw new Exception(
         pht('Trying to refund an uncharged charge!'));
     }
 
     $refund_charge = PhortuneCharge::initializeNewCharge()
       ->setAccountPHID($this->getAccount()->getPHID())
       ->setCartPHID($this->getPHID())
       ->setAuthorPHID($actor->getPHID())
       ->setMerchantPHID($this->getMerchant()->getPHID())
       ->setProviderPHID($provider->getProviderConfig()->getPHID())
       ->setPaymentMethodPHID($charge->getPaymentMethodPHID())
       ->setRefundedChargePHID($charge->getPHID())
       ->setAmountAsCurrency($amount->negate());
 
     $charge->openTransaction();
       $charge->beginReadLocking();
 
         $copy = clone $charge;
         $copy->reload();
 
         if ($copy->getRefundingPHID() !== null) {
           throw new Exception(
             pht('Trying to refund a charge which is already refunding!'));
         }
 
         $refund_charge->save();
         $charge->setRefundingPHID($refund_charge->getPHID());
         $charge->save();
 
       $charge->endReadLocking();
     $charge->saveTransaction();
 
     return $refund_charge;
   }
 
   public function didRefundCharge(
     PhortuneCharge $charge,
     PhortuneCharge $refund) {
 
     $refund->setStatus(PhortuneCharge::STATUS_CHARGED);
 
     $this->openTransaction();
       $this->beginReadLocking();
 
         $copy = clone $charge;
         $copy->reload();
 
         if ($charge->getRefundingPHID() !== $refund->getPHID()) {
           throw new Exception(
             pht('Charge is in the wrong refunding state!'));
         }
 
         $charge->setRefundingPHID(null);
 
         // NOTE: There's some trickiness here to get the signs right. Both
         // these values are positive but the refund has a negative value.
         $total_refunded = $charge
           ->getAmountRefundedAsCurrency()
           ->add($refund->getAmountAsCurrency()->negate());
 
         $charge->setAmountRefundedAsCurrency($total_refunded);
         $charge->save();
         $refund->save();
 
       $this->endReadLocking();
     $this->saveTransaction();
 
     $amount = $refund->getAmountAsCurrency()->negate();
     foreach ($this->purchases as $purchase) {
       $purchase->getProduct()->didRefundProduct($purchase, $amount);
     }
 
     return $this;
   }
 
   public function didFailRefund(
     PhortuneCharge $charge,
     PhortuneCharge $refund) {
 
     $refund->setStatus(PhortuneCharge::STATUS_FAILED);
 
     $this->openTransaction();
       $this->beginReadLocking();
 
         $copy = clone $charge;
         $copy->reload();
 
         if ($charge->getRefundingPHID() !== $refund->getPHID()) {
           throw new Exception(
             pht('Charge is in the wrong refunding state!'));
         }
 
         $charge->setRefundingPHID(null);
         $charge->save();
         $refund->save();
 
       $this->endReadLocking();
     $this->saveTransaction();
   }
 
   private function recordCartTransaction($type) {
     $omnipotent_user = PhabricatorUser::getOmnipotentUser();
     $phortune_phid = id(new PhabricatorPhortuneApplication())->getPHID();
 
     $xactions = array();
 
     $xactions[] = id(new PhortuneCartTransaction())
       ->setTransactionType($type)
       ->setNewValue(true);
 
     $content_source = PhabricatorContentSource::newForSource(
       PhabricatorContentSource::SOURCE_PHORTUNE,
       array());
 
     $editor = id(new PhortuneCartEditor())
       ->setActor($omnipotent_user)
       ->setActingAsPHID($phortune_phid)
       ->setContentSource($content_source)
       ->setContinueOnMissingFields(true)
       ->setContinueOnNoEffect(true);
 
     $editor->applyTransactions($this, $xactions);
   }
 
   public function getName() {
     return $this->getImplementation()->getName($this);
   }
 
   public function getDoneURI() {
     return $this->getImplementation()->getDoneURI($this);
   }
 
   public function getDoneActionName() {
     return $this->getImplementation()->getDoneActionName($this);
   }
 
   public function getCancelURI() {
     return $this->getImplementation()->getCancelURI($this);
   }
 
   public function getDetailURI() {
     return '/phortune/cart/'.$this->getID().'/';
   }
 
   public function getCheckoutURI() {
     return '/phortune/cart/'.$this->getID().'/checkout/';
   }
 
   public function canCancelOrder() {
     try {
       $this->assertCanCancelOrder();
       return true;
     } catch (Exception $ex) {
       return false;
     }
   }
 
   public function canRefundOrder() {
     try {
       $this->assertCanRefundOrder();
       return true;
     } catch (Exception $ex) {
       return false;
     }
   }
 
   public function assertCanCancelOrder() {
     switch ($this->getStatus()) {
       case self::STATUS_BUILDING:
         throw new Exception(
           pht(
             'This order can not be cancelled because the application has not '.
             'finished building it yet.'));
       case self::STATUS_READY:
         throw new Exception(
           pht(
             'This order can not be cancelled because it has not been placed.'));
     }
 
     return $this->getImplementation()->assertCanCancelOrder($this);
   }
 
   public function assertCanRefundOrder() {
     switch ($this->getStatus()) {
       case self::STATUS_BUILDING:
         throw new Exception(
           pht(
             'This order can not be refunded because the application has not '.
             'finished building it yet.'));
       case self::STATUS_READY:
         throw new Exception(
           pht(
             'This order can not be refunded because it has not been placed.'));
     }
 
     return $this->getImplementation()->assertCanRefundOrder($this);
   }
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'metadata' => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'status' => 'text32',
         'cartClass' => 'text128',
         'mailKey' => 'bytes20',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_account' => array(
           'columns' => array('accountPHID'),
         ),
         'key_merchant' => array(
           'columns' => array('merchantPHID'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       PhortuneCartPHIDType::TYPECONST);
   }
 
   public function save() {
     if (!$this->getMailKey()) {
       $this->setMailKey(Filesystem::readRandomCharacters(20));
     }
     return parent::save();
   }
 
   public function attachPurchases(array $purchases) {
     assert_instances_of($purchases, 'PhortunePurchase');
     $this->purchases = $purchases;
     return $this;
   }
 
   public function getPurchases() {
     return $this->assertAttached($this->purchases);
   }
 
   public function attachAccount(PhortuneAccount $account) {
     $this->account = $account;
     return $this;
   }
 
   public function getAccount() {
     return $this->assertAttached($this->account);
   }
 
   public function attachMerchant(PhortuneMerchant $merchant) {
     $this->merchant = $merchant;
     return $this;
   }
 
   public function getMerchant() {
     return $this->assertAttached($this->merchant);
   }
 
   public function attachImplementation(
     PhortuneCartImplementation $implementation) {
     $this->implementation = $implementation;
     return $this;
   }
 
   public function getImplementation() {
     return $this->assertAttached($this->implementation);
   }
 
   public function getTotalPriceAsCurrency() {
     $prices = array();
     foreach ($this->getPurchases() as $purchase) {
       $prices[] = $purchase->getTotalPriceAsCurrency();
     }
 
     return PhortuneCurrency::newFromList($prices);
   }
 
   public function setMetadataValue($key, $value) {
     $this->metadata[$key] = $value;
     return $this;
   }
 
   public function getMetadataValue($key, $default = null) {
     return idx($this->metadata, $key, $default);
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new PhortuneCartEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new PhortuneCartTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     // NOTE: Both view and edit use the account's edit policy. We punch a hole
     // through this for merchants, below.
     return $this
       ->getAccount()
       ->getPolicy(PhabricatorPolicyCapability::CAN_EDIT);
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     if ($this->getAccount()->hasAutomaticCapability($capability, $viewer)) {
       return true;
     }
 
     // If the viewer controls the merchant this order was placed with, they
     // can view the order.
     if ($capability == PhabricatorPolicyCapability::CAN_VIEW) {
       $can_admin = PhabricatorPolicyFilter::hasCapability(
         $viewer,
         $this->getMerchant(),
         PhabricatorPolicyCapability::CAN_EDIT);
       if ($can_admin) {
         return true;
       }
     }
 
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     return array(
       pht('Orders inherit the policies of the associated account.'),
       pht('The merchant you placed an order with can review and manage it.'),
     );
   }
 
 }
diff --git a/src/applications/phortune/storage/PhortuneMerchant.php b/src/applications/phortune/storage/PhortuneMerchant.php
index a54fd4dcf0..05dbb00ebb 100644
--- a/src/applications/phortune/storage/PhortuneMerchant.php
+++ b/src/applications/phortune/storage/PhortuneMerchant.php
@@ -1,75 +1,93 @@
 <?php
 
 final class PhortuneMerchant extends PhortuneDAO
-  implements PhabricatorPolicyInterface {
+  implements
+    PhabricatorApplicationTransactionInterface,
+    PhabricatorPolicyInterface {
 
   protected $name;
   protected $viewPolicy;
   protected $description;
 
   private $memberPHIDs = self::ATTACHABLE;
 
   public static function initializeNewMerchant(PhabricatorUser $actor) {
     return id(new PhortuneMerchant())
       ->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())
       ->attachMemberPHIDs(array());
   }
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'text255',
         'description' => 'text',
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       PhortuneMerchantPHIDType::TYPECONST);
   }
 
   public function getMemberPHIDs() {
     return $this->assertAttached($this->memberPHIDs);
   }
 
   public function attachMemberPHIDs(array $member_phids) {
     $this->memberPHIDs = $member_phids;
     return $this;
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new PhortuneMerchantEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new PhortuneMerchantTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return $this->getViewPolicy();
       case PhabricatorPolicyCapability::CAN_EDIT:
         return PhabricatorPolicies::POLICY_NOONE;
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     $members = array_fuse($this->getMemberPHIDs());
     if (isset($members[$viewer->getPHID()])) {
       return true;
     }
 
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     return pht("A merchant's members an always view and edit it.");
   }
 
 }
diff --git a/src/applications/ponder/controller/PonderAnswerCommentController.php b/src/applications/ponder/controller/PonderAnswerCommentController.php
index b59dd4259c..711908c6ed 100644
--- a/src/applications/ponder/controller/PonderAnswerCommentController.php
+++ b/src/applications/ponder/controller/PonderAnswerCommentController.php
@@ -1,70 +1,70 @@
 <?php
 
 final class PonderAnswerCommentController extends PonderController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     if (!$request->isFormPost()) {
       return new Aphront400Response();
     }
 
     $answer = id(new PonderAnswerQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->id))
       ->executeOne();
     if (!$answer) {
       return new Aphront404Response();
     }
 
     $is_preview = $request->isPreviewRequest();
 //    $draft = PhabricatorDraft::buildFromRequest($request);
 
     $qid = $answer->getQuestion()->getID();
     $aid = $answer->getID();
-    $view_uri = "Q{$qid}#A{$aid}";
+    $view_uri = "/Q{$qid}#A{$aid}";
 
     $xactions = array();
     $xactions[] = id(new PonderAnswerTransaction())
       ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
       ->attachComment(
         id(new PonderAnswerTransactionComment())
           ->setContent($request->getStr('comment')));
 
     $editor = id(new PonderAnswerEditor())
       ->setActor($viewer)
       ->setContinueOnNoEffect($request->isContinueRequest())
       ->setContentSourceFromRequest($request)
       ->setIsPreview($is_preview);
 
     try {
       $xactions = $editor->applyTransactions($answer, $xactions);
     } catch (PhabricatorApplicationTransactionNoEffectException $ex) {
       return id(new PhabricatorApplicationTransactionNoEffectResponse())
         ->setCancelURI($view_uri)
         ->setException($ex);
     }
 
 //    if ($draft) {
 //      $draft->replaceOrDelete();
 //    }
 
     if ($request->isAjax() && $is_preview) {
       return id(new PhabricatorApplicationTransactionResponse())
         ->setViewer($viewer)
         ->setTransactions($xactions)
         ->setIsPreview($is_preview);
     } else {
       return id(new AphrontRedirectResponse())
         ->setURI($view_uri);
     }
   }
 
 }
diff --git a/src/applications/ponder/controller/PonderAnswerHistoryController.php b/src/applications/ponder/controller/PonderAnswerHistoryController.php
index dbecfa1394..931c090e02 100644
--- a/src/applications/ponder/controller/PonderAnswerHistoryController.php
+++ b/src/applications/ponder/controller/PonderAnswerHistoryController.php
@@ -1,63 +1,47 @@
 <?php
 
 final class PonderAnswerHistoryController extends PonderController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $answer = id(new PonderAnswerQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->id))
       ->executeOne();
     if (!$answer) {
       return new Aphront404Response();
     }
 
-    $xactions = id(new PonderAnswerTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($answer->getPHID()))
-      ->execute();
-
-    $engine = id(new PhabricatorMarkupEngine())
-      ->setViewer($viewer);
-    foreach ($xactions as $xaction) {
-      if ($xaction->getComment()) {
-        $engine->addObject(
-          $xaction->getComment(),
-          PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
-      }
-    }
-    $engine->process();
 
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($answer->getPHID())
-      ->setTransactions($xactions)
-      ->setMarkupEngine($engine);
+    $timeline = $this->buildTransactionTimeline(
+      $answer,
+      new PonderAnswerTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     $qid = $answer->getQuestion()->getID();
     $aid = $answer->getID();
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb("Q{$qid}", "/Q{$qid}");
     $crumbs->addTextCrumb("A{$aid}", "/Q{$qid}#{$aid}");
     $crumbs->addTextCrumb(pht('History'));
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $timeline,
       ),
       array(
         'title' => pht('Answer History'),
       ));
   }
 
 }
diff --git a/src/applications/ponder/controller/PonderQuestionHistoryController.php b/src/applications/ponder/controller/PonderQuestionHistoryController.php
index 196d5658eb..253dbcc26c 100644
--- a/src/applications/ponder/controller/PonderQuestionHistoryController.php
+++ b/src/applications/ponder/controller/PonderQuestionHistoryController.php
@@ -1,61 +1,44 @@
 <?php
 
 final class PonderQuestionHistoryController extends PonderController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $question = id(new PonderQuestionQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->id))
       ->executeOne();
     if (!$question) {
       return new Aphront404Response();
     }
 
-    $xactions = id(new PonderQuestionTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($question->getPHID()))
-      ->execute();
-
-    $engine = id(new PhabricatorMarkupEngine())
-      ->setViewer($viewer);
-    foreach ($xactions as $xaction) {
-      if ($xaction->getComment()) {
-        $engine->addObject(
-          $xaction->getComment(),
-          PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
-      }
-    }
-    $engine->process();
-
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($question->getPHID())
-      ->setTransactions($xactions)
-      ->setMarkupEngine($engine);
+    $timeline = $this->buildTransactionTimeline(
+      $question,
+      new PonderQuestionTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     $qid = $question->getID();
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb("Q{$qid}", "/Q{$qid}");
     $crumbs->addTextCrumb(pht('History'));
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $timeline,
       ),
       array(
         'title' => pht('Question History'),
       ));
   }
 
 }
diff --git a/src/applications/ponder/controller/PonderQuestionViewController.php b/src/applications/ponder/controller/PonderQuestionViewController.php
index 2c046b50e2..e606bb2b93 100644
--- a/src/applications/ponder/controller/PonderQuestionViewController.php
+++ b/src/applications/ponder/controller/PonderQuestionViewController.php
@@ -1,415 +1,405 @@
 <?php
 
 final class PonderQuestionViewController extends PonderController {
 
   private $questionID;
 
   public function willProcessRequest(array $data) {
     $this->questionID = $data['id'];
   }
 
   public function processRequest() {
 
     $request = $this->getRequest();
     $user = $request->getUser();
 
     $question = id(new PonderQuestionQuery())
       ->setViewer($user)
       ->withIDs(array($this->questionID))
       ->needAnswers(true)
       ->needViewerVotes(true)
       ->executeOne();
     if (!$question) {
       return new Aphront404Response();
     }
 
     $question->attachVotes($user->getPHID());
 
     $question_xactions = $this->buildQuestionTransactions($question);
     $answers = $this->buildAnswers($question->getAnswers());
 
     $authors = mpull($question->getAnswers(), null, 'getAuthorPHID');
     if (isset($authors[$user->getPHID()])) {
       $answer_add_panel = id(new AphrontErrorView())
         ->setSeverity(AphrontErrorView::SEVERITY_NODATA)
         ->appendChild(
           pht(
             'You have already answered this question. You can not answer '.
             'twice, but you can edit your existing answer.'));
     } else {
       $answer_add_panel = new PonderAddAnswerView();
       $answer_add_panel
         ->setQuestion($question)
         ->setUser($user)
         ->setActionURI('/ponder/answer/add/');
     }
 
     $header = id(new PHUIHeaderView())
       ->setHeader($question->getTitle());
 
     $actions = $this->buildActionListView($question);
     $properties = $this->buildPropertyListView($question, $actions);
 
     $object_box = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->addPropertyList($properties);
 
     $crumbs = $this->buildApplicationCrumbs($this->buildSideNavView());
     $crumbs->setActionList($actions);
     $crumbs->addTextCrumb('Q'.$this->questionID, '/Q'.$this->questionID);
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $object_box,
         $question_xactions,
         $answers,
         $answer_add_panel,
       ),
       array(
         'title' => 'Q'.$question->getID().' '.$question->getTitle(),
         'pageObjects' => array_merge(
           array($question->getPHID()),
           mpull($question->getAnswers(), 'getPHID')),
       ));
   }
 
   private function buildActionListView(PonderQuestion $question) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $id = $question->getID();
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $question,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $view = id(new PhabricatorActionListView())
       ->setUser($request->getUser())
       ->setObject($question)
       ->setObjectURI($request->getRequestURI());
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setIcon('fa-pencil')
         ->setName(pht('Edit Question'))
         ->setHref($this->getApplicationURI("/question/edit/{$id}/"))
         ->setDisabled(!$can_edit)
         ->setWorkflow(!$can_edit));
 
     if ($question->getStatus() == PonderQuestionStatus::STATUS_OPEN) {
       $name = pht('Close Question');
       $icon = 'fa-times';
       $href = 'close';
     } else {
       $name = pht('Reopen Question');
       $icon = 'fa-check-circle-o';
       $href = 'open';
     }
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setName($name)
         ->setIcon($icon)
         ->setRenderAsForm($can_edit)
         ->setWorkflow(!$can_edit)
         ->setDisabled(!$can_edit)
         ->setHref($this->getApplicationURI("/question/{$href}/{$id}/")));
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setIcon('fa-list')
         ->setName(pht('View History'))
         ->setHref($this->getApplicationURI("/question/history/{$id}/")));
 
     return $view;
   }
 
   private function buildPropertyListView(
     PonderQuestion $question,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($question)
       ->setActionList($actions);
 
     $this->loadHandles(array($question->getAuthorPHID()));
 
     $view->addProperty(
       pht('Status'),
       PonderQuestionStatus::getQuestionStatusFullName($question->getStatus()));
 
     $view->addProperty(
       pht('Author'),
       $this->getHandle($question->getAuthorPHID())->renderLink());
 
     $view->addProperty(
       pht('Created'),
       phabricator_datetime($question->getDateCreated(), $viewer));
 
     $view->invokeWillRenderEvent();
 
     $votable = id(new PonderVotableView())
       ->setPHID($question->getPHID())
       ->setURI($this->getApplicationURI('vote/'))
       ->setCount($question->getVoteCount())
       ->setVote($question->getUserVote());
 
     $view->addSectionHeader(pht('Question'));
     $view->addTextContent(
       array(
         $votable,
         phutil_tag(
           'div',
           array(
             'class' => 'phabricator-remarkup',
           ),
           PhabricatorMarkupEngine::renderOneObject(
             $question,
             $question->getMarkupField(),
             $viewer)),
       ));
 
 
     return $view;
   }
 
   private function buildQuestionTransactions(PonderQuestion $question) {
-    $viewer = $this->getRequest()->getUser();
+    $viewer = $this->getViewer();
     $id = $question->getID();
 
-    $xactions = id(new PonderQuestionTransactionQuery())
-      ->setViewer($viewer)
-      ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT))
-      ->withObjectPHIDs(array($question->getPHID()))
-      ->execute();
-
-    $engine = id(new PhabricatorMarkupEngine())
-      ->setViewer($viewer);
-    foreach ($xactions as $xaction) {
-      if ($xaction->getComment()) {
-        $engine->addObject(
-          $xaction->getComment(),
-          PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
-      }
-    }
-    $engine->process();
-
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($question->getPHID())
-      ->setTransactions($xactions)
-      ->setMarkupEngine($engine);
+    $timeline = $this->buildTransactionTimeline(
+      $question,
+      id(new PonderQuestionTransactionQuery())
+      ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT)));
+    $xactions = $timeline->getTransactions();
 
     $add_comment = id(new PhabricatorApplicationTransactionCommentView())
       ->setUser($viewer)
       ->setObjectPHID($question->getPHID())
       ->setShowPreview(false)
       ->setHeaderText(pht('Question Comment'))
       ->setAction($this->getApplicationURI("/question/comment/{$id}/"))
       ->setSubmitButtonName(pht('Comment'));
 
     return $this->wrapComments(
       count($xactions),
       array(
         $timeline,
         $add_comment,
       ));
   }
 
+  /**
+   * This is fairly non-standard; building N timelines at once (N = number of
+   * answers) is tricky business.
+   *
+   * TODO - re-factor this to ajax in one answer panel at a time in a more
+   * standard fashion. This is necessary to scale this application.
+   */
   private function buildAnswers(array $answers) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $out = array();
 
     $phids = mpull($answers, 'getAuthorPHID');
     $this->loadHandles($phids);
 
     $xactions = id(new PonderAnswerTransactionQuery())
       ->setViewer($viewer)
       ->withTransactionTypes(array(PhabricatorTransactions::TYPE_COMMENT))
       ->withObjectPHIDs(mpull($answers, 'getPHID'))
       ->execute();
 
     $engine = id(new PhabricatorMarkupEngine())
       ->setViewer($viewer);
     foreach ($xactions as $xaction) {
       if ($xaction->getComment()) {
         $engine->addObject(
           $xaction->getComment(),
           PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
       }
     }
     $engine->process();
 
     $xaction_groups = mgroup($xactions, 'getObjectPHID');
 
     foreach ($answers as $answer) {
       $author_phid = $answer->getAuthorPHID();
       $xactions = idx($xaction_groups, $answer->getPHID(), array());
       $id = $answer->getID();
 
       $out[] = phutil_tag('br');
       $out[] = phutil_tag('br');
       $out[] = id(new PhabricatorAnchorView())
         ->setAnchorName("A$id");
       $header = id(new PHUIHeaderView())
         ->setHeader($this->getHandle($author_phid)->getFullName());
 
       $actions = $this->buildAnswerActions($answer);
       $properties = $this->buildAnswerProperties($answer, $actions);
 
       $object_box = id(new PHUIObjectBoxView())
         ->setHeader($header)
         ->addPropertyList($properties);
 
       $out[] = $object_box;
       $details = array();
 
       $details[] = id(new PhabricatorApplicationTransactionView())
         ->setUser($viewer)
         ->setObjectPHID($answer->getPHID())
         ->setTransactions($xactions)
         ->setMarkupEngine($engine);
 
       $form = id(new PhabricatorApplicationTransactionCommentView())
         ->setUser($viewer)
         ->setObjectPHID($answer->getPHID())
         ->setShowPreview(false)
         ->setHeaderText(pht('Answer Comment'))
         ->setAction($this->getApplicationURI("/answer/comment/{$id}/"))
         ->setSubmitButtonName(pht('Comment'));
 
       $details[] = $form;
 
       $out[] = $this->wrapComments(
         count($xactions),
         $details);
     }
 
     $out[] = phutil_tag('br');
     $out[] = phutil_tag('br');
 
     return $out;
   }
 
   private function buildAnswerActions(PonderAnswer $answer) {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $id = $answer->getID();
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $answer,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $view = id(new PhabricatorActionListView())
       ->setUser($request->getUser())
       ->setObject($answer)
       ->setObjectURI($request->getRequestURI());
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setIcon('fa-pencil')
         ->setName(pht('Edit Answer'))
         ->setHref($this->getApplicationURI("/answer/edit/{$id}/"))
         ->setDisabled(!$can_edit)
         ->setWorkflow(!$can_edit));
 
     $view->addAction(
       id(new PhabricatorActionView())
         ->setIcon('fa-list')
         ->setName(pht('View History'))
         ->setHref($this->getApplicationURI("/answer/history/{$id}/")));
 
     return $view;
   }
 
   private function buildAnswerProperties(
     PonderAnswer $answer,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getRequest()->getUser();
     $view = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($answer)
       ->setActionList($actions);
 
     $view->addProperty(
       pht('Created'),
       phabricator_datetime($answer->getDateCreated(), $viewer));
 
     $view->invokeWillRenderEvent();
 
     $votable = id(new PonderVotableView())
       ->setPHID($answer->getPHID())
       ->setURI($this->getApplicationURI('vote/'))
       ->setCount($answer->getVoteCount())
       ->setVote($answer->getUserVote());
 
     $view->addSectionHeader(pht('Answer'));
     $view->addTextContent(
       array(
         $votable,
         phutil_tag(
           'div',
           array(
             'class' => 'phabricator-remarkup',
           ),
           PhabricatorMarkupEngine::renderOneObject(
             $answer,
             $answer->getMarkupField(),
             $viewer)),
       ));
 
     return $view;
   }
 
   private function wrapComments($n, $stuff) {
     if ($n == 0) {
       $text = pht('Add a Comment');
     } else {
       $text = pht('Show %s Comments', new PhutilNumber($n));
     }
 
     $show_id = celerity_generate_unique_node_id();
     $hide_id = celerity_generate_unique_node_id();
 
     Javelin::initBehavior('phabricator-reveal-content');
     require_celerity_resource('ponder-comment-table-css');
 
     $show = phutil_tag(
       'div',
       array(
         'id' => $show_id,
         'class' => 'ponder-show-comments',
       ),
       javelin_tag(
         'a',
         array(
           'href' => '#',
           'sigil' => 'reveal-content',
           'meta' => array(
             'showIDs' => array($hide_id),
             'hideIDs' => array($show_id),
           ),
         ),
         $text));
 
     $hide = phutil_tag(
       'div',
       array(
         'id' => $hide_id,
         'style' => 'display: none',
       ),
       $stuff);
 
     return array($show, $hide);
   }
 
 }
diff --git a/src/applications/ponder/storage/PonderAnswer.php b/src/applications/ponder/storage/PonderAnswer.php
index a85aa6d3ad..6cdf079d45 100644
--- a/src/applications/ponder/storage/PonderAnswer.php
+++ b/src/applications/ponder/storage/PonderAnswer.php
@@ -1,236 +1,254 @@
 <?php
 
 final class PonderAnswer extends PonderDAO
   implements
+    PhabricatorApplicationTransactionInterface,
     PhabricatorMarkupInterface,
     PonderVotableInterface,
     PhabricatorPolicyInterface,
     PhabricatorFlaggableInterface,
     PhabricatorSubscribableInterface,
     PhabricatorTokenReceiverInterface,
     PhabricatorDestructibleInterface {
 
   const MARKUP_FIELD_CONTENT = 'markup:content';
 
   protected $authorPHID;
   protected $questionID;
 
   protected $content;
   protected $contentSource;
 
   protected $voteCount;
   private $vote;
   private $question = self::ATTACHABLE;
   private $comments;
 
   private $userVotes = array();
 
   public function attachQuestion(PonderQuestion $question = null) {
     $this->question = $question;
     return $this;
   }
 
   public function getQuestion() {
     return $this->assertAttached($this->question);
   }
 
   public function getURI() {
     return '/Q'.$this->getQuestionID().'#A'.$this->getID();
   }
 
   public function setUserVote($vote) {
     $this->vote = $vote['data'];
     if (!$this->vote) {
       $this->vote = PonderVote::VOTE_NONE;
     }
     return $this;
   }
 
   public function attachUserVote($user_phid, $vote) {
     $this->vote = $vote;
     return $this;
   }
 
   public function getUserVote() {
     return $this->vote;
   }
 
   public function setComments($comments) {
     $this->comments = $comments;
     return $this;
   }
 
   public function getComments() {
     return $this->comments;
   }
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'voteCount' => 'sint32',
         'content' => 'text',
 
         // T6203/NULLABILITY
         // This should always exist.
         'contentSource' => 'text?',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_phid' => null,
         'phid' => array(
           'columns' => array('phid'),
           'unique' => true,
         ),
         'key_oneanswerperquestion' => array(
           'columns' => array('questionID', 'authorPHID'),
           'unique' => true,
         ),
         'questionID' => array(
           'columns' => array('questionID'),
         ),
         'authorPHID' => array(
           'columns' => array('authorPHID'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(PonderAnswerPHIDType::TYPECONST);
   }
 
   public function setContentSource(PhabricatorContentSource $content_source) {
     $this->contentSource = $content_source->serialize();
     return $this;
   }
 
   public function getContentSource() {
     return PhabricatorContentSource::newFromSerialized($this->contentSource);
   }
 
   public function getMarkupField() {
     return self::MARKUP_FIELD_CONTENT;
   }
 
+
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new PonderAnswerEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new PonderAnswerTransaction();
+  }
+
+
   // Markup interface
 
   public function getMarkupFieldKey($field) {
     $hash = PhabricatorHash::digest($this->getMarkupText($field));
     $id = $this->getID();
     return "ponder:A{$id}:{$field}:{$hash}";
   }
 
   public function getMarkupText($field) {
     return $this->getContent();
   }
 
   public function newMarkupEngine($field) {
     return PhabricatorMarkupEngine::getEngine();
   }
 
   public function didMarkupText(
     $field,
     $output,
     PhutilMarkupEngine $engine) {
     return $output;
   }
 
   public function shouldUseMarkupCache($field) {
     return (bool)$this->getID();
   }
 
   // votable interface
   public function getUserVoteEdgeType() {
     return PhabricatorEdgeConfig::TYPE_VOTING_USER_HAS_ANSWER;
   }
 
   public function getVotablePHID() {
     return $this->getPHID();
   }
 
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return $this->getQuestion()->getPolicy($capability);
       case PhabricatorPolicyCapability::CAN_EDIT:
         return PhabricatorPolicies::POLICY_NOONE;
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         if ($this->getAuthorPHID() == $viewer->getPHID()) {
           return true;
         }
         return $this->getQuestion()->hasAutomaticCapability(
           $capability,
           $viewer);
       case PhabricatorPolicyCapability::CAN_EDIT:
         return ($this->getAuthorPHID() == $viewer->getPHID());
     }
   }
 
 
   public function describeAutomaticCapability($capability) {
     $out = array();
     $out[] = pht('The author of an answer can always view and edit it.');
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         $out[] = pht(
           'The user who asks a question can always view the answers.');
         break;
     }
     return $out;
   }
 
 
 /* -(  PhabricatorTokenReceiverInterface  )---------------------------------- */
 
 
   public function getUsersToNotifyOfTokenGiven() {
     return array(
       $this->getAuthorPHID(),
     );
   }
 
 
 /* -(  PhabricatorSubscribableInterface  )----------------------------------- */
 
 
   public function isAutomaticallySubscribed($phid) {
     return ($phid == $this->getAuthorPHID());
   }
 
   public function shouldShowSubscribersProperty() {
     return true;
   }
 
   public function shouldAllowSubscription($phid) {
     return true;
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $this->openTransaction();
       $this->delete();
     $this->saveTransaction();
   }
 
 }
diff --git a/src/applications/ponder/storage/PonderQuestion.php b/src/applications/ponder/storage/PonderQuestion.php
index 5caa52ad78..abeda5e98c 100644
--- a/src/applications/ponder/storage/PonderQuestion.php
+++ b/src/applications/ponder/storage/PonderQuestion.php
@@ -1,277 +1,295 @@
 <?php
 
 final class PonderQuestion extends PonderDAO
   implements
+    PhabricatorApplicationTransactionInterface,
     PhabricatorMarkupInterface,
     PonderVotableInterface,
     PhabricatorSubscribableInterface,
     PhabricatorFlaggableInterface,
     PhabricatorPolicyInterface,
     PhabricatorTokenReceiverInterface,
     PhabricatorProjectInterface,
     PhabricatorDestructibleInterface {
 
   const MARKUP_FIELD_CONTENT = 'markup:content';
 
   protected $title;
   protected $phid;
 
   protected $authorPHID;
   protected $status;
   protected $content;
   protected $contentSource;
 
   protected $voteCount;
   protected $answerCount;
   protected $heat;
   protected $mailKey;
 
   private $answers;
   private $vote;
   private $comments;
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'title' => 'text255',
         'voteCount' => 'sint32',
         'status' => 'uint32',
         'content' => 'text',
         'heat' => 'double',
         'answerCount' => 'uint32',
         'mailKey' => 'bytes20',
 
         // T6203/NULLABILITY
         // This should always exist.
         'contentSource' => 'text?',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_phid' => null,
         'phid' => array(
           'columns' => array('phid'),
           'unique' => true,
         ),
         'authorPHID' => array(
           'columns' => array('authorPHID'),
         ),
         'heat' => array(
           'columns' => array('heat'),
         ),
         'status' => array(
           'columns' => array('status'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(PonderQuestionPHIDType::TYPECONST);
   }
 
   public function setContentSource(PhabricatorContentSource $content_source) {
     $this->contentSource = $content_source->serialize();
     return $this;
   }
 
   public function getContentSource() {
     return PhabricatorContentSource::newFromSerialized($this->contentSource);
   }
 
   public function attachVotes($user_phid) {
     $qa_phids = mpull($this->answers, 'getPHID') + array($this->getPHID());
 
     $edges = id(new PhabricatorEdgeQuery())
       ->withSourcePHIDs(array($user_phid))
       ->withDestinationPHIDs($qa_phids)
       ->withEdgeTypes(
         array(
           PhabricatorEdgeConfig::TYPE_VOTING_USER_HAS_QUESTION,
           PhabricatorEdgeConfig::TYPE_VOTING_USER_HAS_ANSWER,
         ))
       ->needEdgeData(true)
       ->execute();
 
     $question_edge =
       $edges[$user_phid][PhabricatorEdgeConfig::TYPE_VOTING_USER_HAS_QUESTION];
     $answer_edges =
       $edges[$user_phid][PhabricatorEdgeConfig::TYPE_VOTING_USER_HAS_ANSWER];
     $edges = null;
 
     $this->setUserVote(idx($question_edge, $this->getPHID()));
     foreach ($this->answers as $answer) {
       $answer->setUserVote(idx($answer_edges, $answer->getPHID()));
     }
   }
 
   public function setUserVote($vote) {
     $this->vote = $vote['data'];
     if (!$this->vote) {
       $this->vote = PonderVote::VOTE_NONE;
     }
     return $this;
   }
 
   public function attachUserVote($user_phid, $vote) {
     $this->vote = $vote;
     return $this;
   }
 
   public function getUserVote() {
     return $this->vote;
   }
 
   public function setComments($comments) {
     $this->comments = $comments;
     return $this;
   }
 
   public function getComments() {
     return $this->comments;
   }
 
   public function attachAnswers(array $answers) {
     assert_instances_of($answers, 'PonderAnswer');
     $this->answers = $answers;
     return $this;
   }
 
   public function getAnswers() {
     return $this->answers;
   }
 
   public function getMarkupField() {
     return self::MARKUP_FIELD_CONTENT;
   }
 
+
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new PonderQuestionEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new PonderQuestionTransaction();
+  }
+
+
   // Markup interface
 
   public function getMarkupFieldKey($field) {
     $hash = PhabricatorHash::digest($this->getMarkupText($field));
     $id = $this->getID();
     return "ponder:Q{$id}:{$field}:{$hash}";
   }
 
   public function getMarkupText($field) {
     return $this->getContent();
   }
 
   public function newMarkupEngine($field) {
     return PhabricatorMarkupEngine::getEngine();
   }
 
   public function didMarkupText(
     $field,
     $output,
     PhutilMarkupEngine $engine) {
     return $output;
   }
 
   public function shouldUseMarkupCache($field) {
     return (bool)$this->getID();
   }
 
   // votable interface
   public function getUserVoteEdgeType() {
     return PhabricatorEdgeConfig::TYPE_VOTING_USER_HAS_QUESTION;
   }
 
   public function getVotablePHID() {
     return $this->getPHID();
   }
 
   public function save() {
     if (!$this->getMailKey()) {
       $this->setMailKey(Filesystem::readRandomCharacters(20));
     }
     return parent::save();
   }
 
   public function getOriginalTitle() {
     // TODO: Make this actually save/return the original title.
     return $this->getTitle();
   }
 
   public function getFullTitle() {
     $id = $this->getID();
     $title = $this->getTitle();
     return "Q{$id}: {$title}";
   }
 
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     $policy = PhabricatorPolicies::POLICY_NOONE;
 
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         $policy = PhabricatorPolicies::POLICY_USER;
         break;
     }
 
     return $policy;
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return ($viewer->getPHID() == $this->getAuthorPHID());
   }
 
 
   public function describeAutomaticCapability($capability) {
     return pht(
       'The user who asked a question can always view and edit it.');
   }
 
 
 /* -(  PhabricatorSubscribableInterface  )----------------------------------- */
 
 
   public function isAutomaticallySubscribed($phid) {
     return ($phid == $this->getAuthorPHID());
   }
 
   public function shouldShowSubscribersProperty() {
     return true;
   }
 
   public function shouldAllowSubscription($phid) {
     return true;
   }
 
 
 /* -(  PhabricatorTokenReceiverInterface  )---------------------------------- */
 
 
   public function getUsersToNotifyOfTokenGiven() {
     return array(
       $this->getAuthorPHID(),
     );
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $this->openTransaction();
       $answers = id(new PonderAnswer())->loadAllWhere(
         'questionID = %d',
         $this->getID());
       foreach ($answers as $answer) {
         $engine->destroyObject($answer);
       }
 
       $this->delete();
     $this->saveTransaction();
   }
 
 }
diff --git a/src/applications/releeph/controller/branch/ReleephBranchHistoryController.php b/src/applications/releeph/controller/branch/ReleephBranchHistoryController.php
index 67559c8d91..46c0b47f6c 100644
--- a/src/applications/releeph/controller/branch/ReleephBranchHistoryController.php
+++ b/src/applications/releeph/controller/branch/ReleephBranchHistoryController.php
@@ -1,52 +1,47 @@
 <?php
 
 final class ReleephBranchHistoryController extends ReleephBranchController {
 
   private $branchID;
 
   public function shouldAllowPublic() {
     return true;
   }
 
   public function willProcessRequest(array $data) {
     $this->branchID = $data['branchID'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $branch = id(new ReleephBranchQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->branchID))
       ->executeOne();
     if (!$branch) {
       return new Aphront404Response();
     }
     $this->setBranch($branch);
 
-    $xactions = id(new ReleephBranchTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($branch->getPHID()))
-      ->execute();
-
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($branch->getPHID())
-      ->setTransactions($xactions)
+    $timeline = $this->buildTransactionTimeline(
+      $branch,
+      new ReleephBranchTransactionQuery());
+    $timeline
       ->setShouldTerminate(true);
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('History'));
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $timeline,
       ),
       array(
         'title' => pht('Branch History'),
       ));
   }
 
 }
diff --git a/src/applications/releeph/controller/product/ReleephProductEditController.php b/src/applications/releeph/controller/product/ReleephProductEditController.php
index bd4a108ca1..34a3a48091 100644
--- a/src/applications/releeph/controller/product/ReleephProductEditController.php
+++ b/src/applications/releeph/controller/product/ReleephProductEditController.php
@@ -1,279 +1,280 @@
 <?php
 
 final class ReleephProductEditController extends ReleephProductController {
 
   private $productID;
 
   public function willProcessRequest(array $data) {
     $this->productID = $data['projectID'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $product = id(new ReleephProductQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->productID))
       ->needArcanistProjects(true)
       ->requireCapabilities(
         array(
           PhabricatorPolicyCapability::CAN_VIEW,
           PhabricatorPolicyCapability::CAN_EDIT,
         ))
       ->executeOne();
     if (!$product) {
       return new Aphront404Response();
     }
     $this->setProduct($product);
 
     $e_name = true;
     $e_trunk_branch = true;
     $e_branch_template = false;
     $errors = array();
 
     $product_name = $request->getStr('name', $product->getName());
 
     $trunk_branch = $request->getStr('trunkBranch', $product->getTrunkBranch());
     $branch_template = $request->getStr('branchTemplate');
     if ($branch_template === null) {
       $branch_template = $product->getDetail('branchTemplate');
     }
     $pick_failure_instructions = $request->getStr('pickFailureInstructions',
       $product->getDetail('pick_failure_instructions'));
     $test_paths = $request->getStr('testPaths');
     if ($test_paths !== null) {
       $test_paths = array_filter(explode("\n", $test_paths));
     } else {
       $test_paths = $product->getDetail('testPaths', array());
     }
 
     $arc_project_id = $product->getArcanistProjectID();
 
     if ($request->isFormPost()) {
       $pusher_phids = $request->getArr('pushers');
 
       if (!$product_name) {
         $e_name = pht('Required');
         $errors[] =
           pht('Your releeph product should have a simple descriptive name.');
       }
 
       if (!$trunk_branch) {
         $e_trunk_branch = pht('Required');
         $errors[] =
           pht('You must specify which branch you will be picking from.');
       }
 
       $other_releeph_products = id(new ReleephProject())
         ->loadAllWhere('id != %d', $product->getID());
       $other_releeph_product_names = mpull($other_releeph_products,
         'getName', 'getID');
 
       if (in_array($product_name, $other_releeph_product_names)) {
         $errors[] = pht('Releeph product name %s is already taken',
           $product_name);
       }
 
       foreach ($test_paths as $test_path) {
         $result = @preg_match($test_path, '');
         $is_a_valid_regexp = $result !== false;
         if (!$is_a_valid_regexp) {
           $errors[] = pht('Please provide a valid regular expression: '.
             '%s is not valid', $test_path);
         }
       }
 
       $product
+        ->setName($product_name)
         ->setTrunkBranch($trunk_branch)
         ->setDetail('pushers', $pusher_phids)
         ->setDetail('pick_failure_instructions', $pick_failure_instructions)
         ->setDetail('branchTemplate', $branch_template)
         ->setDetail('testPaths', $test_paths);
 
       $fake_commit_handle =
         ReleephBranchTemplate::getFakeCommitHandleFor($arc_project_id);
 
       if ($branch_template) {
         list($branch_name, $template_errors) = id(new ReleephBranchTemplate())
           ->setCommitHandle($fake_commit_handle)
           ->setReleephProjectName($product_name)
           ->interpolate($branch_template);
 
         if ($template_errors) {
           $e_branch_template = pht('Whoopsies!');
           foreach ($template_errors as $template_error) {
             $errors[] = "Template error: {$template_error}";
           }
         }
       }
 
       if (!$errors) {
         $product->save();
 
         return id(new AphrontRedirectResponse())->setURI($product->getURI());
       }
     }
 
     $pusher_phids = $request->getArr(
       'pushers',
       $product->getDetail('pushers', array()));
 
     $handles = id(new PhabricatorHandleQuery())
       ->setViewer($request->getUser())
       ->withPHIDs($pusher_phids)
       ->execute();
 
     $pusher_handles = array_select_keys($handles, $pusher_phids);
 
     $form = id(new AphrontFormView())
       ->setUser($request->getUser())
       ->appendChild(
         id(new AphrontFormTextControl())
           ->setLabel(pht('Name'))
           ->setName('name')
           ->setValue($product_name)
           ->setError($e_name)
           ->setCaption(pht('A name like "Thrift" but not "Thrift releases".')))
       ->appendChild(
         id(new AphrontFormStaticControl())
           ->setLabel(pht('Repository'))
           ->setValue(
             $product->getRepository()->getName()))
       ->appendChild(
         id(new AphrontFormStaticControl())
           ->setLabel(pht('Arc Project'))
           ->setValue(
             $product->getArcanistProject()->getName()))
       ->appendChild(
         id(new AphrontFormStaticControl())
           ->setLabel(pht('Releeph Project PHID'))
           ->setValue(
             $product->getPHID()))
       ->appendChild(
         id(new AphrontFormTextControl())
           ->setLabel(pht('Trunk'))
           ->setValue($trunk_branch)
           ->setName('trunkBranch')
           ->setError($e_trunk_branch))
       ->appendChild(
         id(new AphrontFormTextAreaControl())
           ->setLabel(pht('Pick Instructions'))
           ->setValue($pick_failure_instructions)
           ->setName('pickFailureInstructions')
           ->setCaption(
             pht('Instructions for pick failures, which will be used '.
             'in emails generated by failed picks')))
       ->appendChild(
         id(new AphrontFormTextAreaControl())
           ->setLabel(pht('Tests paths'))
           ->setValue(implode("\n", $test_paths))
           ->setName('testPaths')
           ->setCaption(
             pht('List of strings that all test files contain in their path '.
             'in this project. One string per line. '.
             'Examples: \'__tests__\', \'/javatests/\'...')));
 
     $branch_template_input = id(new AphrontFormTextControl())
       ->setName('branchTemplate')
       ->setValue($branch_template)
       ->setLabel('Branch Template')
       ->setError($e_branch_template)
       ->setCaption(
         pht("Leave this blank to use your installation's default."));
 
     $branch_template_preview = id(new ReleephBranchPreviewView())
       ->setLabel(pht('Preview'))
       ->addControl('template', $branch_template_input)
       ->addStatic('arcProjectID', $arc_project_id)
       ->addStatic('isSymbolic', false)
       ->addStatic('projectName', $product->getName());
 
     $form
       ->appendChild(
         id(new AphrontFormTokenizerControl())
           ->setLabel(pht('Pushers'))
           ->setName('pushers')
           ->setDatasource(new PhabricatorPeopleDatasource())
           ->setValue($pusher_handles))
       ->appendChild($branch_template_input)
       ->appendChild($branch_template_preview)
       ->appendRemarkupInstructions($this->getBranchHelpText());
 
     $form
       ->appendChild(
         id(new AphrontFormSubmitControl())
           ->addCancelButton('/releeph/product/')
           ->setValue(pht('Save')));
 
     $box = id(new PHUIObjectBoxView())
       ->setHeaderText(pht('Edit Releeph Product'))
       ->setFormErrors($errors)
       ->appendChild($form);
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Edit Product'));
 
     return $this->buildStandardPageResponse(
       array(
         $crumbs,
         $box,
       ),
       array(
         'title' => pht('Edit Releeph Product'),
         'device' => true,
       ));
   }
 
   private function getBranchHelpText() {
     return <<<EOTEXT
 
 ==== Interpolations ====
 
 | Code  | Meaning
 | ----- | -------
 | `%P`  | The name of your product, with spaces changed to "-".
 | `%p`  | Like %P, but all lowercase.
 | `%Y`  | The four digit year associated with the branch date.
 | `%m`  | The two digit month.
 | `%d`  | The two digit day.
 | `%v`  | The handle of the commit where the branch was cut ("rXYZa4b3c2d1").
 | `%V`  | The abbreviated commit id where the branch was cut ("a4b3c2d1").
 | `%..` | Any other sequence interpreted by `strftime()`.
 | `%%`  | A literal percent sign.
 
 
 ==== Tips for Branch Templates ====
 
 Use a directory to separate your release branches from other branches:
 
   lang=none
   releases/%Y-%M-%d-%v
   => releases/2012-30-16-rHERGE32cd512a52b7
 
 Include a second hierarchy if you share your repository with other products:
 
   lang=none
   releases/%P/%p-release-%Y%m%d-%V
   => releases/Tintin/tintin-release-20121116-32cd512a52b7
 
 Keep your branch names simple, avoiding strange punctuation, most of which is
 forbidden or escaped anyway:
 
   lang=none, counterexample
   releases//..clown-releases..//`date --iso=seconds`-$(sudo halt)
 
 Include the date early in your template, in an order which sorts properly:
 
   lang=none
   releases/%Y%m%d-%v
   => releases/20121116-rHERGE32cd512a52b7 (good!)
 
   releases/%V-%m.%d.%Y
   => releases/32cd512a52b7-11.16.2012 (awful!)
 
 
 EOTEXT;
   }
 
 }
diff --git a/src/applications/releeph/controller/product/ReleephProductHistoryController.php b/src/applications/releeph/controller/product/ReleephProductHistoryController.php
index f55385a12c..15d7139854 100644
--- a/src/applications/releeph/controller/product/ReleephProductHistoryController.php
+++ b/src/applications/releeph/controller/product/ReleephProductHistoryController.php
@@ -1,52 +1,46 @@
 <?php
 
 final class ReleephProductHistoryController extends ReleephProductController {
 
   private $id;
 
   public function shouldAllowPublic() {
     return true;
   }
 
   public function willProcessRequest(array $data) {
     $this->id = $data['projectID'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $product = id(new ReleephProductQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->id))
       ->executeOne();
     if (!$product) {
       return new Aphront404Response();
     }
     $this->setProduct($product);
 
-    $xactions = id(new ReleephProductTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($product->getPHID()))
-      ->execute();
-
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($viewer)
-      ->setObjectPHID($product->getPHID())
-      ->setTransactions($xactions)
-      ->setShouldTerminate(true);
+    $timeline = $this->buildTransactionTimeline(
+      $product,
+      new ReleephProductTransactionQuery());
+    $timeline->setShouldTerminate(true);
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('History'));
 
     return $this->buildApplicationPage(
       array(
         $crumbs,
         $timeline,
       ),
       array(
         'title' => pht('Product History'),
       ));
   }
 
 }
diff --git a/src/applications/releeph/controller/request/ReleephRequestViewController.php b/src/applications/releeph/controller/request/ReleephRequestViewController.php
index 9644f6f025..04f91b5fc6 100644
--- a/src/applications/releeph/controller/request/ReleephRequestViewController.php
+++ b/src/applications/releeph/controller/request/ReleephRequestViewController.php
@@ -1,106 +1,100 @@
 <?php
 
 final class ReleephRequestViewController
   extends ReleephBranchController {
 
   private $requestID;
 
   public function willProcessRequest(array $data) {
     $this->requestID = $data['requestID'];
   }
 
   public function processRequest() {
     $request = $this->getRequest();
     $viewer = $request->getUser();
 
     $pull = id(new ReleephRequestQuery())
       ->setViewer($viewer)
       ->withIDs(array($this->requestID))
       ->executeOne();
     if (!$pull) {
       return new Aphront404Response();
     }
     $this->setBranch($pull->getBranch());
 
     // Redirect older URIs to new "Y" URIs.
     // TODO: Get rid of this eventually.
     $actual_path = $request->getRequestURI()->getPath();
     $expect_path = '/'.$pull->getMonogram();
     if ($actual_path != $expect_path) {
       return id(new AphrontRedirectResponse())->setURI($expect_path);
     }
 
     // TODO: Break this 1:1 stuff?
     $branch = $pull->getBranch();
 
     $field_list = PhabricatorCustomField::getObjectFields(
       $pull,
       PhabricatorCustomField::ROLE_VIEW);
 
     $field_list
       ->setViewer($viewer)
       ->readFieldsFromStorage($pull);
 
     // TODO: This should be more modern and general.
     $engine = id(new PhabricatorMarkupEngine())
       ->setViewer($viewer);
     foreach ($field_list->getFields() as $field) {
       if ($field->shouldMarkup()) {
         $field->setMarkupEngine($engine);
       }
     }
     $engine->process();
 
     $pull_box = id(new ReleephRequestView())
       ->setUser($viewer)
       ->setCustomFields($field_list)
       ->setPullRequest($pull);
 
-    $xactions = id(new ReleephRequestTransactionQuery())
-      ->setViewer($viewer)
-      ->withObjectPHIDs(array($pull->getPHID()))
-      ->execute();
-
-    $timeline = id(new PhabricatorApplicationTransactionView())
-      ->setUser($request->getUser())
-      ->setObjectPHID($pull->getPHID())
-      ->setTransactions($xactions);
+    $timeline = $this->buildTransactionTimeline(
+      $pull,
+      new ReleephRequestTransactionQuery());
 
     $add_comment_header = pht('Plea or Yield');
 
     $draft = PhabricatorDraft::newFromUserAndKey(
       $viewer,
       $pull->getPHID());
 
     $title = hsprintf(
       '%s %s',
       $pull->getMonogram(),
       $pull->getSummaryForDisplay());
 
     $add_comment_form = id(new PhabricatorApplicationTransactionCommentView())
       ->setUser($viewer)
       ->setObjectPHID($pull->getPHID())
       ->setDraft($draft)
       ->setHeaderText($add_comment_header)
       ->setAction($this->getApplicationURI(
         '/request/comment/'.$pull->getID().'/'))
       ->setSubmitButtonName(pht('Comment'));
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb($pull->getMonogram(), '/'.$pull->getMonogram());
 
     return $this->buildStandardPageResponse(
       array(
         $crumbs,
         $pull_box,
         $timeline,
         $add_comment_form,
       ),
       array(
         'title' => $title,
         'device' => true,
       ));
   }
 
 
 }
diff --git a/src/applications/releeph/storage/ReleephBranch.php b/src/applications/releeph/storage/ReleephBranch.php
index f6cb1834c9..bc83b5e0a2 100644
--- a/src/applications/releeph/storage/ReleephBranch.php
+++ b/src/applications/releeph/storage/ReleephBranch.php
@@ -1,174 +1,192 @@
 <?php
 
 final class ReleephBranch extends ReleephDAO
-  implements PhabricatorPolicyInterface {
+  implements
+    PhabricatorApplicationTransactionInterface,
+    PhabricatorPolicyInterface {
 
   protected $releephProjectID;
   protected $isActive;
   protected $createdByUserPHID;
 
   // The immutable name of this branch ('releases/foo-2013.01.24')
   protected $name;
   protected $basename;
 
   // The symbolic name of this branch (LATEST, PRODUCTION, RC, ...)
   // See SYMBOLIC_NAME_NOTE below
   protected $symbolicName;
 
   // Where to cut the branch
   protected $cutPointCommitPHID;
 
   protected $details = array();
 
   private $project = self::ATTACHABLE;
   private $cutPointCommit = self::ATTACHABLE;
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'details' => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'basename' => 'text64',
         'isActive' => 'bool',
         'symbolicName' => 'text64?',
         'name' => 'text128',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'releephProjectID' => array(
           'columns' => array('releephProjectID', 'symbolicName'),
           'unique' => true,
         ),
         'releephProjectID_2' => array(
           'columns' => array('releephProjectID', 'basename'),
           'unique' => true,
         ),
         'releephProjectID_name' => array(
           'columns' => array('releephProjectID', 'name'),
           'unique' => true,
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(ReleephBranchPHIDType::TYPECONST);
   }
 
   public function getDetail($key, $default = null) {
     return idx($this->getDetails(), $key, $default);
   }
 
   public function setDetail($key, $value) {
     $this->details[$key] = $value;
     return $this;
   }
 
   public function willWriteData(array &$data) {
     // If symbolicName is omitted, set it to the basename.
     //
     // This means that we can enforce symbolicName as a UNIQUE column in the
     // DB. We'll interpret symbolicName === basename as meaning "no symbolic
     // name".
     //
     // SYMBOLIC_NAME_NOTE
     if (!$data['symbolicName']) {
       $data['symbolicName'] = $data['basename'];
     }
     parent::willWriteData($data);
   }
 
   public function getSymbolicName() {
     // See SYMBOLIC_NAME_NOTE above for why this is needed
     if ($this->symbolicName == $this->getBasename()) {
       return '';
     }
     return $this->symbolicName;
   }
 
   public function setSymbolicName($name) {
     if ($name) {
       parent::setSymbolicName($name);
     } else {
       parent::setSymbolicName($this->getBasename());
     }
     return $this;
   }
 
   public function getDisplayName() {
     if ($sn = $this->getSymbolicName()) {
       return $sn;
     }
     return $this->getBasename();
   }
 
   public function getDisplayNameWithDetail() {
     $n = $this->getBasename();
     if ($sn = $this->getSymbolicName()) {
       return "{$sn} ({$n})";
     } else {
       return $n;
     }
   }
 
   public function getURI($path = null) {
     $components = array(
       '/releeph/branch',
       $this->getID(),
       $path,
     );
     return implode('/', $components);
   }
 
   public function isActive() {
     return $this->getIsActive();
   }
 
   public function attachProject(ReleephProject $project) {
     $this->project = $project;
     return $this;
   }
 
   public function getProject() {
     return $this->assertAttached($this->project);
   }
 
   public function getProduct() {
     return $this->getProject();
   }
 
   public function attachCutPointCommit(
     PhabricatorRepositoryCommit $commit = null) {
     $this->cutPointCommit = $commit;
     return $this;
   }
 
   public function getCutPointCommit() {
     return $this->assertAttached($this->cutPointCommit);
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new ReleephBranchEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new ReleephBranchTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return $this->getProduct()->getCapabilities();
   }
 
   public function getPolicy($capability) {
     return $this->getProduct()->getPolicy($capability);
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return $this->getProduct()->hasAutomaticCapability($capability, $viewer);
   }
 
   public function describeAutomaticCapability($capability) {
     return pht(
       'Release branches have the same policies as the product they are a '.
       'part of.');
   }
 
 
 }
diff --git a/src/applications/releeph/storage/ReleephProject.php b/src/applications/releeph/storage/ReleephProject.php
index cfe0026a85..b92e78afaa 100644
--- a/src/applications/releeph/storage/ReleephProject.php
+++ b/src/applications/releeph/storage/ReleephProject.php
@@ -1,146 +1,166 @@
 <?php
 
 final class ReleephProject extends ReleephDAO
-  implements PhabricatorPolicyInterface {
+  implements
+    PhabricatorApplicationTransactionInterface,
+    PhabricatorPolicyInterface {
 
   const DEFAULT_BRANCH_NAMESPACE = 'releeph-releases';
   const SYSTEM_AGENT_USERNAME_PREFIX = 'releeph-agent-';
 
   protected $name;
 
   // Specifying the place to pick from is a requirement for svn, though not
   // for git. It's always useful though for reasoning about what revs have
   // been picked and which haven't.
   protected $trunkBranch;
 
   protected $repositoryPHID;
   protected $isActive;
   protected $createdByUserPHID;
   protected $arcanistProjectID;
 
   protected $details = array();
 
   private $repository = self::ATTACHABLE;
   private $arcanistProject = self::ATTACHABLE;
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'details' => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'text128',
         'trunkBranch' => 'text255',
         'isActive' => 'bool',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'projectName' => array(
           'columns' => array('name'),
           'unique' => true,
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(ReleephProductPHIDType::TYPECONST);
   }
 
   public function getDetail($key, $default = null) {
     return idx($this->details, $key, $default);
   }
 
   public function getURI($path = null) {
     $components = array(
       '/releeph/product',
       $this->getID(),
       $path,
     );
     return implode('/', $components);
   }
 
   public function setDetail($key, $value) {
     $this->details[$key] = $value;
     return $this;
   }
 
   public function getArcanistProject() {
     return $this->assertAttached($this->arcanistProject);
   }
 
   public function attachArcanistProject(
     PhabricatorRepositoryArcanistProject $arcanist_project = null) {
     $this->arcanistProject = $arcanist_project;
     return $this;
   }
 
   public function getPushers() {
     return $this->getDetail('pushers', array());
   }
 
   public function isPusher(PhabricatorUser $user) {
     // TODO Deprecate this once `isPusher` is out of the Facebook codebase.
     return $this->isAuthoritative($user);
   }
 
   public function isAuthoritative(PhabricatorUser $user) {
     return $this->isAuthoritativePHID($user->getPHID());
   }
 
   public function isAuthoritativePHID($phid) {
     $pushers = $this->getPushers();
     if (!$pushers) {
       return true;
     } else {
       return in_array($phid, $pushers);
     }
   }
 
   public function attachRepository(PhabricatorRepository $repository) {
     $this->repository = $repository;
     return $this;
   }
 
   public function getRepository() {
     return $this->assertAttached($this->repository);
   }
 
   public function getReleephFieldSelector() {
     return new ReleephDefaultFieldSelector();
   }
 
   public function isTestFile($filename) {
     $test_paths = $this->getDetail('testPaths', array());
 
     foreach ($test_paths as $test_path) {
       if (preg_match($test_path, $filename)) {
         return true;
       }
     }
     return false;
   }
 
+
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new ReleephProductEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new ReleephProductTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
+
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     return PhabricatorPolicies::POLICY_USER;
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     return null;
   }
 
 
 }
diff --git a/src/applications/releeph/storage/ReleephRequest.php b/src/applications/releeph/storage/ReleephRequest.php
index 54976ae451..a29bdee3f7 100644
--- a/src/applications/releeph/storage/ReleephRequest.php
+++ b/src/applications/releeph/storage/ReleephRequest.php
@@ -1,346 +1,363 @@
 <?php
 
 final class ReleephRequest extends ReleephDAO
   implements
+    PhabricatorApplicationTransactionInterface,
     PhabricatorPolicyInterface,
     PhabricatorCustomFieldInterface {
 
   protected $branchID;
   protected $requestUserPHID;
   protected $details = array();
   protected $userIntents = array();
   protected $inBranch;
   protected $pickStatus;
   protected $mailKey;
 
   /**
    * The object which is being requested. Normally this is a commit, but it
    * might also be a revision. In the future, it could be a repository branch
    * or an external object (like a GitHub pull request).
    */
   protected $requestedObjectPHID;
 
   // Information about the thing being requested
   protected $requestCommitPHID;
 
   // Information about the last commit to the releeph branch
   protected $commitIdentifier;
   protected $commitPHID;
 
 
   private $customFields = self::ATTACHABLE;
   private $branch = self::ATTACHABLE;
   private $requestedObject = self::ATTACHABLE;
 
 
 /* -(  Constants and helper methods  )--------------------------------------- */
 
   const INTENT_WANT = 'want';
   const INTENT_PASS = 'pass';
 
   const PICK_PENDING  = 1; // old
   const PICK_FAILED   = 2;
   const PICK_OK       = 3;
   const PICK_MANUAL   = 4; // old
   const REVERT_OK     = 5;
   const REVERT_FAILED = 6;
 
   public function shouldBeInBranch() {
     return
       $this->getPusherIntent() == self::INTENT_WANT &&
       /**
        * We use "!= pass" instead of "== want" in case the requestor intent is
        * not present. In other words, only revert if the requestor explicitly
        * passed.
        */
       $this->getRequestorIntent() != self::INTENT_PASS;
   }
 
   /**
    * Will return INTENT_WANT if any pusher wants this request, and no pusher
    * passes on this request.
    */
   public function getPusherIntent() {
     $product = $this->getBranch()->getProduct();
 
     if (!$product->getPushers()) {
       return self::INTENT_WANT;
     }
 
     $found_pusher_want = false;
     foreach ($this->userIntents as $phid => $intent) {
       if ($product->isAuthoritativePHID($phid)) {
         if ($intent == self::INTENT_PASS) {
           return self::INTENT_PASS;
         }
 
         $found_pusher_want = true;
       }
     }
 
     if ($found_pusher_want) {
       return self::INTENT_WANT;
     } else {
       return null;
     }
   }
 
   public function getRequestorIntent() {
     return idx($this->userIntents, $this->requestUserPHID);
   }
 
   public function getStatus() {
     return $this->calculateStatus();
   }
 
   public function getMonogram() {
     return 'Y'.$this->getID();
   }
 
   public function getBranch() {
     return $this->assertAttached($this->branch);
   }
 
   public function attachBranch(ReleephBranch $branch) {
     $this->branch = $branch;
     return $this;
   }
 
   public function getRequestedObject() {
     return $this->assertAttached($this->requestedObject);
   }
 
   public function attachRequestedObject($object) {
     $this->requestedObject = $object;
     return $this;
   }
 
   private function calculateStatus() {
     if ($this->shouldBeInBranch()) {
       if ($this->getInBranch()) {
         return ReleephRequestStatus::STATUS_PICKED;
       } else {
         return ReleephRequestStatus::STATUS_NEEDS_PICK;
       }
     } else {
       if ($this->getInBranch()) {
         return ReleephRequestStatus::STATUS_NEEDS_REVERT;
       } else {
         $has_been_in_branch = $this->getCommitIdentifier();
         // Regardless of why we reverted something, always say reverted if it
         // was once in the branch.
         if ($has_been_in_branch) {
           return ReleephRequestStatus::STATUS_REVERTED;
         } else if ($this->getPusherIntent() === ReleephRequest::INTENT_PASS) {
           // Otherwise, if it has never been in the branch, explicitly say why:
           return ReleephRequestStatus::STATUS_REJECTED;
         } else if ($this->getRequestorIntent() === ReleephRequest::INTENT_WANT) {
           return ReleephRequestStatus::STATUS_REQUESTED;
         } else {
           return ReleephRequestStatus::STATUS_ABANDONED;
         }
       }
     }
   }
 
 
 /* -(  Lisk mechanics  )----------------------------------------------------- */
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'details' => self::SERIALIZATION_JSON,
         'userIntents' => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'requestCommitPHID' => 'phid?',
         'commitIdentifier' => 'text40?',
         'commitPHID' => 'phid?',
         'pickStatus' => 'uint32?',
         'inBranch' => 'bool',
         'mailKey' => 'bytes20',
         'userIntents' => 'text?',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_phid' => null,
         'phid' => array(
           'columns' => array('phid'),
           'unique' => true,
         ),
         'requestIdentifierBranch' => array(
           'columns' => array('requestCommitPHID', 'branchID'),
           'unique' => true,
         ),
         'branchID' => array(
           'columns' => array('branchID'),
         ),
         'key_requestedObject' => array(
           'columns' => array('requestedObjectPHID'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       ReleephRequestPHIDType::TYPECONST);
   }
 
   public function save() {
     if (!$this->getMailKey()) {
       $this->setMailKey(Filesystem::readRandomCharacters(20));
     }
     return parent::save();
   }
 
 
 /* -(  Helpful accessors )--------------------------------------------------- */
 
 
   public function getDetail($key, $default = null) {
     return idx($this->getDetails(), $key, $default);
   }
 
   public function setDetail($key, $value) {
     $this->details[$key] = $value;
     return $this;
   }
 
 
   /**
    * Get the commit PHIDs this request is requesting.
    *
    * NOTE: For now, this always returns one PHID.
    *
    * @return list<phid> Commit PHIDs requested by this request.
    */
   public function getCommitPHIDs() {
     return array(
       $this->requestCommitPHID,
     );
   }
 
   public function getReason() {
     // Backward compatibility: reason used to be called comments
     $reason = $this->getDetail('reason');
     if (!$reason) {
       return $this->getDetail('comments');
     }
     return $reason;
   }
 
   /**
    * Allow a null summary, and fall back to the title of the commit.
    */
   public function getSummaryForDisplay() {
     $summary = $this->getDetail('summary');
 
     if (!strlen($summary)) {
       $commit = $this->loadPhabricatorRepositoryCommit();
       if ($commit) {
         $summary = $commit->getSummary();
       }
     }
 
     if (!strlen($summary)) {
       $summary = pht('None');
     }
 
     return $summary;
   }
 
 /* -(  Loading external objects  )------------------------------------------- */
 
   public function loadPhabricatorRepositoryCommit() {
     return $this->loadOneRelative(
       new PhabricatorRepositoryCommit(),
       'phid',
       'getRequestCommitPHID');
   }
 
   public function loadPhabricatorRepositoryCommitData() {
     $commit = $this->loadPhabricatorRepositoryCommit();
     if ($commit) {
       return $commit->loadOneRelative(
         new PhabricatorRepositoryCommitData(),
         'commitID');
     }
   }
 
 
 /* -(  State change helpers  )----------------------------------------------- */
 
   public function setUserIntent(PhabricatorUser $user, $intent) {
     $this->userIntents[$user->getPHID()] = $intent;
     return $this;
   }
 
 
 /* -(  Migrating to status-less ReleephRequests  )--------------------------- */
 
   protected function didReadData() {
     if ($this->userIntents === null) {
       $this->userIntents = array();
     }
   }
 
   public function setStatus($value) {
     throw new Exception('`status` is now deprecated!');
   }
 
 /* -(  Make magic Lisk methods private  )------------------------------------ */
 
   private function setUserIntents(array $ar) {
     return parent::setUserIntents($ar);
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new ReleephRequestTransactionalEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new ReleephRequestTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     return $this->getBranch()->getPolicy($capability);
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return $this->getBranch()->hasAutomaticCapability($capability, $viewer);
   }
 
   public function describeAutomaticCapability($capability) {
     return pht(
       'Pull requests have the same policies as the branches they are '.
       'requested against.');
   }
 
 
 
 /* -(  PhabricatorCustomFieldInterface  )------------------------------------ */
 
 
   public function getCustomFieldSpecificationForRole($role) {
     return PhabricatorEnv::getEnvConfig('releeph.fields');
   }
 
   public function getCustomFieldBaseClass() {
     return 'ReleephFieldSpecification';
   }
 
   public function getCustomFields() {
     return $this->assertAttached($this->customFields);
   }
 
   public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) {
     $this->customFields = $fields;
     return $this;
   }
 
 
 }
diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php
index bba53b0d9c..ceae8cbf2e 100644
--- a/src/applications/repository/storage/PhabricatorRepository.php
+++ b/src/applications/repository/storage/PhabricatorRepository.php
@@ -1,1591 +1,1608 @@
 <?php
 
 /**
  * @task uri        Repository URI Management
  * @task autoclose  Autoclose
  */
 final class PhabricatorRepository extends PhabricatorRepositoryDAO
   implements
+    PhabricatorApplicationTransactionInterface,
     PhabricatorPolicyInterface,
     PhabricatorFlaggableInterface,
     PhabricatorMarkupInterface,
     PhabricatorDestructibleInterface,
     PhabricatorProjectInterface {
 
   /**
    * Shortest hash we'll recognize in raw "a829f32" form.
    */
   const MINIMUM_UNQUALIFIED_HASH = 7;
 
   /**
    * Shortest hash we'll recognize in qualified "rXab7ef2f8" form.
    */
   const MINIMUM_QUALIFIED_HASH = 5;
 
   const TABLE_PATH = 'repository_path';
   const TABLE_PATHCHANGE = 'repository_pathchange';
   const TABLE_FILESYSTEM = 'repository_filesystem';
   const TABLE_SUMMARY = 'repository_summary';
   const TABLE_BADCOMMIT = 'repository_badcommit';
   const TABLE_LINTMESSAGE = 'repository_lintmessage';
   const TABLE_PARENTS = 'repository_parents';
   const TABLE_COVERAGE = 'repository_coverage';
 
   const SERVE_OFF = 'off';
   const SERVE_READONLY = 'readonly';
   const SERVE_READWRITE = 'readwrite';
 
   const BECAUSE_REPOSITORY_IMPORTING = 'auto/importing';
   const BECAUSE_AUTOCLOSE_DISABLED = 'auto/disabled';
   const BECAUSE_NOT_ON_AUTOCLOSE_BRANCH = 'auto/nobranch';
   const BECAUSE_BRANCH_UNTRACKED = 'auto/notrack';
   const BECAUSE_BRANCH_NOT_AUTOCLOSE = 'auto/noclose';
 
   protected $name;
   protected $callsign;
   protected $uuid;
   protected $viewPolicy;
   protected $editPolicy;
   protected $pushPolicy;
 
   protected $versionControlSystem;
   protected $details = array();
   protected $credentialPHID;
 
   private $commitCount = self::ATTACHABLE;
   private $mostRecentCommit = self::ATTACHABLE;
   private $projectPHIDs = self::ATTACHABLE;
 
   public static function initializeNewRepository(PhabricatorUser $actor) {
     $app = id(new PhabricatorApplicationQuery())
       ->setViewer($actor)
       ->withClasses(array('PhabricatorDiffusionApplication'))
       ->executeOne();
 
     $view_policy = $app->getPolicy(DiffusionDefaultViewCapability::CAPABILITY);
     $edit_policy = $app->getPolicy(DiffusionDefaultEditCapability::CAPABILITY);
     $push_policy = $app->getPolicy(DiffusionDefaultPushCapability::CAPABILITY);
 
     return id(new PhabricatorRepository())
       ->setViewPolicy($view_policy)
       ->setEditPolicy($edit_policy)
       ->setPushPolicy($push_policy);
   }
 
   public function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'details' => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'sort255',
         'callsign' => 'sort32',
         'versionControlSystem' => 'text32',
         'uuid' => 'text64?',
         'pushPolicy' => 'policy',
         'credentialPHID' => 'phid?',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_phid' => null,
         'phid' => array(
           'columns' => array('phid'),
           'unique' => true,
         ),
         'callsign' => array(
           'columns' => array('callsign'),
           'unique' => true,
         ),
         'key_name' => array(
           'columns' => array('name(128)'),
         ),
         'key_vcs' => array(
           'columns' => array('versionControlSystem'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       PhabricatorRepositoryRepositoryPHIDType::TYPECONST);
   }
 
   public function toDictionary() {
     return array(
       'id'          => $this->getID(),
       'name'        => $this->getName(),
       'phid'        => $this->getPHID(),
       'callsign'    => $this->getCallsign(),
       'monogram'    => $this->getMonogram(),
       'vcs'         => $this->getVersionControlSystem(),
       'uri'         => PhabricatorEnv::getProductionURI($this->getURI()),
       'remoteURI'   => (string)$this->getRemoteURI(),
       'description' => $this->getDetail('description'),
       'isActive'    => $this->isTracked(),
       'isHosted'    => $this->isHosted(),
       'isImporting' => $this->isImporting(),
     );
   }
 
   public function getMonogram() {
     return 'r'.$this->getCallsign();
   }
 
   public function getDetail($key, $default = null) {
     return idx($this->details, $key, $default);
   }
 
   public function getHumanReadableDetail($key, $default = null) {
     $value = $this->getDetail($key, $default);
 
     switch ($key) {
       case 'branch-filter':
       case 'close-commits-filter':
         $value = array_keys($value);
         $value = implode(', ', $value);
         break;
     }
 
     return $value;
   }
 
   public function setDetail($key, $value) {
     $this->details[$key] = $value;
     return $this;
   }
 
   public function attachCommitCount($count) {
     $this->commitCount = $count;
     return $this;
   }
 
   public function getCommitCount() {
     return $this->assertAttached($this->commitCount);
   }
 
   public function attachMostRecentCommit(
     PhabricatorRepositoryCommit $commit = null) {
     $this->mostRecentCommit = $commit;
     return $this;
   }
 
   public function getMostRecentCommit() {
     return $this->assertAttached($this->mostRecentCommit);
   }
 
   public function getDiffusionBrowseURIForPath(
     PhabricatorUser $user,
     $path,
     $line = null,
     $branch = null) {
 
     $drequest = DiffusionRequest::newFromDictionary(
       array(
         'user' => $user,
         'repository' => $this,
         'path' => $path,
         'branch' => $branch,
       ));
 
     return $drequest->generateURI(
       array(
         'action' => 'browse',
         'line'   => $line,
       ));
   }
 
   public function getLocalPath() {
     return $this->getDetail('local-path');
   }
 
   public function getSubversionBaseURI($commit = null) {
     $subpath = $this->getDetail('svn-subpath');
     if (!strlen($subpath)) {
       $subpath = null;
     }
     return $this->getSubversionPathURI($subpath, $commit);
   }
 
   public function getSubversionPathURI($path = null, $commit = null) {
     $vcs = $this->getVersionControlSystem();
     if ($vcs != PhabricatorRepositoryType::REPOSITORY_TYPE_SVN) {
       throw new Exception('Not a subversion repository!');
     }
 
     if ($this->isHosted()) {
       $uri = 'file://'.$this->getLocalPath();
     } else {
       $uri = $this->getDetail('remote-uri');
     }
 
     $uri = rtrim($uri, '/');
 
     if (strlen($path)) {
       $path = rawurlencode($path);
       $path = str_replace('%2F', '/', $path);
       $uri = $uri.'/'.ltrim($path, '/');
     }
 
     if ($path !== null || $commit !== null) {
       $uri .= '@';
     }
 
     if ($commit !== null) {
       $uri .= $commit;
     }
 
     return $uri;
   }
 
   public function attachProjectPHIDs(array $project_phids) {
     $this->projectPHIDs = $project_phids;
     return $this;
   }
 
   public function getProjectPHIDs() {
     return $this->assertAttached($this->projectPHIDs);
   }
 
 
   /**
    * Get the name of the directory this repository should clone or checkout
    * into. For example, if the repository name is "Example Repository", a
    * reasonable name might be "example-repository". This is used to help users
    * get reasonable results when cloning repositories, since they generally do
    * not want to clone into directories called "X/" or "Example Repository/".
    *
    * @return string
    */
   public function getCloneName() {
     $name = $this->getDetail('clone-name');
 
     // Make some reasonable effort to produce reasonable default directory
     // names from repository names.
     if (!strlen($name)) {
       $name = $this->getName();
       $name = phutil_utf8_strtolower($name);
       $name = preg_replace('@[/ -:]+@', '-', $name);
       $name = trim($name, '-');
       if (!strlen($name)) {
         $name = $this->getCallsign();
       }
     }
 
     return $name;
   }
 
 
 /* -(  Remote Command Execution  )------------------------------------------- */
 
 
   public function execRemoteCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     return $this->newRemoteCommandFuture($args)->resolve();
   }
 
   public function execxRemoteCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     return $this->newRemoteCommandFuture($args)->resolvex();
   }
 
   public function getRemoteCommandFuture($pattern /* , $arg, ... */) {
     $args = func_get_args();
     return $this->newRemoteCommandFuture($args);
   }
 
   public function passthruRemoteCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     return $this->newRemoteCommandPassthru($args)->execute();
   }
 
   private function newRemoteCommandFuture(array $argv) {
     $argv = $this->formatRemoteCommand($argv);
     $future = newv('ExecFuture', $argv);
     $future->setEnv($this->getRemoteCommandEnvironment());
     return $future;
   }
 
   private function newRemoteCommandPassthru(array $argv) {
     $argv = $this->formatRemoteCommand($argv);
     $passthru = newv('PhutilExecPassthru', $argv);
     $passthru->setEnv($this->getRemoteCommandEnvironment());
     return $passthru;
   }
 
 
 /* -(  Local Command Execution  )-------------------------------------------- */
 
 
   public function execLocalCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     return $this->newLocalCommandFuture($args)->resolve();
   }
 
   public function execxLocalCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     return $this->newLocalCommandFuture($args)->resolvex();
   }
 
   public function getLocalCommandFuture($pattern /* , $arg, ... */) {
     $args = func_get_args();
     return $this->newLocalCommandFuture($args);
   }
 
   public function passthruLocalCommand($pattern /* , $arg, ... */) {
     $args = func_get_args();
     return $this->newLocalCommandPassthru($args)->execute();
   }
 
   private function newLocalCommandFuture(array $argv) {
     $this->assertLocalExists();
 
     $argv = $this->formatLocalCommand($argv);
     $future = newv('ExecFuture', $argv);
     $future->setEnv($this->getLocalCommandEnvironment());
 
     if ($this->usesLocalWorkingCopy()) {
       $future->setCWD($this->getLocalPath());
     }
 
     return $future;
   }
 
   private function newLocalCommandPassthru(array $argv) {
     $this->assertLocalExists();
 
     $argv = $this->formatLocalCommand($argv);
     $future = newv('PhutilExecPassthru', $argv);
     $future->setEnv($this->getLocalCommandEnvironment());
 
     if ($this->usesLocalWorkingCopy()) {
       $future->setCWD($this->getLocalPath());
     }
 
     return $future;
   }
 
 
 /* -(  Command Infrastructure  )--------------------------------------------- */
 
 
   private function getSSHWrapper() {
     $root = dirname(phutil_get_library_root('phabricator'));
     return $root.'/bin/ssh-connect';
   }
 
   private function getCommonCommandEnvironment() {
     $env = array(
       // NOTE: Force the language to "en_US.UTF-8", which overrides locale
       // settings. This makes stuff print in English instead of, e.g., French,
       // so we can parse the output of some commands, error messages, etc.
       'LANG' => 'en_US.UTF-8',
 
       // Propagate PHABRICATOR_ENV explicitly. For discussion, see T4155.
       'PHABRICATOR_ENV' => PhabricatorEnv::getSelectedEnvironmentName(),
     );
 
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         // NOTE: See T2965. Some time after Git 1.7.5.4, Git started fataling if
         // it can not read $HOME. For many users, $HOME points at /root (this
         // seems to be a default result of Apache setup). Instead, explicitly
         // point $HOME at a readable, empty directory so that Git looks for the
         // config file it's after, fails to locate it, and moves on. This is
         // really silly, but seems like the least damaging approach to
         // mitigating the issue.
 
         $root = dirname(phutil_get_library_root('phabricator'));
         $env['HOME'] = $root.'/support/empty/';
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         // NOTE: This overrides certain configuration, extensions, and settings
         // which make Mercurial commands do random unusual things.
         $env['HGPLAIN'] = 1;
         break;
       default:
         throw new Exception('Unrecognized version control system.');
     }
 
     return $env;
   }
 
   private function getLocalCommandEnvironment() {
     return $this->getCommonCommandEnvironment();
   }
 
   private function getRemoteCommandEnvironment() {
     $env = $this->getCommonCommandEnvironment();
 
     if ($this->shouldUseSSH()) {
       // NOTE: This is read by `bin/ssh-connect`, and tells it which credentials
       // to use.
       $env['PHABRICATOR_CREDENTIAL'] = $this->getCredentialPHID();
       switch ($this->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
           // Force SVN to use `bin/ssh-connect`.
           $env['SVN_SSH'] = $this->getSSHWrapper();
           break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
           // Force Git to use `bin/ssh-connect`.
           $env['GIT_SSH'] = $this->getSSHWrapper();
           break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
           // We force Mercurial through `bin/ssh-connect` too, but it uses a
           // command-line flag instead of an environmental variable.
           break;
         default:
           throw new Exception('Unrecognized version control system.');
       }
     }
 
     return $env;
   }
 
   private function formatRemoteCommand(array $args) {
     $pattern = $args[0];
     $args = array_slice($args, 1);
 
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         if ($this->shouldUseHTTP() || $this->shouldUseSVNProtocol()) {
           $flags = array();
           $flag_args = array();
           $flags[] = '--non-interactive';
           $flags[] = '--no-auth-cache';
           if ($this->shouldUseHTTP()) {
             $flags[] = '--trust-server-cert';
           }
 
           $credential_phid = $this->getCredentialPHID();
           if ($credential_phid) {
             $key = PassphrasePasswordKey::loadFromPHID(
               $credential_phid,
               PhabricatorUser::getOmnipotentUser());
             $flags[] = '--username %P';
             $flags[] = '--password %P';
             $flag_args[] = $key->getUsernameEnvelope();
             $flag_args[] = $key->getPasswordEnvelope();
           }
 
           $flags = implode(' ', $flags);
           $pattern = "svn {$flags} {$pattern}";
           $args = array_mergev(array($flag_args, $args));
         } else {
           $pattern = "svn --non-interactive {$pattern}";
         }
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         $pattern = "git {$pattern}";
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         if ($this->shouldUseSSH()) {
           $pattern = "hg --config ui.ssh=%s {$pattern}";
           array_unshift(
             $args,
             $this->getSSHWrapper());
         } else {
           $pattern = "hg {$pattern}";
         }
         break;
       default:
         throw new Exception('Unrecognized version control system.');
     }
 
     array_unshift($args, $pattern);
 
     return $args;
   }
 
   private function formatLocalCommand(array $args) {
     $pattern = $args[0];
     $args = array_slice($args, 1);
 
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         $pattern = "svn --non-interactive {$pattern}";
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         $pattern = "git {$pattern}";
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         $pattern = "hg {$pattern}";
         break;
       default:
         throw new Exception('Unrecognized version control system.');
     }
 
     array_unshift($args, $pattern);
 
     return $args;
   }
 
   /**
    * Sanitize output of an `hg` command invoked with the `--debug` flag to make
    * it usable.
    *
    * @param string Output from `hg --debug ...`
    * @return string Usable output.
    */
   public static function filterMercurialDebugOutput($stdout) {
     // When hg commands are run with `--debug` and some config file isn't
     // trusted, Mercurial prints out a warning to stdout, twice, after Feb 2011.
     //
     // http://selenic.com/pipermail/mercurial-devel/2011-February/028541.html
 
     $lines = preg_split('/(?<=\n)/', $stdout);
     $regex = '/ignoring untrusted configuration option .*\n$/';
 
     foreach ($lines as $key => $line) {
       $lines[$key] = preg_replace($regex, '', $line);
     }
 
     return implode('', $lines);
   }
 
   public function getURI() {
     return '/diffusion/'.$this->getCallsign().'/';
   }
 
   public function getNormalizedPath() {
     $uri = (string)$this->getCloneURIObject();
 
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         $normalized_uri = new PhabricatorRepositoryURINormalizer(
           PhabricatorRepositoryURINormalizer::TYPE_GIT,
           $uri);
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         $normalized_uri = new PhabricatorRepositoryURINormalizer(
           PhabricatorRepositoryURINormalizer::TYPE_SVN,
           $uri);
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         $normalized_uri = new PhabricatorRepositoryURINormalizer(
           PhabricatorRepositoryURINormalizer::TYPE_MERCURIAL,
           $uri);
         break;
       default:
         throw new Exception('Unrecognized version control system.');
     }
 
     return $normalized_uri->getNormalizedPath();
   }
 
   public function isTracked() {
     return $this->getDetail('tracking-enabled', false);
   }
 
   public function getDefaultBranch() {
     $default = $this->getDetail('default-branch');
     if (strlen($default)) {
       return $default;
     }
 
     $default_branches = array(
       PhabricatorRepositoryType::REPOSITORY_TYPE_GIT        => 'master',
       PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL  => 'default',
     );
 
     return idx($default_branches, $this->getVersionControlSystem());
   }
 
   public function getDefaultArcanistBranch() {
     return coalesce($this->getDefaultBranch(), 'svn');
   }
 
   private function isBranchInFilter($branch, $filter_key) {
     $vcs = $this->getVersionControlSystem();
 
     $is_git = ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT);
 
     $use_filter = ($is_git);
     if (!$use_filter) {
       // If this VCS doesn't use filters, pass everything through.
       return true;
     }
 
 
     $filter = $this->getDetail($filter_key, array());
 
     // If there's no filter set, let everything through.
     if (!$filter) {
       return true;
     }
 
     // If this branch isn't literally named `regexp(...)`, and it's in the
     // filter list, let it through.
     if (isset($filter[$branch])) {
       if (self::extractBranchRegexp($branch) === null) {
         return true;
       }
     }
 
     // If the branch matches a regexp, let it through.
     foreach ($filter as $pattern => $ignored) {
       $regexp = self::extractBranchRegexp($pattern);
       if ($regexp !== null) {
         if (preg_match($regexp, $branch)) {
           return true;
         }
       }
     }
 
     // Nothing matched, so filter this branch out.
     return false;
   }
 
   public static function extractBranchRegexp($pattern) {
     $matches = null;
     if (preg_match('/^regexp\\((.*)\\)\z/', $pattern, $matches)) {
       return $matches[1];
     }
     return null;
   }
 
   public function shouldTrackBranch($branch) {
     return $this->isBranchInFilter($branch, 'branch-filter');
   }
 
   public function formatCommitName($commit_identifier) {
     $vcs = $this->getVersionControlSystem();
 
     $type_git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
     $type_hg = PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL;
 
     $is_git = ($vcs == $type_git);
     $is_hg = ($vcs == $type_hg);
     if ($is_git || $is_hg) {
       $short_identifier = substr($commit_identifier, 0, 12);
     } else {
       $short_identifier = $commit_identifier;
     }
 
     return 'r'.$this->getCallsign().$short_identifier;
   }
 
   public function isImporting() {
     return (bool)$this->getDetail('importing', false);
   }
 
 
 /* -(  Autoclose  )---------------------------------------------------------- */
 
 
   /**
    * Determine if autoclose is active for a branch.
    *
    * For more details about why, use @{method:shouldSkipAutocloseBranch}.
    *
    * @param string Branch name to check.
    * @return bool True if autoclose is active for the branch.
    * @task autoclose
    */
   public function shouldAutocloseBranch($branch) {
     return ($this->shouldSkipAutocloseBranch($branch) === null);
   }
 
   /**
    * Determine if autoclose is active for a commit.
    *
    * For more details about why, use @{method:shouldSkipAutocloseCommit}.
    *
    * @param PhabricatorRepositoryCommit Commit to check.
    * @return bool True if autoclose is active for the commit.
    * @task autoclose
    */
   public function shouldAutocloseCommit(PhabricatorRepositoryCommit $commit) {
     return ($this->shouldSkipAutocloseCommit($commit) === null);
   }
 
 
   /**
    * Determine why autoclose should be skipped for a branch.
    *
    * This method gives a detailed reason why autoclose will be skipped. To
    * perform a simple test, use @{method:shouldAutocloseBranch}.
    *
    * @param string Branch name to check.
    * @return const|null Constant identifying reason to skip this branch, or null
    *   if autoclose is active.
    * @task autoclose
    */
   public function shouldSkipAutocloseBranch($branch) {
     $all_reason = $this->shouldSkipAllAutoclose();
     if ($all_reason) {
       return $all_reason;
     }
 
     if (!$this->shouldTrackBranch($branch)) {
       return self::BECAUSE_BRANCH_UNTRACKED;
     }
 
     if (!$this->isBranchInFilter($branch, 'close-commits-filter')) {
       return self::BECAUSE_BRANCH_NOT_AUTOCLOSE;
     }
 
     return null;
   }
 
 
   /**
    * Determine why autoclose should be skipped for a commit.
    *
    * This method gives a detailed reason why autoclose will be skipped. To
    * perform a simple test, use @{method:shouldAutocloseCommit}.
    *
    * @param PhabricatorRepositoryCommit Commit to check.
    * @return const|null Constant identifying reason to skip this commit, or null
    *   if autoclose is active.
    * @task autoclose
    */
   public function shouldSkipAutocloseCommit(
     PhabricatorRepositoryCommit $commit) {
 
     $all_reason = $this->shouldSkipAllAutoclose();
     if ($all_reason) {
       return $all_reason;
     }
 
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         return null;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         break;
       default:
         throw new Exception('Unrecognized version control system.');
     }
 
     $closeable_flag = PhabricatorRepositoryCommit::IMPORTED_CLOSEABLE;
     if (!$commit->isPartiallyImported($closeable_flag)) {
       return self::BECAUSE_NOT_ON_AUTOCLOSE_BRANCH;
     }
 
     return null;
   }
 
 
   /**
    * Determine why all autoclose operations should be skipped for this
    * repository.
    *
    * @return const|null Constant identifying reason to skip all autoclose
    *   operations, or null if autoclose operations are not blocked at the
    *   repository level.
    * @task autoclose
    */
   private function shouldSkipAllAutoclose() {
     if ($this->isImporting()) {
       return self::BECAUSE_REPOSITORY_IMPORTING;
     }
 
     if ($this->getDetail('disable-autoclose', false)) {
       return self::BECAUSE_AUTOCLOSE_DISABLED;
     }
 
     return null;
   }
 
 
 /* -(  Repository URI Management  )------------------------------------------ */
 
 
   /**
    * Get the remote URI for this repository.
    *
    * @return string
    * @task uri
    */
   public function getRemoteURI() {
     return (string)$this->getRemoteURIObject();
   }
 
 
   /**
    * Get the remote URI for this repository, including credentials if they're
    * used by this repository.
    *
    * @return PhutilOpaqueEnvelope URI, possibly including credentials.
    * @task uri
    */
   public function getRemoteURIEnvelope() {
     $uri = $this->getRemoteURIObject();
 
     $remote_protocol = $this->getRemoteProtocol();
     if ($remote_protocol == 'http' || $remote_protocol == 'https') {
       // For SVN, we use `--username` and `--password` flags separately, so
       // don't add any credentials here.
       if (!$this->isSVN()) {
         $credential_phid = $this->getCredentialPHID();
         if ($credential_phid) {
           $key = PassphrasePasswordKey::loadFromPHID(
             $credential_phid,
             PhabricatorUser::getOmnipotentUser());
 
           $uri->setUser($key->getUsernameEnvelope()->openEnvelope());
           $uri->setPass($key->getPasswordEnvelope()->openEnvelope());
         }
       }
     }
 
     return new PhutilOpaqueEnvelope((string)$uri);
   }
 
 
   /**
    * Get the clone (or checkout) URI for this repository, without authentication
    * information.
    *
    * @return string Repository URI.
    * @task uri
    */
   public function getPublicCloneURI() {
     $uri = $this->getCloneURIObject();
 
     // Make sure we don't leak anything if this repo is using HTTP Basic Auth
     // with the credentials in the URI or something zany like that.
 
     // If repository is not accessed over SSH we remove both username and
     // password.
     if (!$this->isHosted()) {
       if (!$this->shouldUseSSH()) {
         $uri->setUser(null);
 
         // This might be a Git URI or a normal URI. If it's Git, there's no
         // password support.
         if ($uri instanceof PhutilURI) {
           $uri->setPass(null);
         }
       }
     }
 
     return (string)$uri;
   }
 
 
   /**
    * Get the protocol for the repository's remote.
    *
    * @return string Protocol, like "ssh" or "git".
    * @task uri
    */
   public function getRemoteProtocol() {
     $uri = $this->getRemoteURIObject();
 
     if ($uri instanceof PhutilGitURI) {
       return 'ssh';
     } else {
       return $uri->getProtocol();
     }
   }
 
 
   /**
    * Get a parsed object representation of the repository's remote URI. This
    * may be a normal URI (returned as a @{class@libphutil:PhutilURI}) or a git
    * URI (returned as a @{class@libphutil:PhutilGitURI}).
    *
    * @return wild A @{class@libphutil:PhutilURI} or
    *              @{class@libphutil:PhutilGitURI}.
    * @task uri
    */
   public function getRemoteURIObject() {
     $raw_uri = $this->getDetail('remote-uri');
     if (!$raw_uri) {
       return new PhutilURI('');
     }
 
     if (!strncmp($raw_uri, '/', 1)) {
       return new PhutilURI('file://'.$raw_uri);
     }
 
     $uri = new PhutilURI($raw_uri);
     if ($uri->getProtocol()) {
       return $uri;
     }
 
     $uri = new PhutilGitURI($raw_uri);
     if ($uri->getDomain()) {
       return $uri;
     }
 
     throw new Exception("Remote URI '{$raw_uri}' could not be parsed!");
   }
 
 
   /**
    * Get the "best" clone/checkout URI for this repository, on any protocol.
    */
   public function getCloneURIObject() {
     if (!$this->isHosted()) {
       if ($this->isSVN()) {
         // Make sure we pick up the "Import Only" path for Subversion, so
         // the user clones the repository starting at the correct path, not
         // from the root.
         $base_uri = $this->getSubversionBaseURI();
         $base_uri = new PhutilURI($base_uri);
         $path = $base_uri->getPath();
         if (!$path) {
           $path = '/';
         }
 
         // If the trailing "@" is not required to escape the URI, strip it for
         // readability.
         if (!preg_match('/@.*@/', $path)) {
           $path = rtrim($path, '@');
         }
 
         $base_uri->setPath($path);
         return $base_uri;
       } else {
         return $this->getRemoteURIObject();
       }
     }
 
     // Choose the best URI: pick a read/write URI over a URI which is not
     // read/write, and SSH over HTTP.
 
     $serve_ssh = $this->getServeOverSSH();
     $serve_http = $this->getServeOverHTTP();
 
     if ($serve_ssh === self::SERVE_READWRITE) {
       return $this->getSSHCloneURIObject();
     } else if ($serve_http === self::SERVE_READWRITE) {
       return $this->getHTTPCloneURIObject();
     } else if ($serve_ssh !== self::SERVE_OFF) {
       return $this->getSSHCloneURIObject();
     } else if ($serve_http !== self::SERVE_OFF) {
       return $this->getHTTPCloneURIObject();
     } else {
       return null;
     }
   }
 
 
   /**
    * Get the repository's SSH clone/checkout URI, if one exists.
    */
   public function getSSHCloneURIObject() {
     if (!$this->isHosted()) {
       if ($this->shouldUseSSH()) {
         return $this->getRemoteURIObject();
       } else {
         return null;
       }
     }
 
     $serve_ssh = $this->getServeOverSSH();
     if ($serve_ssh === self::SERVE_OFF) {
       return null;
     }
 
     $uri = new PhutilURI(PhabricatorEnv::getProductionURI($this->getURI()));
 
     if ($this->isSVN()) {
       $uri->setProtocol('svn+ssh');
     } else {
       $uri->setProtocol('ssh');
     }
 
     if ($this->isGit()) {
       $uri->setPath($uri->getPath().$this->getCloneName().'.git');
     } else if ($this->isHg()) {
       $uri->setPath($uri->getPath().$this->getCloneName().'/');
     }
 
     $ssh_user = PhabricatorEnv::getEnvConfig('diffusion.ssh-user');
     if ($ssh_user) {
       $uri->setUser($ssh_user);
     }
 
     $uri->setPort(PhabricatorEnv::getEnvConfig('diffusion.ssh-port'));
 
     return $uri;
   }
 
 
   /**
    * Get the repository's HTTP clone/checkout URI, if one exists.
    */
   public function getHTTPCloneURIObject() {
     if (!$this->isHosted()) {
       if ($this->shouldUseHTTP()) {
         return $this->getRemoteURIObject();
       } else {
         return null;
       }
     }
 
     $serve_http = $this->getServeOverHTTP();
     if ($serve_http === self::SERVE_OFF) {
       return null;
     }
 
     $uri = PhabricatorEnv::getProductionURI($this->getURI());
     $uri = new PhutilURI($uri);
 
     if ($this->isGit()) {
       $uri->setPath($uri->getPath().$this->getCloneName().'.git');
     } else if ($this->isHg()) {
       $uri->setPath($uri->getPath().$this->getCloneName().'/');
     }
 
     return $uri;
   }
 
 
   /**
    * Determine if we should connect to the remote using SSH flags and
    * credentials.
    *
    * @return bool True to use the SSH protocol.
    * @task uri
    */
   private function shouldUseSSH() {
     if ($this->isHosted()) {
       return false;
     }
 
     $protocol = $this->getRemoteProtocol();
     if ($this->isSSHProtocol($protocol)) {
       return true;
     }
 
     return false;
   }
 
 
   /**
    * Determine if we should connect to the remote using HTTP flags and
    * credentials.
    *
    * @return bool True to use the HTTP protocol.
    * @task uri
    */
   private function shouldUseHTTP() {
     if ($this->isHosted()) {
       return false;
     }
 
     $protocol = $this->getRemoteProtocol();
     return ($protocol == 'http' || $protocol == 'https');
   }
 
 
   /**
    * Determine if we should connect to the remote using SVN flags and
    * credentials.
    *
    * @return bool True to use the SVN protocol.
    * @task uri
    */
   private function shouldUseSVNProtocol() {
     if ($this->isHosted()) {
       return false;
     }
 
     $protocol = $this->getRemoteProtocol();
     return ($protocol == 'svn');
   }
 
 
   /**
    * Determine if a protocol is SSH or SSH-like.
    *
    * @param string A protocol string, like "http" or "ssh".
    * @return bool True if the protocol is SSH-like.
    * @task uri
    */
   private function isSSHProtocol($protocol) {
     return ($protocol == 'ssh' || $protocol == 'svn+ssh');
   }
 
   public function delete() {
     $this->openTransaction();
 
       $paths = id(new PhabricatorOwnersPath())
         ->loadAllWhere('repositoryPHID = %s', $this->getPHID());
       foreach ($paths as $path) {
         $path->delete();
       }
 
       $projects = id(new PhabricatorRepositoryArcanistProject())
         ->loadAllWhere('repositoryID = %d', $this->getID());
       foreach ($projects as $project) {
         // note each project deletes its PhabricatorRepositorySymbols
         $project->delete();
       }
 
       $commits = id(new PhabricatorRepositoryCommit())
         ->loadAllWhere('repositoryID = %d', $this->getID());
       foreach ($commits as $commit) {
         // note PhabricatorRepositoryAuditRequests and
         // PhabricatorRepositoryCommitData are deleted here too.
         $commit->delete();
       }
 
       $mirrors = id(new PhabricatorRepositoryMirror())
         ->loadAllWhere('repositoryPHID = %s', $this->getPHID());
       foreach ($mirrors as $mirror) {
         $mirror->delete();
       }
 
       $ref_cursors = id(new PhabricatorRepositoryRefCursor())
         ->loadAllWhere('repositoryPHID = %s', $this->getPHID());
       foreach ($ref_cursors as $cursor) {
         $cursor->delete();
       }
 
       $conn_w = $this->establishConnection('w');
 
       queryfx(
         $conn_w,
         'DELETE FROM %T WHERE repositoryID = %d',
         self::TABLE_FILESYSTEM,
         $this->getID());
 
       queryfx(
         $conn_w,
         'DELETE FROM %T WHERE repositoryID = %d',
         self::TABLE_PATHCHANGE,
         $this->getID());
 
       queryfx(
         $conn_w,
         'DELETE FROM %T WHERE repositoryID = %d',
         self::TABLE_SUMMARY,
         $this->getID());
 
       $result = parent::delete();
 
     $this->saveTransaction();
     return $result;
   }
 
   public function isGit() {
     $vcs = $this->getVersionControlSystem();
     return ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT);
   }
 
   public function isSVN() {
     $vcs = $this->getVersionControlSystem();
     return ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_SVN);
   }
 
   public function isHg() {
     $vcs = $this->getVersionControlSystem();
     return ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL);
   }
 
   public function isHosted() {
     return (bool)$this->getDetail('hosting-enabled', false);
   }
 
   public function setHosted($enabled) {
     return $this->setDetail('hosting-enabled', $enabled);
   }
 
   public function getServeOverHTTP() {
     if ($this->isSVN()) {
       return self::SERVE_OFF;
     }
     $serve = $this->getDetail('serve-over-http', self::SERVE_OFF);
     return $this->normalizeServeConfigSetting($serve);
   }
 
   public function setServeOverHTTP($mode) {
     return $this->setDetail('serve-over-http', $mode);
   }
 
   public function getServeOverSSH() {
     $serve = $this->getDetail('serve-over-ssh', self::SERVE_OFF);
     return $this->normalizeServeConfigSetting($serve);
   }
 
   public function setServeOverSSH($mode) {
     return $this->setDetail('serve-over-ssh', $mode);
   }
 
   public static function getProtocolAvailabilityName($constant) {
     switch ($constant) {
       case self::SERVE_OFF:
         return pht('Off');
       case self::SERVE_READONLY:
         return pht('Read Only');
       case self::SERVE_READWRITE:
         return pht('Read/Write');
       default:
         return pht('Unknown');
     }
   }
 
   private function normalizeServeConfigSetting($value) {
     switch ($value) {
       case self::SERVE_OFF:
       case self::SERVE_READONLY:
         return $value;
       case self::SERVE_READWRITE:
         if ($this->isHosted()) {
           return self::SERVE_READWRITE;
         } else {
           return self::SERVE_READONLY;
         }
       default:
         return self::SERVE_OFF;
     }
   }
 
 
   /**
    * Raise more useful errors when there are basic filesystem problems.
    */
   private function assertLocalExists() {
     if (!$this->usesLocalWorkingCopy()) {
       return;
     }
 
     $local = $this->getLocalPath();
     Filesystem::assertExists($local);
     Filesystem::assertIsDirectory($local);
     Filesystem::assertReadable($local);
   }
 
   /**
    * Determine if the working copy is bare or not. In Git, this corresponds
    * to `--bare`. In Mercurial, `--noupdate`.
    */
   public function isWorkingCopyBare() {
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         return false;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         $local = $this->getLocalPath();
         if (Filesystem::pathExists($local.'/.git')) {
           return false;
         } else {
           return true;
         }
     }
   }
 
   public function usesLocalWorkingCopy() {
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         return $this->isHosted();
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         return true;
     }
   }
 
   public function getHookDirectories() {
     $directories = array();
     if (!$this->isHosted()) {
       return $directories;
     }
 
     $root = $this->getLocalPath();
 
     switch ($this->getVersionControlSystem()) {
       case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
         if ($this->isWorkingCopyBare()) {
           $directories[] = $root.'/hooks/pre-receive-phabricator.d/';
         } else {
           $directories[] = $root.'/.git/hooks/pre-receive-phabricator.d/';
         }
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
         $directories[] = $root.'/hooks/pre-commit-phabricator.d/';
         break;
       case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
         // NOTE: We don't support custom Mercurial hooks for now because they're
         // messy and we can't easily just drop a `hooks.d/` directory next to
         // the hooks.
         break;
     }
 
     return $directories;
   }
 
   public function canDestroyWorkingCopy() {
     if ($this->isHosted()) {
       // Never destroy hosted working copies.
       return false;
     }
 
     $default_path = PhabricatorEnv::getEnvConfig(
       'repository.default-local-path');
     return Filesystem::isDescendant($this->getLocalPath(), $default_path);
   }
 
   public function canUsePathTree() {
     return !$this->isSVN();
   }
 
   public function canMirror() {
     if ($this->isGit() || $this->isHg()) {
       return true;
     }
 
     return false;
   }
 
   public function canAllowDangerousChanges() {
     if (!$this->isHosted()) {
       return false;
     }
 
     if ($this->isGit() || $this->isHg()) {
       return true;
     }
 
     return false;
   }
 
   public function shouldAllowDangerousChanges() {
     return (bool)$this->getDetail('allow-dangerous-changes');
   }
 
   public function writeStatusMessage(
     $status_type,
     $status_code,
     array $parameters = array()) {
 
     $table = new PhabricatorRepositoryStatusMessage();
     $conn_w = $table->establishConnection('w');
     $table_name = $table->getTableName();
 
     if ($status_code === null) {
       queryfx(
         $conn_w,
         'DELETE FROM %T WHERE repositoryID = %d AND statusType = %s',
         $table_name,
         $this->getID(),
         $status_type);
     } else {
       queryfx(
         $conn_w,
         'INSERT INTO %T
           (repositoryID, statusType, statusCode, parameters, epoch)
           VALUES (%d, %s, %s, %s, %d)
           ON DUPLICATE KEY UPDATE
             statusCode = VALUES(statusCode),
             parameters = VALUES(parameters),
             epoch = VALUES(epoch)',
         $table_name,
         $this->getID(),
         $status_type,
         $status_code,
         json_encode($parameters),
         time());
     }
 
     return $this;
   }
 
   public static function getRemoteURIProtocol($raw_uri) {
     $uri = new PhutilURI($raw_uri);
     if ($uri->getProtocol()) {
       return strtolower($uri->getProtocol());
     }
 
     $git_uri = new PhutilGitURI($raw_uri);
     if (strlen($git_uri->getDomain()) && strlen($git_uri->getPath())) {
       return 'ssh';
     }
 
     return null;
   }
 
   public static function assertValidRemoteURI($uri) {
     if (trim($uri) != $uri) {
       throw new Exception(
         pht(
           'The remote URI has leading or trailing whitespace.'));
     }
 
     $protocol = self::getRemoteURIProtocol($uri);
 
     // Catch confusion between Git/SCP-style URIs and normal URIs. See T3619
     // for discussion. This is usually a user adding "ssh://" to an implicit
     // SSH Git URI.
     if ($protocol == 'ssh') {
       if (preg_match('(^[^:@]+://[^/:]+:[^\d])', $uri)) {
         throw new Exception(
           pht(
             "The remote URI is not formatted correctly. Remote URIs ".
             "with an explicit protocol should be in the form ".
             "'proto://domain/path', not 'proto://domain:/path'. ".
             "The ':/path' syntax is only valid in SCP-style URIs."));
       }
     }
 
     switch ($protocol) {
       case 'ssh':
       case 'http':
       case 'https':
       case 'git':
       case 'svn':
       case 'svn+ssh':
         break;
       default:
         // NOTE: We're explicitly rejecting 'file://' because it can be
         // used to clone from the working copy of another repository on disk
         // that you don't normally have permission to access.
 
         throw new Exception(
           pht(
             "The URI protocol is unrecognized. It should begin ".
             "'ssh://', 'http://', 'https://', 'git://', 'svn://', ".
             "'svn+ssh://', or be in the form 'git@domain.com:path'."));
     }
 
     return true;
   }
 
 
   /**
    * Load the pull frequency for this repository, based on the time since the
    * last activity.
    *
    * We pull rarely used repositories less frequently. This finds the most
    * recent commit which is older than the current time (which prevents us from
    * spinning on repositories with a silly commit post-dated to some time in
    * 2037). We adjust the pull frequency based on when the most recent commit
    * occurred.
    *
    * @param   int   The minimum update interval to use, in seconds.
    * @return  int   Repository update interval, in seconds.
    */
   public function loadUpdateInterval($minimum = 15) {
     // If a repository is still importing, always pull it as frequently as
     // possible. This prevents us from hanging for a long time at 99.9% when
     // importing an inactive repository.
     if ($this->isImporting()) {
       return $minimum;
     }
 
     $window_start = (PhabricatorTime::getNow() + $minimum);
 
     $table = id(new PhabricatorRepositoryCommit());
     $last_commit = queryfx_one(
       $table->establishConnection('r'),
       'SELECT epoch FROM %T
         WHERE repositoryID = %d AND epoch <= %d
         ORDER BY epoch DESC LIMIT 1',
       $table->getTableName(),
       $this->getID(),
       $window_start);
     if ($last_commit) {
       $time_since_commit = ($window_start - $last_commit['epoch']);
 
       $last_few_days = phutil_units('3 days in seconds');
 
       if ($time_since_commit <= $last_few_days) {
         // For repositories with activity in the recent past, we wait one
         // extra second for every 10 minutes since the last commit. This
         // shorter backoff is intended to handle weekends and other short
         // breaks from development.
         $smart_wait = ($time_since_commit / 600);
       } else {
         // For repositories without recent activity, we wait one extra second
         // for every 4 minutes since the last commit. This longer backoff
         // handles rarely used repositories, up to the maximum.
         $smart_wait = ($time_since_commit / 240);
       }
 
       // We'll never wait more than 6 hours to pull a repository.
       $longest_wait = phutil_units('6 hours in seconds');
       $smart_wait = min($smart_wait, $longest_wait);
 
       $smart_wait = max($minimum, $smart_wait);
     } else {
       $smart_wait = $minimum;
     }
 
     return $smart_wait;
   }
 
 
+/* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
+
+
+  public function getApplicationTransactionEditor() {
+    return new PhabricatorRepositoryEditor();
+  }
+
+  public function getApplicationTransactionObject() {
+    return $this;
+  }
+
+  public function getApplicationTransactionTemplate() {
+    return new PhabricatorRepositoryTransaction();
+  }
+
+
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
       DiffusionPushCapability::CAPABILITY,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return $this->getViewPolicy();
       case PhabricatorPolicyCapability::CAN_EDIT:
         return $this->getEditPolicy();
       case DiffusionPushCapability::CAPABILITY:
         return $this->getPushPolicy();
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $user) {
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     return null;
   }
 
 
 
 /* -(  PhabricatorMarkupInterface  )----------------------------------------- */
 
 
   public function getMarkupFieldKey($field) {
     $hash = PhabricatorHash::digestForIndex($this->getMarkupText($field));
     return "repo:{$hash}";
   }
 
   public function newMarkupEngine($field) {
     return PhabricatorMarkupEngine::newMarkupEngine(array());
   }
 
   public function getMarkupText($field) {
     return $this->getDetail('description');
   }
 
   public function didMarkupText(
     $field,
     $output,
     PhutilMarkupEngine $engine) {
     require_celerity_resource('phabricator-remarkup-css');
     return phutil_tag(
       'div',
       array(
         'class' => 'phabricator-remarkup',
       ),
       $output);
   }
 
   public function shouldUseMarkupCache($field) {
     return true;
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $this->openTransaction();
     $this->delete();
     $this->saveTransaction();
   }
 
 }