diff --git a/resources/sql/patches/releeph.sql b/resources/sql/patches/releeph.sql
new file mode 100644
index 000000000..a82435795
--- /dev/null
+++ b/resources/sql/patches/releeph.sql
@@ -0,0 +1,92 @@
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_project` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `dateCreated` int(10) unsigned NOT NULL,
+  `dateModified` int(10) unsigned NOT NULL,
+  `phid` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `name` varchar(255) NOT NULL,
+  `trunkBranch` varchar(255) NOT NULL,
+  `repositoryID` int(10) unsigned NOT NULL,
+  `repositoryPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `arcanistProjectID` int(10) unsigned NOT NULL,
+  `createdByUserPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `isActive` tinyint(1) NOT NULL DEFAULT '1',
+  `projectID` int(10) unsigned DEFAULT NULL,
+  `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `projectName` (`name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_branch` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `dateCreated` int(10) unsigned NOT NULL,
+  `dateModified` int(10) unsigned NOT NULL,
+  `basename` varchar(64) NOT NULL,
+  `releephProjectID` int(10) unsigned NOT NULL,
+  `createdByUserPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `cutPointCommitIdentifier`
+    varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `cutPointCommitPHID`
+    varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `isActive` tinyint(1) NOT NULL DEFAULT '1',
+  `symbolicName` varchar(64) DEFAULT NULL,
+  `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `phid` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `name` varchar(128) NOT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `releephProjectID_2` (`releephProjectID`,`basename`),
+  UNIQUE KEY `releephProjectID_name` (`releephProjectID`,`name`),
+  UNIQUE KEY `releephProjectID` (`releephProjectID`,`symbolicName`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_request` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `dateCreated` int(10) unsigned NOT NULL,
+  `dateModified` int(10) unsigned NOT NULL,
+  `phid` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `branchID` int(10) unsigned NOT NULL,
+  `summary` longtext CHARACTER SET utf8 COLLATE utf8_bin,
+  `requestUserPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `requestCommitIdentifier`
+    varchar(40) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `requestCommitPHID`
+    varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+  `requestCommitOrdinal` int(10) unsigned NOT NULL,
+  `commitIdentifier`
+    varchar(40) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+  `committedByUserPHID`
+    varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+  `commitPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+  `status` tinyint(4) DEFAULT NULL,
+  `pickStatus` tinyint(4) DEFAULT NULL,
+  `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `userIntents` longtext CHARACTER SET utf8 COLLATE utf8_bin,
+  `inBranch` tinyint(1) NOT NULL DEFAULT '0',
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `phid` (`phid`),
+  UNIQUE KEY `requestIdentifierBranch` (`requestCommitIdentifier`,`branchID`),
+  KEY `branchID` (`branchID`,`requestCommitOrdinal`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_requestevent` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `dateCreated` int(10) unsigned NOT NULL,
+  `dateModified` int(10) unsigned NOT NULL,
+  `releephRequestID` int(10) unsigned NOT NULL,
+  `actorPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+  `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  `type` varchar(32) NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+CREATE TABLE {$NAMESPACE}_releeph.`releeph_event` (
+  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+  `dateCreated` int(10) unsigned NOT NULL,
+  `dateModified` int(10) unsigned NOT NULL,
+  `releephProjectID` int(10) unsigned NOT NULL,
+  `releephBranchID` int(10) unsigned DEFAULT NULL,
+  `type` varchar(32) NOT NULL,
+  `epoch` int(10) unsigned DEFAULT NULL,
+  `actorPHID` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
+  `details` longtext CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php
index 3f64a695a..43b2d86a4 100644
--- a/src/__celerity_resource_map__.php
+++ b/src/__celerity_resource_map__.php
@@ -1,3937 +1,4066 @@
 <?php
 
 /**
  * This file is automatically generated. Use 'celerity_mapper.php' to rebuild
  * it.
  * @generated
  */
 
 celerity_register_resource_map(array(
   '/rsrc/image/actions/edit.png' =>
   array(
     'hash' => 'ae90914d120ac3838ddc633b480343f3',
     'uri' => '/res/ae90914d/rsrc/image/actions/edit.png',
     'disk' => '/rsrc/image/actions/edit.png',
     'type' => 'png',
   ),
   '/rsrc/image/avatar.png' =>
   array(
     'hash' => '1c5f255071537f05406adee86717ff27',
     'uri' => '/res/1c5f2550/rsrc/image/avatar.png',
     'disk' => '/rsrc/image/avatar.png',
     'type' => 'png',
   ),
   '/rsrc/image/checker_dark.png' =>
   array(
     'hash' => '640f795343df76ebe5409aae6187e57f',
     'uri' => '/res/640f7953/rsrc/image/checker_dark.png',
     'disk' => '/rsrc/image/checker_dark.png',
     'type' => 'png',
   ),
   '/rsrc/image/checker_light.png' =>
   array(
     'hash' => '7f8f3ef8beb0f2cc4cc69efb9e1c3308',
     'uri' => '/res/7f8f3ef8/rsrc/image/checker_light.png',
     'disk' => '/rsrc/image/checker_light.png',
     'type' => 'png',
   ),
   '/rsrc/image/credit_cards.png' =>
   array(
     'hash' => '681448de424ea159b6ea68af04c046ae',
     'uri' => '/res/681448de/rsrc/image/credit_cards.png',
     'disk' => '/rsrc/image/credit_cards.png',
     'type' => 'png',
   ),
   '/rsrc/image/darkload.gif' =>
   array(
     'hash' => '3a52cb7145d6e70f461fed21273117f2',
     'uri' => '/res/3a52cb71/rsrc/image/darkload.gif',
     'disk' => '/rsrc/image/darkload.gif',
     'type' => 'gif',
   ),
   '/rsrc/image/divot.png' =>
   array(
     'hash' => '3be267bd11ea375bf68e808893718e0e',
     'uri' => '/res/3be267bd/rsrc/image/divot.png',
     'disk' => '/rsrc/image/divot.png',
     'type' => 'png',
   ),
   '/rsrc/image/grippy_texture.png' =>
   array(
     'hash' => 'a8945e12ceeaddd5b491a8d81cfa19c1',
     'uri' => '/res/a8945e12/rsrc/image/grippy_texture.png',
     'disk' => '/rsrc/image/grippy_texture.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/arrow_branch.png' =>
   array(
     'hash' => 'f27b67520766e3d971722bcff703f3a8',
     'uri' => '/res/f27b6752/rsrc/image/icon/fatcow/arrow_branch.png',
     'disk' => '/rsrc/image/icon/fatcow/arrow_branch.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/arrow_merge.png' =>
   array(
     'hash' => 'c4bd97f3b1257439e2123ef69d2194d0',
     'uri' => '/res/c4bd97f3/rsrc/image/icon/fatcow/arrow_merge.png',
     'disk' => '/rsrc/image/icon/fatcow/arrow_merge.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/bullet_black.png' =>
   array(
     'hash' => '718f9c560a13766796f1be7dfaadeeab',
     'uri' => '/res/718f9c56/rsrc/image/icon/fatcow/bullet_black.png',
     'disk' => '/rsrc/image/icon/fatcow/bullet_black.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/bullet_orange.png' =>
   array(
     'hash' => 'c3bf91b65baacb27f2af143ab9180119',
     'uri' => '/res/c3bf91b6/rsrc/image/icon/fatcow/bullet_orange.png',
     'disk' => '/rsrc/image/icon/fatcow/bullet_orange.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/bullet_red.png' =>
   array(
     'hash' => '00273e4aa6ea3de630295610d6c9560c',
     'uri' => '/res/00273e4a/rsrc/image/icon/fatcow/bullet_red.png',
     'disk' => '/rsrc/image/icon/fatcow/bullet_red.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/calendar_edit.png' =>
   array(
     'hash' => 'de249c0f4f37bf5b2c69ff39ec5573fb',
     'uri' => '/res/de249c0f/rsrc/image/icon/fatcow/calendar_edit.png',
     'disk' => '/rsrc/image/icon/fatcow/calendar_edit.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/document_black.png' =>
   array(
     'hash' => '44d65a7f05a9c921719deedc160d68f7',
     'uri' => '/res/44d65a7f/rsrc/image/icon/fatcow/document_black.png',
     'disk' => '/rsrc/image/icon/fatcow/document_black.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/flag_blue.png' =>
   array(
     'hash' => '75a080492f900fbe489e4b27e403962b',
     'uri' => '/res/75a08049/rsrc/image/icon/fatcow/flag_blue.png',
     'disk' => '/rsrc/image/icon/fatcow/flag_blue.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/flag_finish.png' =>
   array(
     'hash' => '4af11fc7fab8e4610cbc3c88a02d4f78',
     'uri' => '/res/4af11fc7/rsrc/image/icon/fatcow/flag_finish.png',
     'disk' => '/rsrc/image/icon/fatcow/flag_finish.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/flag_ghost.png' =>
   array(
     'hash' => '14c9f30a37b43f276f27a27a924bf02d',
     'uri' => '/res/14c9f30a/rsrc/image/icon/fatcow/flag_ghost.png',
     'disk' => '/rsrc/image/icon/fatcow/flag_ghost.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/flag_green.png' =>
   array(
     'hash' => 'fed01374cd396cb774872762dcc447e1',
     'uri' => '/res/fed01374/rsrc/image/icon/fatcow/flag_green.png',
     'disk' => '/rsrc/image/icon/fatcow/flag_green.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/flag_orange.png' =>
   array(
     'hash' => '88008cb8bb99761a37e5a743e2455aeb',
     'uri' => '/res/88008cb8/rsrc/image/icon/fatcow/flag_orange.png',
     'disk' => '/rsrc/image/icon/fatcow/flag_orange.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/flag_pink.png' =>
   array(
     'hash' => '2f199f06ffc3dfc81b7561a057e0bc33',
     'uri' => '/res/2f199f06/rsrc/image/icon/fatcow/flag_pink.png',
     'disk' => '/rsrc/image/icon/fatcow/flag_pink.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/flag_purple.png' =>
   array(
     'hash' => '16358629dc86c39550b575586eb5df80',
     'uri' => '/res/16358629/rsrc/image/icon/fatcow/flag_purple.png',
     'disk' => '/rsrc/image/icon/fatcow/flag_purple.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/flag_red.png' =>
   array(
     'hash' => '210c28b4d93c439a499f5814f5e05772',
     'uri' => '/res/210c28b4/rsrc/image/icon/fatcow/flag_red.png',
     'disk' => '/rsrc/image/icon/fatcow/flag_red.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/flag_yellow.png' =>
   array(
     'hash' => 'bdfd73744a80bb80329ae50bc8a5f962',
     'uri' => '/res/bdfd7374/rsrc/image/icon/fatcow/flag_yellow.png',
     'disk' => '/rsrc/image/icon/fatcow/flag_yellow.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/folder.png' =>
   array(
     'hash' => '25e46cf9d210dde2242332296f79938c',
     'uri' => '/res/25e46cf9/rsrc/image/icon/fatcow/folder.png',
     'disk' => '/rsrc/image/icon/fatcow/folder.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/folder_go.png' =>
   array(
     'hash' => 'ba922ff7959309f51a14cb7ed5124d8b',
     'uri' => '/res/ba922ff7/rsrc/image/icon/fatcow/folder_go.png',
     'disk' => '/rsrc/image/icon/fatcow/folder_go.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/key_question.png' =>
   array(
     'hash' => '530a6448a4b91edec091a9292ccfd3d9',
     'uri' => '/res/530a6448/rsrc/image/icon/fatcow/key_question.png',
     'disk' => '/rsrc/image/icon/fatcow/key_question.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/link.png' =>
   array(
     'hash' => 'be1bea49b216548433014f3324902928',
     'uri' => '/res/be1bea49/rsrc/image/icon/fatcow/link.png',
     'disk' => '/rsrc/image/icon/fatcow/link.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/page_white_edit.png' =>
   array(
     'hash' => 'e7b7e7f2d9730bc80bc5c9eac1f3e36d',
     'uri' => '/res/e7b7e7f2/rsrc/image/icon/fatcow/page_white_edit.png',
     'disk' => '/rsrc/image/icon/fatcow/page_white_edit.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/page_white_link.png' =>
   array(
     'hash' => '1cfbad14412bda6c6f132dcc7c8725fd',
     'uri' => '/res/1cfbad14/rsrc/image/icon/fatcow/page_white_link.png',
     'disk' => '/rsrc/image/icon/fatcow/page_white_link.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/page_white_put.png' =>
   array(
     'hash' => 'bb7308aa5ac40137a8262da395a267fd',
     'uri' => '/res/bb7308aa/rsrc/image/icon/fatcow/page_white_put.png',
     'disk' => '/rsrc/image/icon/fatcow/page_white_put.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/page_white_text.png' =>
   array(
     'hash' => 'e47d590b626f617fb7d1d44e96e8fd11',
     'uri' => '/res/e47d590b/rsrc/image/icon/fatcow/page_white_text.png',
     'disk' => '/rsrc/image/icon/fatcow/page_white_text.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/source/conduit.png' =>
   array(
     'hash' => '1cae0656580aa3cd0b54b9d98306b1b9',
     'uri' => '/res/1cae0656/rsrc/image/icon/fatcow/source/conduit.png',
     'disk' => '/rsrc/image/icon/fatcow/source/conduit.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/source/email.png' =>
   array(
     'hash' => '93bdb3e168da1ed68f50c42125729d4e',
     'uri' => '/res/93bdb3e1/rsrc/image/icon/fatcow/source/email.png',
     'disk' => '/rsrc/image/icon/fatcow/source/email.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/source/fax.png' =>
   array(
     'hash' => 'd7dedf229841f2d041b347afd881596f',
     'uri' => '/res/d7dedf22/rsrc/image/icon/fatcow/source/fax.png',
     'disk' => '/rsrc/image/icon/fatcow/source/fax.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/source/mobile.png' =>
   array(
     'hash' => '786e7146d1e7d7318baf76c9d2baad97',
     'uri' => '/res/786e7146/rsrc/image/icon/fatcow/source/mobile.png',
     'disk' => '/rsrc/image/icon/fatcow/source/mobile.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/source/tablet.png' =>
   array(
     'hash' => '374cd40e4965be6b2fbdef4059d0ca05',
     'uri' => '/res/374cd40e/rsrc/image/icon/fatcow/source/tablet.png',
     'disk' => '/rsrc/image/icon/fatcow/source/tablet.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/source/web.png' =>
   array(
     'hash' => 'f4882a8f5619ba505ca033f72a340635',
     'uri' => '/res/f4882a8f/rsrc/image/icon/fatcow/source/web.png',
     'disk' => '/rsrc/image/icon/fatcow/source/web.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/thumbnails/default160x120.png' =>
   array(
     'hash' => '1b52ebd1fe0eee3ed0abfc382991b265',
     'uri' => '/res/1b52ebd1/rsrc/image/icon/fatcow/thumbnails/default160x120.png',
     'disk' => '/rsrc/image/icon/fatcow/thumbnails/default160x120.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/thumbnails/default60x45.png' =>
   array(
     'hash' => '048d851d8d1daad4754e891e734c1899',
     'uri' => '/res/048d851d/rsrc/image/icon/fatcow/thumbnails/default60x45.png',
     'disk' => '/rsrc/image/icon/fatcow/thumbnails/default60x45.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/thumbnails/image160x120.png' =>
   array(
     'hash' => '434acbd8dbbc2da9f09f6205a396eba1',
     'uri' => '/res/434acbd8/rsrc/image/icon/fatcow/thumbnails/image160x120.png',
     'disk' => '/rsrc/image/icon/fatcow/thumbnails/image160x120.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/thumbnails/image60x45.png' =>
   array(
     'hash' => '29f7872dc53588fe0b8f0b330c7ee23a',
     'uri' => '/res/29f7872d/rsrc/image/icon/fatcow/thumbnails/image60x45.png',
     'disk' => '/rsrc/image/icon/fatcow/thumbnails/image60x45.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/thumbnails/pdf160x120.png' =>
   array(
     'hash' => '39d2e22541658a3472ba41ae2fa548e5',
     'uri' => '/res/39d2e225/rsrc/image/icon/fatcow/thumbnails/pdf160x120.png',
     'disk' => '/rsrc/image/icon/fatcow/thumbnails/pdf160x120.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/thumbnails/pdf60x45.png' =>
   array(
     'hash' => 'b3572e9317cbed5184d12bdfabed2727',
     'uri' => '/res/b3572e93/rsrc/image/icon/fatcow/thumbnails/pdf60x45.png',
     'disk' => '/rsrc/image/icon/fatcow/thumbnails/pdf60x45.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/thumbnails/zip160x120.png' =>
   array(
     'hash' => 'e505108688a903b5cfb674707a289bcc',
     'uri' => '/res/e5051086/rsrc/image/icon/fatcow/thumbnails/zip160x120.png',
     'disk' => '/rsrc/image/icon/fatcow/thumbnails/zip160x120.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/fatcow/thumbnails/zip60x45.png' =>
   array(
     'hash' => 'f00716f4e8f7a95e70d43504f06be0a6',
     'uri' => '/res/f00716f4/rsrc/image/icon/fatcow/thumbnails/zip60x45.png',
     'disk' => '/rsrc/image/icon/fatcow/thumbnails/zip60x45.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/lightbox/close-2.png' =>
   array(
     'hash' => '72ff3ddcc1ed5d19a715ed6242114b53',
     'uri' => '/res/72ff3ddc/rsrc/image/icon/lightbox/close-2.png',
     'disk' => '/rsrc/image/icon/lightbox/close-2.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/lightbox/close-hover-2.png' =>
   array(
     'hash' => '6ad4bd4a7820547a1d9041752546ba16',
     'uri' => '/res/6ad4bd4a/rsrc/image/icon/lightbox/close-hover-2.png',
     'disk' => '/rsrc/image/icon/lightbox/close-hover-2.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/lightbox/left-arrow-2.png' =>
   array(
     'hash' => 'd84cbb0d42739f87b8f25b2f1d2f1153',
     'uri' => '/res/d84cbb0d/rsrc/image/icon/lightbox/left-arrow-2.png',
     'disk' => '/rsrc/image/icon/lightbox/left-arrow-2.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/lightbox/left-arrow-hover-2.png' =>
   array(
     'hash' => 'cdf05f98fff3f390cd8df0c89894a3e1',
     'uri' => '/res/cdf05f98/rsrc/image/icon/lightbox/left-arrow-hover-2.png',
     'disk' => '/rsrc/image/icon/lightbox/left-arrow-hover-2.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/lightbox/right-arrow-2.png' =>
   array(
     'hash' => '52021038cb6995c71f62a804bc2d420d',
     'uri' => '/res/52021038/rsrc/image/icon/lightbox/right-arrow-2.png',
     'disk' => '/rsrc/image/icon/lightbox/right-arrow-2.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/lightbox/right-arrow-hover-2.png' =>
   array(
     'hash' => '65d5756b7b9cfcdeb2eb197a9aa6bbd2',
     'uri' => '/res/65d5756b/rsrc/image/icon/lightbox/right-arrow-hover-2.png',
     'disk' => '/rsrc/image/icon/lightbox/right-arrow-hover-2.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/subscribe.png' =>
   array(
     'hash' => '5f47a4b17de245af39a4e7a097e40623',
     'uri' => '/res/5f47a4b1/rsrc/image/icon/subscribe.png',
     'disk' => '/rsrc/image/icon/subscribe.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/tango/attachment.png' =>
   array(
     'hash' => '776fed2de89803fd8a0ba4b9deede230',
     'uri' => '/res/776fed2d/rsrc/image/icon/tango/attachment.png',
     'disk' => '/rsrc/image/icon/tango/attachment.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/tango/edit.png' =>
   array(
     'hash' => 'c0028d99dcf4e9559bbf3c88ce2d8a8d',
     'uri' => '/res/c0028d99/rsrc/image/icon/tango/edit.png',
     'disk' => '/rsrc/image/icon/tango/edit.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/tango/go-down.png' =>
   array(
     'hash' => '96862812cbb0445573c264dc057b8300',
     'uri' => '/res/96862812/rsrc/image/icon/tango/go-down.png',
     'disk' => '/rsrc/image/icon/tango/go-down.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/tango/log.png' =>
   array(
     'hash' => 'a6f72499bef279ff6807a7dbc5148f1e',
     'uri' => '/res/a6f72499/rsrc/image/icon/tango/log.png',
     'disk' => '/rsrc/image/icon/tango/log.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/tango/upload.png' =>
   array(
     'hash' => '8c11b63d6d99db3d7159c5d9a94e3062',
     'uri' => '/res/8c11b63d/rsrc/image/icon/tango/upload.png',
     'disk' => '/rsrc/image/icon/tango/upload.png',
     'type' => 'png',
   ),
   '/rsrc/image/icon/unsubscribe.png' =>
   array(
     'hash' => '29429ad65aa3af50b072b32087057361',
     'uri' => '/res/29429ad6/rsrc/image/icon/unsubscribe.png',
     'disk' => '/rsrc/image/icon/unsubscribe.png',
     'type' => 'png',
   ),
   '/rsrc/image/loading.gif' =>
   array(
     'hash' => '664297671941142f37d8c89e717ff2ce',
     'uri' => '/res/66429767/rsrc/image/loading.gif',
     'disk' => '/rsrc/image/loading.gif',
     'type' => 'gif',
   ),
   '/rsrc/image/main_texture.png' =>
   array(
     'hash' => 'e34d8143384721be73ec9b7532a977ab',
     'uri' => '/res/e34d8143/rsrc/image/main_texture.png',
     'disk' => '/rsrc/image/main_texture.png',
     'type' => 'png',
   ),
   '/rsrc/image/menu_texture.png' =>
   array(
     'hash' => 'ad020b1529b3a3b3480ca9de1d5f1e40',
     'uri' => '/res/ad020b15/rsrc/image/menu_texture.png',
     'disk' => '/rsrc/image/menu_texture.png',
     'type' => 'png',
   ),
   '/rsrc/image/search.png' =>
   array(
     'hash' => 'ff7da044e6f923b8f569dec11f97e5e5',
     'uri' => '/res/ff7da044/rsrc/image/search.png',
     'disk' => '/rsrc/image/search.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-apps-X2.png' =>
   array(
     'hash' => '361e64ded74eee1094127c7878c2c385',
     'uri' => '/res/361e64de/rsrc/image/sprite-apps-X2.png',
     'disk' => '/rsrc/image/sprite-apps-X2.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-apps-large-X2.png' =>
   array(
     'hash' => '73507e04b4bd4d1e8e7544f7c424fc0f',
     'uri' => '/res/73507e04/rsrc/image/sprite-apps-large-X2.png',
     'disk' => '/rsrc/image/sprite-apps-large-X2.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-apps-large.png' =>
   array(
     'hash' => '6a5aade6134954171f2f1f8507270632',
     'uri' => '/res/6a5aade6/rsrc/image/sprite-apps-large.png',
     'disk' => '/rsrc/image/sprite-apps-large.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-apps-xlarge.png' =>
   array(
     'hash' => '992d2c278b6a22c0fa874d457a252fbd',
     'uri' => '/res/992d2c27/rsrc/image/sprite-apps-xlarge.png',
     'disk' => '/rsrc/image/sprite-apps-xlarge.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-apps.png' =>
   array(
     'hash' => '5e76c53e9f61755e5d3e7befa9d73ae5',
     'uri' => '/res/5e76c53e/rsrc/image/sprite-apps.png',
     'disk' => '/rsrc/image/sprite-apps.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-conpherence-X2.png' =>
   array(
     'hash' => '5e47868b00933a9afb6c844e464e6b23',
     'uri' => '/res/5e47868b/rsrc/image/sprite-conpherence-X2.png',
     'disk' => '/rsrc/image/sprite-conpherence-X2.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-conpherence.png' =>
   array(
     'hash' => 'ca51f1be25213262d68e626e4cab7f0f',
     'uri' => '/res/ca51f1be/rsrc/image/sprite-conpherence.png',
     'disk' => '/rsrc/image/sprite-conpherence.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-docs-X2.png' =>
   array(
     'hash' => '57d3286ce88133f3ec9240e35f6bb897',
     'uri' => '/res/57d3286c/rsrc/image/sprite-docs-X2.png',
     'disk' => '/rsrc/image/sprite-docs-X2.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-docs.png' =>
   array(
     'hash' => 'b2b089072d6eddd831402a77c02b5736',
     'uri' => '/res/b2b08907/rsrc/image/sprite-docs.png',
     'disk' => '/rsrc/image/sprite-docs.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-gradient.png' =>
   array(
     'hash' => '92aebaab67dcc6baf2ea99294368d895',
     'uri' => '/res/92aebaab/rsrc/image/sprite-gradient.png',
     'disk' => '/rsrc/image/sprite-gradient.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-icon-X2.png' =>
   array(
     'hash' => 'c9fae25bc6221922ce26517e654a18e4',
     'uri' => '/res/c9fae25b/rsrc/image/sprite-icon-X2.png',
     'disk' => '/rsrc/image/sprite-icon-X2.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-icon.png' =>
   array(
     'hash' => 'b690ea69bf5f2abe84d0a6e9ef64b03d',
     'uri' => '/res/b690ea69/rsrc/image/sprite-icon.png',
     'disk' => '/rsrc/image/sprite-icon.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-menu-X2.png' =>
   array(
     'hash' => '9f5cae08146fbe3b7e865b60c64121d1',
     'uri' => '/res/9f5cae08/rsrc/image/sprite-menu-X2.png',
     'disk' => '/rsrc/image/sprite-menu-X2.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-menu.png' =>
   array(
     'hash' => 'cc82b64d031dafa2b2a62cc8effa62f6',
     'uri' => '/res/cc82b64d/rsrc/image/sprite-menu.png',
     'disk' => '/rsrc/image/sprite-menu.png',
     'type' => 'png',
   ),
   '/rsrc/image/sprite-tokens.png' =>
   array(
     'hash' => '67c46fd75c885b76ecbfe46e71a476cc',
     'uri' => '/res/67c46fd7/rsrc/image/sprite-tokens.png',
     'disk' => '/rsrc/image/sprite-tokens.png',
     'type' => 'png',
   ),
   '/rsrc/image/texture/dark-menu-hover.png' =>
   array(
     'hash' => 'a214a732644be34872e895b338b5d639',
     'uri' => '/res/a214a732/rsrc/image/texture/dark-menu-hover.png',
     'disk' => '/rsrc/image/texture/dark-menu-hover.png',
     'type' => 'png',
   ),
   '/rsrc/image/texture/dark-menu.png' =>
   array(
     'hash' => '41ee673a762cec48a154b456ad5ac204',
     'uri' => '/res/41ee673a/rsrc/image/texture/dark-menu.png',
     'disk' => '/rsrc/image/texture/dark-menu.png',
     'type' => 'png',
   ),
   '/rsrc/image/texture/dust_background.jpg' =>
   array(
     'hash' => '1ff330c03712e08ca2eed006ccc6c1e7',
     'uri' => '/res/1ff330c0/rsrc/image/texture/dust_background.jpg',
     'disk' => '/rsrc/image/texture/dust_background.jpg',
     'type' => 'jpg',
   ),
   '/rsrc/image/texture/pholio-background.gif' =>
   array(
     'hash' => 'cf4561af116edf393dc583e5119fb412',
     'uri' => '/res/cf4561af/rsrc/image/texture/pholio-background.gif',
     'disk' => '/rsrc/image/texture/pholio-background.gif',
     'type' => 'gif',
   ),
   '/rsrc/image/texture/table_header.png' =>
   array(
     'hash' => '4ed3f56a30d3749e8f62052b9735a316',
     'uri' => '/res/4ed3f56a/rsrc/image/texture/table_header.png',
     'disk' => '/rsrc/image/texture/table_header.png',
     'type' => 'png',
   ),
   '/rsrc/image/texture/table_header_hover.png' =>
   array(
     'hash' => 'ea1f71a604e9b4859de1e25751540437',
     'uri' => '/res/ea1f71a6/rsrc/image/texture/table_header_hover.png',
     'disk' => '/rsrc/image/texture/table_header_hover.png',
     'type' => 'png',
   ),
   '/rsrc/image/texture/table_header_tall.png' =>
   array(
     'hash' => 'b05525601f78d759f1c5e47fd9c1a8aa',
     'uri' => '/res/b0552560/rsrc/image/texture/table_header_tall.png',
     'disk' => '/rsrc/image/texture/table_header_tall.png',
     'type' => 'png',
   ),
   '/rsrc/swf/aphlict.swf' =>
   array(
     'hash' => '4b9a9d83bebaf254f3790e87b45c1f92',
     'uri' => '/res/4b9a9d83/rsrc/swf/aphlict.swf',
     'disk' => '/rsrc/swf/aphlict.swf',
     'type' => 'swf',
   ),
   'aphront-attached-file-view-css' =>
   array(
     'uri' => '/res/a6ca5487/rsrc/css/aphront/attached-file-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/attached-file-view.css',
   ),
   'aphront-bars' =>
   array(
     'uri' => '/res/d7bd9032/rsrc/css/core/aphront-bars.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/core/aphront-bars.css',
   ),
   'aphront-calendar-view-css' =>
   array(
     'uri' => '/res/73061a31/rsrc/css/aphront/calendar-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/calendar-view.css',
   ),
   'aphront-contextbar-view-css' =>
   array(
     'uri' => '/res/ecfd5ba9/rsrc/css/aphront/context-bar.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/context-bar.css',
   ),
   'aphront-dark-console-css' =>
   array(
     'uri' => '/res/0d316573/rsrc/css/aphront/dark-console.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/dark-console.css',
   ),
   'aphront-dialog-view-css' =>
   array(
     'uri' => '/res/215b3ab1/rsrc/css/aphront/dialog-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/dialog-view.css',
   ),
   'aphront-error-view-css' =>
   array(
     'uri' => '/res/5f43a7c5/rsrc/css/aphront/error-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/error-view.css',
   ),
   'aphront-form-view-css' =>
   array(
     'uri' => '/res/ed8c70fa/rsrc/css/aphront/form-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/form-view.css',
   ),
   'aphront-list-filter-view-css' =>
   array(
     'uri' => '/res/cc6e940e/rsrc/css/aphront/list-filter-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/list-filter-view.css',
   ),
   'aphront-notes' =>
   array(
     'uri' => '/res/f8f3dcfa/rsrc/css/core/aphront-notes.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/core/aphront-notes.css',
   ),
   'aphront-pager-view-css' =>
   array(
     'uri' => '/res/43fb79f0/rsrc/css/aphront/pager-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/pager-view.css',
   ),
   'aphront-panel-view-css' =>
   array(
     'uri' => '/res/3d1420b3/rsrc/css/aphront/panel-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/panel-view.css',
   ),
   'aphront-request-failure-view-css' =>
   array(
     'uri' => '/res/c9a43002/rsrc/css/aphront/request-failure-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/request-failure-view.css',
   ),
   'aphront-table-view-css' =>
   array(
     'uri' => '/res/fd33a0f0/rsrc/css/aphront/table-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/table-view.css',
   ),
   'aphront-tokenizer-control-css' =>
   array(
     'uri' => '/res/207105f0/rsrc/css/aphront/tokenizer.css',
     'type' => 'css',
     'requires' =>
     array(
       0 => 'aphront-typeahead-control-css',
     ),
     'disk' => '/rsrc/css/aphront/tokenizer.css',
   ),
   'aphront-tooltip-css' =>
   array(
     'uri' => '/res/3a7d8e07/rsrc/css/aphront/tooltip.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/tooltip.css',
   ),
   'aphront-two-column-view-css' =>
   array(
     'uri' => '/res/7afa129f/rsrc/css/aphront/two-column.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/two-column.css',
   ),
   'aphront-typeahead-control-css' =>
   array(
     'uri' => '/res/ef59c20c/rsrc/css/aphront/typeahead.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/typeahead.css',
   ),
   'config-options-css' =>
   array(
     'uri' => '/res/e6c21f2f/rsrc/css/application/config/config-options.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/config/config-options.css',
   ),
   'conpherence-header-pane-css' =>
   array(
     'uri' => '/res/11c32adc/rsrc/css/application/conpherence/header-pane.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/conpherence/header-pane.css',
   ),
   'conpherence-menu-css' =>
   array(
     'uri' => '/res/0dc6b412/rsrc/css/application/conpherence/menu.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/conpherence/menu.css',
   ),
   'conpherence-message-pane-css' =>
   array(
     'uri' => '/res/3aa15b9e/rsrc/css/application/conpherence/message-pane.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/conpherence/message-pane.css',
   ),
   'conpherence-update-css' =>
   array(
     'uri' => '/res/92094ed7/rsrc/css/application/conpherence/update.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/conpherence/update.css',
   ),
   'conpherence-widget-pane-css' =>
   array(
     'uri' => '/res/f728d1fc/rsrc/css/application/conpherence/widget-pane.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/conpherence/widget-pane.css',
   ),
   'differential-changeset-view-css' =>
   array(
     'uri' => '/res/ea694162/rsrc/css/application/differential/changeset-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/changeset-view.css',
   ),
   'differential-core-view-css' =>
   array(
     'uri' => '/res/85fe5117/rsrc/css/application/differential/core.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/core.css',
   ),
   'differential-inline-comment-editor' =>
   array(
     'uri' => '/res/e0ad34ac/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-dom',
       1 => 'javelin-util',
       2 => 'javelin-stratcom',
       3 => 'javelin-install',
       4 => 'javelin-request',
       5 => 'javelin-workflow',
     ),
     'disk' => '/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
   ),
   'differential-local-commits-view-css' =>
   array(
     'uri' => '/res/224f3703/rsrc/css/application/differential/local-commits-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/local-commits-view.css',
   ),
   'differential-results-table-css' =>
   array(
     'uri' => '/res/aab3123c/rsrc/css/application/differential/results-table.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/results-table.css',
   ),
   'differential-revision-add-comment-css' =>
   array(
     'uri' => '/res/849748d3/rsrc/css/application/differential/add-comment.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/add-comment.css',
   ),
   'differential-revision-comment-css' =>
   array(
     'uri' => '/res/42c222f4/rsrc/css/application/differential/revision-comment.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/revision-comment.css',
   ),
   'differential-revision-comment-list-css' =>
   array(
     'uri' => '/res/3b31faa3/rsrc/css/application/differential/revision-comment-list.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/revision-comment-list.css',
   ),
   'differential-revision-history-css' =>
   array(
     'uri' => '/res/d41bc64c/rsrc/css/application/differential/revision-history.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/revision-history.css',
   ),
   'differential-revision-list-css' =>
   array(
     'uri' => '/res/fe6c4721/rsrc/css/application/differential/revision-list.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/revision-list.css',
   ),
   'differential-table-of-contents-css' =>
   array(
     'uri' => '/res/4fde8bfc/rsrc/css/application/differential/table-of-contents.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/table-of-contents.css',
   ),
   'diffusion-commit-view-css' =>
   array(
     'uri' => '/res/b445944e/rsrc/css/application/diffusion/commit-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/diffusion/commit-view.css',
   ),
   'diffusion-icons-css' =>
   array(
     'uri' => '/res/b93e32c9/rsrc/css/application/diffusion/diffusion-icons.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/diffusion/diffusion-icons.css',
   ),
   'diffusion-source-css' =>
   array(
     'uri' => '/res/e76bcd50/rsrc/css/application/diffusion/diffusion-source.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/diffusion/diffusion-source.css',
   ),
   'global-drag-and-drop-css' =>
   array(
     'uri' => '/res/4e24cb65/rsrc/css/application/files/global-drag-and-drop.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/files/global-drag-and-drop.css',
   ),
   'herald-css' =>
   array(
     'uri' => '/res/2150a55d/rsrc/css/application/herald/herald.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/herald/herald.css',
   ),
   'herald-rule-editor' =>
   array(
     'uri' => '/res/f35d7e23/rsrc/js/application/herald/HeraldRuleEditor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'multirow-row-manager',
       1 => 'javelin-install',
       2 => 'javelin-typeahead',
       3 => 'javelin-util',
       4 => 'javelin-dom',
       5 => 'javelin-tokenizer',
       6 => 'javelin-typeahead-preloaded-source',
       7 => 'javelin-stratcom',
       8 => 'javelin-json',
       9 => 'phabricator-prefab',
     ),
     'disk' => '/rsrc/js/application/herald/HeraldRuleEditor.js',
   ),
   'herald-test-css' =>
   array(
     'uri' => '/res/c0cd6bdb/rsrc/css/application/herald/herald-test.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/herald/herald-test.css',
   ),
   'inline-comment-summary-css' =>
   array(
     'uri' => '/res/338704f7/rsrc/css/application/diff/inline-comment-summary.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/diff/inline-comment-summary.css',
   ),
   'javelin-aphlict' =>
   array(
     'uri' => '/res/c0b9e53f/rsrc/js/application/aphlict/Aphlict.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/application/aphlict/Aphlict.js',
   ),
   'javelin-behavior' =>
   array(
     'uri' => '/res/ef4eda09/rsrc/js/javelin/lib/behavior.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-magical-init',
     ),
     'disk' => '/rsrc/js/javelin/lib/behavior.js',
   ),
   'javelin-behavior-aphlict-dropdown' =>
   array(
     'uri' => '/res/2418f448/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-request',
       2 => 'javelin-stratcom',
       3 => 'javelin-vector',
       4 => 'javelin-dom',
       5 => 'javelin-uri',
     ),
     'disk' => '/rsrc/js/application/aphlict/behavior-aphlict-dropdown.js',
   ),
   'javelin-behavior-aphlict-listen' =>
   array(
     'uri' => '/res/6dde3f43/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-aphlict',
       2 => 'javelin-stratcom',
       3 => 'javelin-request',
       4 => 'javelin-uri',
       5 => 'javelin-dom',
       6 => 'javelin-json',
       7 => 'phabricator-notification',
     ),
     'disk' => '/rsrc/js/application/aphlict/behavior-aphlict-listen.js',
   ),
   'javelin-behavior-aphront-basic-tokenizer' =>
   array(
     'uri' => '/res/cf049052/rsrc/js/application/core/behavior-tokenizer.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'phabricator-prefab',
     ),
     'disk' => '/rsrc/js/application/core/behavior-tokenizer.js',
   ),
   'javelin-behavior-aphront-crop' =>
   array(
     'uri' => '/res/cda1eace/rsrc/js/application/core/behavior-crop.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-vector',
       3 => 'javelin-magical-init',
     ),
     'disk' => '/rsrc/js/application/core/behavior-crop.js',
   ),
   'javelin-behavior-aphront-drag-and-drop' =>
   array(
     'uri' => '/res/8dd5fd78/rsrc/js/application/core/behavior-drag-and-drop.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'phabricator-file-upload',
       3 => 'phabricator-drag-and-drop-file-upload',
     ),
     'disk' => '/rsrc/js/application/core/behavior-drag-and-drop.js',
   ),
   'javelin-behavior-aphront-drag-and-drop-textarea' =>
   array(
     'uri' => '/res/853e33b9/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'phabricator-drag-and-drop-file-upload',
       3 => 'phabricator-paste-file-upload',
       4 => 'phabricator-textareautils',
     ),
     'disk' => '/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
   ),
   'javelin-behavior-aphront-form-disable-on-submit' =>
   array(
     'uri' => '/res/b5052cd0/rsrc/js/application/core/behavior-form.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-form.js',
   ),
   'javelin-behavior-aphront-more' =>
   array(
     'uri' => '/res/9ad83c3c/rsrc/js/application/core/behavior-more.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-more.js',
   ),
   'javelin-behavior-audit-preview' =>
   array(
     'uri' => '/res/3048b073/rsrc/js/application/diffusion/behavior-audit-preview.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'phabricator-shaped-request',
     ),
     'disk' => '/rsrc/js/application/diffusion/behavior-audit-preview.js',
   ),
   'javelin-behavior-conpherence-drag-and-drop-photo' =>
   array(
     'uri' => '/res/9e3eb1cd/rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-workflow',
       3 => 'phabricator-drag-and-drop-file-upload',
     ),
     'disk' => '/rsrc/js/application/conpherence/behavior-drag-and-drop-photo.js',
   ),
   'javelin-behavior-conpherence-init' =>
   array(
     'uri' => '/res/700bba2e/rsrc/js/application/conpherence/behavior-init.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/conpherence/behavior-init.js',
   ),
   'javelin-behavior-conpherence-menu' =>
   array(
     'uri' => '/res/cb1a5cf0/rsrc/js/application/conpherence/behavior-menu.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-request',
       3 => 'javelin-stratcom',
       4 => 'javelin-uri',
       5 => 'javelin-util',
       6 => 'javelin-workflow',
     ),
     'disk' => '/rsrc/js/application/conpherence/behavior-menu.js',
   ),
   'javelin-behavior-conpherence-pontificate' =>
   array(
     'uri' => '/res/15263692/rsrc/js/application/conpherence/behavior-pontificate.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'javelin-workflow',
     ),
     'disk' => '/rsrc/js/application/conpherence/behavior-pontificate.js',
   ),
   'javelin-behavior-conpherence-widget-pane' =>
   array(
     'uri' => '/res/43a0fe1b/rsrc/js/application/conpherence/behavior-widget-pane.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/conpherence/behavior-widget-pane.js',
   ),
   'javelin-behavior-countdown-timer' =>
   array(
     'uri' => '/res/7468acb7/rsrc/js/application/countdown/timer.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/application/countdown/timer.js',
   ),
   'javelin-behavior-dark-console' =>
   array(
     'uri' => '/res/89aeb6c0/rsrc/js/application/core/behavior-dark-console.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-request',
       5 => 'phabricator-keyboard-shortcut',
     ),
     'disk' => '/rsrc/js/application/core/behavior-dark-console.js',
   ),
   'javelin-behavior-device' =>
   array(
     'uri' => '/res/a10b851b/rsrc/js/application/core/behavior-device.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
       3 => 'javelin-vector',
       4 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/application/core/behavior-device.js',
   ),
   'javelin-behavior-differential-accept-with-errors' =>
   array(
     'uri' => '/res/8fea67b3/rsrc/js/application/differential/behavior-accept-with-errors.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-accept-with-errors.js',
   ),
   'javelin-behavior-differential-add-reviewers-and-ccs' =>
   array(
     'uri' => '/res/27be3f81/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'phabricator-prefab',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js',
   ),
   'javelin-behavior-differential-comment-jump' =>
   array(
     'uri' => '/res/b580229b/rsrc/js/application/differential/behavior-comment-jump.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-util',
       2 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-comment-jump.js',
   ),
   'javelin-behavior-differential-diff-radios' =>
   array(
     'uri' => '/res/004cb66f/rsrc/js/application/differential/behavior-diff-radios.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-diff-radios.js',
   ),
   'javelin-behavior-differential-dropdown-menus' =>
   array(
     'uri' => '/res/752f5dfc/rsrc/js/application/differential/behavior-dropdown-menus.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'javelin-stratcom',
       4 => 'phabricator-dropdown-menu',
       5 => 'phabricator-menu-item',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-dropdown-menus.js',
   ),
   'javelin-behavior-differential-edit-inline-comments' =>
   array(
     'uri' => '/res/70c1f3a3/rsrc/js/application/differential/behavior-edit-inline-comments.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
       3 => 'javelin-util',
       4 => 'javelin-vector',
       5 => 'differential-inline-comment-editor',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-edit-inline-comments.js',
   ),
   'javelin-behavior-differential-feedback-preview' =>
   array(
     'uri' => '/res/5fbce8db/rsrc/js/application/differential/behavior-comment-preview.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
       3 => 'javelin-request',
       4 => 'javelin-util',
       5 => 'phabricator-shaped-request',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-comment-preview.js',
   ),
   'javelin-behavior-differential-keyboard-navigation' =>
   array(
     'uri' => '/res/89e93cc9/rsrc/js/application/differential/behavior-keyboard-nav.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
       3 => 'phabricator-keyboard-shortcut',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-keyboard-nav.js',
   ),
   'javelin-behavior-differential-populate' =>
   array(
     'uri' => '/res/526c2615/rsrc/js/application/differential/behavior-populate.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-workflow',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-stratcom',
       5 => 'javelin-behavior-device',
       6 => 'javelin-vector',
       7 => 'phabricator-tooltip',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-populate.js',
   ),
   'javelin-behavior-differential-show-all-comments' =>
   array(
     'uri' => '/res/eaa12efc/rsrc/js/application/differential/behavior-show-all-comments.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-show-all-comments.js',
   ),
   'javelin-behavior-differential-show-field-details' =>
   array(
     'uri' => '/res/8d57f459/rsrc/js/application/differential/behavior-show-field-details.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-show-field-details.js',
   ),
   'javelin-behavior-differential-show-more' =>
   array(
     'uri' => '/res/b9f93090/rsrc/js/application/differential/behavior-show-more.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-workflow',
       3 => 'javelin-util',
       4 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-show-more.js',
   ),
   'javelin-behavior-differential-toggle-files' =>
   array(
     'uri' => '/res/ae937207/rsrc/js/application/differential/behavior-toggle-files.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-toggle-files.js',
   ),
   'javelin-behavior-differential-user-select' =>
   array(
     'uri' => '/res/23c51a5d/rsrc/js/application/differential/behavior-user-select.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-user-select.js',
   ),
   'javelin-behavior-diffusion-commit-branches' =>
   array(
     'uri' => '/res/1ede335a/rsrc/js/application/diffusion/behavior-commit-branches.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'javelin-request',
     ),
     'disk' => '/rsrc/js/application/diffusion/behavior-commit-branches.js',
   ),
   'javelin-behavior-diffusion-commit-graph' =>
   array(
     'uri' => '/res/62bd2035/rsrc/js/application/diffusion/behavior-commit-graph.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/diffusion/behavior-commit-graph.js',
   ),
   'javelin-behavior-diffusion-jump-to' =>
   array(
     'uri' => '/res/7c42e1ba/rsrc/js/application/diffusion/behavior-jump-to.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-util',
       2 => 'javelin-vector',
       3 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/diffusion/behavior-jump-to.js',
   ),
   'javelin-behavior-diffusion-line-linker' =>
   array(
     'uri' => '/res/12866f13/rsrc/js/application/diffusion/behavior-line-linker.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
       3 => 'javelin-history',
     ),
     'disk' => '/rsrc/js/application/diffusion/behavior-line-linker.js',
   ),
   'javelin-behavior-diffusion-pull-lastmodified' =>
   array(
     'uri' => '/res/29fe2790/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'javelin-request',
     ),
     'disk' => '/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
   ),
   'javelin-behavior-error-log' =>
   array(
     'uri' => '/res/f46289e9/rsrc/js/application/core/behavior-error-log.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-error-log.js',
   ),
   'javelin-behavior-fancy-datepicker' =>
   array(
     'uri' => '/res/0a1bc610/rsrc/js/application/core/behavior-fancy-datepicker.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-util',
       2 => 'javelin-dom',
       3 => 'javelin-stratcom',
       4 => 'javelin-vector',
     ),
     'disk' => '/rsrc/js/application/core/behavior-fancy-datepicker.js',
   ),
   'javelin-behavior-global-drag-and-drop' =>
   array(
     'uri' => '/res/73ae3fd1/rsrc/js/application/core/behavior-global-drag-and-drop.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-uri',
       3 => 'javelin-mask',
       4 => 'phabricator-drag-and-drop-file-upload',
     ),
     'disk' => '/rsrc/js/application/core/behavior-global-drag-and-drop.js',
   ),
   'javelin-behavior-herald-rule-editor' =>
   array(
     'uri' => '/res/77a0c945/rsrc/js/application/herald/herald-rule-editor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'herald-rule-editor',
       1 => 'javelin-behavior',
     ),
     'disk' => '/rsrc/js/application/herald/herald-rule-editor.js',
   ),
   'javelin-behavior-history-install' =>
   array(
     'uri' => '/res/e146a99b/rsrc/js/application/core/behavior-history-install.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-history',
     ),
     'disk' => '/rsrc/js/application/core/behavior-history-install.js',
   ),
   'javelin-behavior-konami' =>
   array(
     'uri' => '/res/2199602f/rsrc/js/application/core/behavior-konami.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-konami.js',
   ),
   'javelin-behavior-lightbox-attachments' =>
   array(
     'uri' => '/res/08f5e202/rsrc/js/application/core/behavior-lightbox-attachments.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
       3 => 'javelin-mask',
       4 => 'javelin-util',
       5 => 'phabricator-busy',
     ),
     'disk' => '/rsrc/js/application/core/behavior-lightbox-attachments.js',
   ),
   'javelin-behavior-line-chart' =>
   array(
     'uri' => '/res/1aa5ac88/rsrc/js/application/maniphest/behavior-line-chart.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-vector',
     ),
     'disk' => '/rsrc/js/application/maniphest/behavior-line-chart.js',
   ),
   'javelin-behavior-load-blame' =>
   array(
     'uri' => '/res/138e2961/rsrc/js/application/diffusion/behavior-load-blame.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-request',
     ),
     'disk' => '/rsrc/js/application/diffusion/behavior-load-blame.js',
   ),
   'javelin-behavior-maniphest-batch-editor' =>
   array(
     'uri' => '/res/d22661be/rsrc/js/application/maniphest/behavior-batch-editor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'phabricator-prefab',
       4 => 'multirow-row-manager',
       5 => 'javelin-json',
     ),
     'disk' => '/rsrc/js/application/maniphest/behavior-batch-editor.js',
   ),
   'javelin-behavior-maniphest-batch-selector' =>
   array(
     'uri' => '/res/398cf8d7/rsrc/js/application/maniphest/behavior-batch-selector.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/maniphest/behavior-batch-selector.js',
   ),
   'javelin-behavior-maniphest-description-preview' =>
   array(
     'uri' => '/res/8acd6f07/rsrc/js/application/maniphest/behavior-task-preview.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'phabricator-shaped-request',
     ),
     'disk' => '/rsrc/js/application/maniphest/behavior-task-preview.js',
   ),
   'javelin-behavior-maniphest-subpriority-editor' =>
   array(
     'uri' => '/res/5e02f19a/rsrc/js/application/maniphest/behavior-subpriorityeditor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-magical-init',
       2 => 'javelin-dom',
       3 => 'javelin-vector',
       4 => 'javelin-stratcom',
       5 => 'javelin-workflow',
     ),
     'disk' => '/rsrc/js/application/maniphest/behavior-subpriorityeditor.js',
   ),
   'javelin-behavior-maniphest-transaction-controls' =>
   array(
     'uri' => '/res/62465554/rsrc/js/application/maniphest/behavior-transaction-controls.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'phabricator-prefab',
     ),
     'disk' => '/rsrc/js/application/maniphest/behavior-transaction-controls.js',
   ),
   'javelin-behavior-maniphest-transaction-expand' =>
   array(
     'uri' => '/res/966410de/rsrc/js/application/maniphest/behavior-transaction-expand.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-workflow',
       3 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/maniphest/behavior-transaction-expand.js',
   ),
   'javelin-behavior-maniphest-transaction-preview' =>
   array(
     'uri' => '/res/855c9f0c/rsrc/js/application/maniphest/behavior-transaction-preview.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'javelin-json',
       4 => 'javelin-stratcom',
       5 => 'phabricator-shaped-request',
     ),
     'disk' => '/rsrc/js/application/maniphest/behavior-transaction-preview.js',
   ),
   'javelin-behavior-owners-path-editor' =>
   array(
     'uri' => '/res/9cf78ffc/rsrc/js/application/owners/owners-path-editor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'owners-path-editor',
       1 => 'javelin-behavior',
     ),
     'disk' => '/rsrc/js/application/owners/owners-path-editor.js',
   ),
   'javelin-behavior-phabricator-active-nav' =>
   array(
     'uri' => '/res/f879d4dd/rsrc/js/application/core/behavior-active-nav.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-vector',
       3 => 'javelin-dom',
       4 => 'javelin-uri',
     ),
     'disk' => '/rsrc/js/application/core/behavior-active-nav.js',
   ),
   'javelin-behavior-phabricator-autofocus' =>
   array(
     'uri' => '/res/2946bb89/rsrc/js/application/core/behavior-autofocus.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-autofocus.js',
   ),
   'javelin-behavior-phabricator-file-tree' =>
   array(
     'uri' => '/res/e9c96597/rsrc/js/application/core/behavior-file-tree.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'phabricator-keyboard-shortcut',
       2 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-file-tree.js',
   ),
   'javelin-behavior-phabricator-gesture' =>
   array(
     'uri' => '/res/f186161c/rsrc/js/application/core/behavior-gesture.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-behavior-device',
       2 => 'javelin-stratcom',
       3 => 'javelin-vector',
       4 => 'javelin-dom',
       5 => 'javelin-magical-init',
     ),
     'disk' => '/rsrc/js/application/core/behavior-gesture.js',
   ),
   'javelin-behavior-phabricator-gesture-example' =>
   array(
     'uri' => '/res/da636e19/rsrc/js/application/uiexample/gesture-example.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-stratcom',
       1 => 'javelin-behavior',
       2 => 'javelin-vector',
       3 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/gesture-example.js',
   ),
   'javelin-behavior-phabricator-keyboard-pager' =>
   array(
     'uri' => '/res/56d64eff/rsrc/js/application/core/behavior-keyboard-pager.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-uri',
       2 => 'phabricator-keyboard-shortcut',
     ),
     'disk' => '/rsrc/js/application/core/behavior-keyboard-pager.js',
   ),
   'javelin-behavior-phabricator-keyboard-shortcuts' =>
   array(
     'uri' => '/res/c5eb65cd/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-workflow',
       2 => 'javelin-json',
       3 => 'javelin-dom',
       4 => 'phabricator-keyboard-shortcut',
     ),
     'disk' => '/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
   ),
   'javelin-behavior-phabricator-nav' =>
   array(
     'uri' => '/res/222b9329/rsrc/js/application/core/behavior-phabricator-nav.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-behavior-device',
       2 => 'javelin-stratcom',
       3 => 'javelin-dom',
       4 => 'javelin-magical-init',
       5 => 'javelin-vector',
     ),
     'disk' => '/rsrc/js/application/core/behavior-phabricator-nav.js',
   ),
   'javelin-behavior-phabricator-notification-example' =>
   array(
     'uri' => '/res/a6d51998/rsrc/js/application/uiexample/notification-example.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'phabricator-notification',
       1 => 'javelin-stratcom',
       2 => 'javelin-behavior',
       3 => 'javelin-uri',
     ),
     'disk' => '/rsrc/js/application/uiexample/notification-example.js',
   ),
   'javelin-behavior-phabricator-object-selector' =>
   array(
     'uri' => '/res/0c4b0d82/rsrc/js/application/core/behavior-object-selector.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-request',
       3 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/application/core/behavior-object-selector.js',
   ),
   'javelin-behavior-phabricator-oncopy' =>
   array(
     'uri' => '/res/f490b8d1/rsrc/js/application/core/behavior-oncopy.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-oncopy.js',
   ),
   'javelin-behavior-phabricator-remarkup-assist' =>
   array(
     'uri' => '/res/07406487/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
       3 => 'phabricator-textareautils',
     ),
     'disk' => '/rsrc/js/application/core/behavior-phabricator-remarkup-assist.js',
   ),
   'javelin-behavior-phabricator-reveal-content' =>
   array(
     'uri' => '/res/a4fae14a/rsrc/js/application/core/behavior-reveal-content.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-reveal-content.js',
   ),
   'javelin-behavior-phabricator-search-typeahead' =>
   array(
     'uri' => '/res/046ab274/rsrc/js/application/core/behavior-search-typeahead.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-typeahead-ondemand-source',
       2 => 'javelin-typeahead',
       3 => 'javelin-dom',
       4 => 'javelin-uri',
       5 => 'javelin-util',
       6 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-search-typeahead.js',
   ),
   'javelin-behavior-phabricator-tooltips' =>
   array(
     'uri' => '/res/e0b344c6/rsrc/js/application/core/behavior-tooltip.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-behavior-device',
       2 => 'javelin-stratcom',
       3 => 'phabricator-tooltip',
     ),
     'disk' => '/rsrc/js/application/core/behavior-tooltip.js',
   ),
   'javelin-behavior-phabricator-transaction-comment-form' =>
   array(
     'uri' => '/res/acc3ada1/rsrc/js/application/transactions/behavior-transaction-comment-form.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'phabricator-shaped-request',
     ),
     'disk' => '/rsrc/js/application/transactions/behavior-transaction-comment-form.js',
   ),
   'javelin-behavior-phabricator-transaction-list' =>
   array(
     'uri' => '/res/f1fbb474/rsrc/js/application/transactions/behavior-transaction-list.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-workflow',
       3 => 'javelin-dom',
       4 => 'javelin-fx',
     ),
     'disk' => '/rsrc/js/application/transactions/behavior-transaction-list.js',
   ),
   'javelin-behavior-phabricator-watch-anchor' =>
   array(
     'uri' => '/res/b20b1cc2/rsrc/js/application/core/behavior-watch-anchor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
       3 => 'javelin-vector',
     ),
     'disk' => '/rsrc/js/application/core/behavior-watch-anchor.js',
   ),
   'javelin-behavior-phame-post-preview' =>
   array(
     'uri' => '/res/ac4c503a/rsrc/js/application/phame/phame-post-preview.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'phabricator-shaped-request',
     ),
     'disk' => '/rsrc/js/application/phame/phame-post-preview.js',
   ),
   'javelin-behavior-pholio-mock-view' =>
   array(
-    'uri' => '/res/eefc43b3/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
+    'uri' => '/res/ecf5f969/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-util',
       2 => 'javelin-stratcom',
       3 => 'javelin-dom',
       4 => 'javelin-vector',
       5 => 'javelin-magical-init',
       6 => 'javelin-request',
       7 => 'javelin-history',
       8 => 'javelin-workflow',
       9 => 'javelin-mask',
       10 => 'javelin-behavior-device',
       11 => 'phabricator-keyboard-shortcut',
     ),
     'disk' => '/rsrc/js/application/pholio/behavior-pholio-mock-view.js',
   ),
   'javelin-behavior-phriction-document-preview' =>
   array(
     'uri' => '/res/f1665ecd/rsrc/js/application/phriction/phriction-document-preview.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'phabricator-shaped-request',
     ),
     'disk' => '/rsrc/js/application/phriction/phriction-document-preview.js',
   ),
   'javelin-behavior-ponder-feedback-preview' =>
   array(
     'uri' => '/res/2e802dd9/rsrc/js/application/ponder/behavior-comment-preview.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'phabricator-shaped-request',
     ),
     'disk' => '/rsrc/js/application/ponder/behavior-comment-preview.js',
   ),
   'javelin-behavior-ponder-votebox' =>
   array(
     'uri' => '/res/9d091af3/rsrc/js/application/ponder/behavior-votebox.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       3 => 'javelin-stratcom',
       4 => 'javelin-request',
     ),
     'disk' => '/rsrc/js/application/ponder/behavior-votebox.js',
   ),
   'javelin-behavior-project-create' =>
   array(
     'uri' => '/res/e91f3f8f/rsrc/js/application/projects/behavior-project-create.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
       3 => 'javelin-workflow',
     ),
     'disk' => '/rsrc/js/application/projects/behavior-project-create.js',
   ),
   'javelin-behavior-refresh-csrf' =>
   array(
     'uri' => '/res/6fd76d0f/rsrc/js/application/core/behavior-refresh-csrf.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-request',
       1 => 'javelin-behavior',
       2 => 'javelin-dom',
       3 => 'phabricator-busy',
     ),
     'disk' => '/rsrc/js/application/core/behavior-refresh-csrf.js',
   ),
+  'javelin-behavior-releeph-preview-branch' =>
+  array(
+    'uri' => '/res/a77ebc86/rsrc/js/application/releeph/releeph-preview-branch.js',
+    'type' => 'js',
+    'requires' =>
+    array(
+      0 => 'javelin-behavior',
+      1 => 'javelin-dom',
+      2 => 'javelin-stratcom',
+      3 => 'javelin-uri',
+      4 => 'javelin-util',
+    ),
+    'disk' => '/rsrc/js/application/releeph/releeph-preview-branch.js',
+  ),
+  'javelin-behavior-releeph-request-state-change' =>
+  array(
+    'uri' => '/res/38f96ba8/rsrc/js/application/releeph/releeph-request-state-change.js',
+    'type' => 'js',
+    'requires' =>
+    array(
+      0 => 'javelin-behavior',
+      1 => 'javelin-dom',
+      2 => 'javelin-stratcom',
+      3 => 'javelin-util',
+      4 => 'phabricator-keyboard-shortcut',
+      5 => 'phabricator-notification',
+    ),
+    'disk' => '/rsrc/js/application/releeph/releeph-request-state-change.js',
+  ),
+  'javelin-behavior-releeph-request-typeahead' =>
+  array(
+    'uri' => '/res/b52096e2/rsrc/js/application/releeph/releeph-request-typeahead.js',
+    'type' => 'js',
+    'requires' =>
+    array(
+      0 => 'javelin-behavior',
+      1 => 'javelin-util',
+      2 => 'javelin-dom',
+      3 => 'javelin-typeahead',
+      4 => 'javelin-tokenizer',
+      5 => 'javelin-typeahead-preloaded-source',
+      6 => 'javelin-typeahead-ondemand-source',
+      7 => 'javelin-dom',
+      8 => 'javelin-stratcom',
+      9 => 'javelin-util',
+    ),
+    'disk' => '/rsrc/js/application/releeph/releeph-request-typeahead.js',
+  ),
   'javelin-behavior-repository-crossreference' =>
   array(
     'uri' => '/res/4b5fab1c/rsrc/js/application/repository/repository-crossreference.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
       3 => 'javelin-uri',
     ),
     'disk' => '/rsrc/js/application/repository/repository-crossreference.js',
   ),
   'javelin-behavior-stripe-payment-form' =>
   array(
     'uri' => '/res/87c7b043/rsrc/js/application/phortune/behavior-stripe-payment-form.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-json',
       3 => 'stripe-core',
     ),
     'disk' => '/rsrc/js/application/phortune/behavior-stripe-payment-form.js',
   ),
   'javelin-behavior-toggle-class' =>
   array(
     'uri' => '/res/fa818e0f/rsrc/js/application/core/behavior-toggle-class.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-toggle-class.js',
   ),
   'javelin-behavior-view-placeholder' =>
   array(
     'uri' => '/res/5b89bdf5/rsrc/js/javelin/ext/view/ViewPlaceholder.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-view-renderer',
     ),
     'disk' => '/rsrc/js/javelin/ext/view/ViewPlaceholder.js',
   ),
   'javelin-behavior-workflow' =>
   array(
     'uri' => '/res/2c99beaf/rsrc/js/application/core/behavior-workflow.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-workflow',
       3 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-workflow.js',
   ),
   'javelin-color' =>
   array(
     'uri' => '/res/b0439fc9/rsrc/js/javelin/ext/fx/Color.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/javelin/ext/fx/Color.js',
   ),
   'javelin-cookie' =>
   array(
     'uri' => '/res/a9cddab0/rsrc/js/javelin/lib/Cookie.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/lib/Cookie.js',
   ),
   'javelin-dom' =>
   array(
     'uri' => '/res/459f3c08/rsrc/js/javelin/lib/DOM.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-magical-init',
       1 => 'javelin-install',
       2 => 'javelin-util',
       3 => 'javelin-vector',
       4 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/javelin/lib/DOM.js',
   ),
   'javelin-dynval' =>
   array(
     'uri' => '/res/d89c6f88/rsrc/js/javelin/ext/reactor/core/DynVal.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-reactornode',
       2 => 'javelin-util',
       3 => 'javelin-reactor',
     ),
     'disk' => '/rsrc/js/javelin/ext/reactor/core/DynVal.js',
   ),
   'javelin-event' =>
   array(
     'uri' => '/res/69d99d9f/rsrc/js/javelin/core/Event.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/javelin/core/Event.js',
   ),
   'javelin-fx' =>
   array(
     'uri' => '/res/30ef0914/rsrc/js/javelin/ext/fx/FX.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-color',
       1 => 'javelin-install',
       2 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/ext/fx/FX.js',
   ),
   'javelin-history' =>
   array(
     'uri' => '/res/9bb36651/rsrc/js/javelin/lib/History.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-stratcom',
       1 => 'javelin-install',
       2 => 'javelin-uri',
       3 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/lib/History.js',
   ),
   'javelin-install' =>
   array(
     'uri' => '/res/cab679ff/rsrc/js/javelin/core/install.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-util',
       1 => 'javelin-magical-init',
     ),
     'disk' => '/rsrc/js/javelin/core/install.js',
   ),
   'javelin-json' =>
   array(
     'uri' => '/res/561b8056/rsrc/js/javelin/lib/JSON.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/javelin/lib/JSON.js',
   ),
   'javelin-magical-init' =>
   array(
     'uri' => '/res/2f1554da/rsrc/js/javelin/core/init.js',
     'type' => 'js',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/js/javelin/core/init.js',
   ),
   'javelin-mask' =>
   array(
     'uri' => '/res/d2a35fff/rsrc/js/javelin/lib/Mask.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/javelin/lib/Mask.js',
   ),
   'javelin-reactor' =>
   array(
     'uri' => '/res/dfd87f3c/rsrc/js/javelin/ext/reactor/core/Reactor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/ext/reactor/core/Reactor.js',
   ),
   'javelin-reactor-dom' =>
   array(
     'uri' => '/res/701b6f39/rsrc/js/javelin/ext/reactor/dom/RDOM.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-dom',
       1 => 'javelin-dynval',
       2 => 'javelin-reactornode',
       3 => 'javelin-install',
       4 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/ext/reactor/dom/RDOM.js',
   ),
   'javelin-reactor-node-calmer' =>
   array(
     'uri' => '/res/5a35920a/rsrc/js/javelin/ext/reactor/core/ReactorNodeCalmer.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-reactor',
       2 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/ext/reactor/core/ReactorNodeCalmer.js',
   ),
   'javelin-reactornode' =>
   array(
     'uri' => '/res/f278cc27/rsrc/js/javelin/ext/reactor/core/ReactorNode.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-reactor',
       2 => 'javelin-util',
       3 => 'javelin-reactor-node-calmer',
     ),
     'disk' => '/rsrc/js/javelin/ext/reactor/core/ReactorNode.js',
   ),
   'javelin-request' =>
   array(
     'uri' => '/res/e25d75b3/rsrc/js/javelin/lib/Request.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-stratcom',
       2 => 'javelin-util',
       3 => 'javelin-behavior',
       4 => 'javelin-json',
       5 => 'javelin-dom',
       6 => 'javelin-resource',
     ),
     'disk' => '/rsrc/js/javelin/lib/Request.js',
   ),
   'javelin-resource' =>
   array(
     'uri' => '/res/d5a3f835/rsrc/js/javelin/lib/Resource.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-magical-init',
       1 => 'javelin-stratcom',
       2 => 'javelin-util',
       3 => 'javelin-uri',
     ),
     'disk' => '/rsrc/js/javelin/lib/Resource.js',
   ),
   'javelin-stratcom' =>
   array(
     'uri' => '/res/c81f64eb/rsrc/js/javelin/core/Stratcom.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-event',
       2 => 'javelin-util',
       3 => 'javelin-magical-init',
     ),
     'disk' => '/rsrc/js/javelin/core/Stratcom.js',
   ),
   'javelin-tokenizer' =>
   array(
     'uri' => '/res/c75c9e12/rsrc/js/javelin/lib/control/tokenizer/Tokenizer.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-dom',
       1 => 'javelin-util',
       2 => 'javelin-stratcom',
       3 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/javelin/lib/control/tokenizer/Tokenizer.js',
   ),
   'javelin-typeahead' =>
   array(
     'uri' => '/res/dccb789e/rsrc/js/javelin/lib/control/typeahead/Typeahead.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-dom',
       2 => 'javelin-vector',
       3 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/lib/control/typeahead/Typeahead.js',
   ),
   'javelin-typeahead-composite-source' =>
   array(
     'uri' => '/res/99705f64/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-typeahead-source',
       2 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadCompositeSource.js',
   ),
   'javelin-typeahead-normalizer' =>
   array(
     'uri' => '/res/a9e97c0d/rsrc/js/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/javelin/lib/control/typeahead/normalizer/TypeaheadNormalizer.js',
   ),
   'javelin-typeahead-ondemand-source' =>
   array(
     'uri' => '/res/81e531aa/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-stratcom',
       3 => 'javelin-request',
       4 => 'javelin-typeahead-source',
     ),
     'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadOnDemandSource.js',
   ),
   'javelin-typeahead-preloaded-source' =>
   array(
     'uri' => '/res/d464efd2/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-stratcom',
       3 => 'javelin-request',
       4 => 'javelin-typeahead-source',
     ),
     'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadPreloadedSource.js',
   ),
   'javelin-typeahead-source' =>
   array(
     'uri' => '/res/74b1f091/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadSource.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-dom',
       3 => 'javelin-typeahead-normalizer',
     ),
     'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadSource.js',
   ),
   'javelin-typeahead-static-source' =>
   array(
     'uri' => '/res/c8e247fc/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-typeahead-source',
     ),
     'disk' => '/rsrc/js/javelin/lib/control/typeahead/source/TypeaheadStaticSource.js',
   ),
   'javelin-uri' =>
   array(
     'uri' => '/res/c107d858/rsrc/js/javelin/lib/URI.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/javelin/lib/URI.js',
   ),
   'javelin-util' =>
   array(
     'uri' => '/res/25786b6c/rsrc/js/javelin/core/util.js',
     'type' => 'js',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/js/javelin/core/util.js',
   ),
   'javelin-vector' =>
   array(
     'uri' => '/res/f240bdb3/rsrc/js/javelin/lib/Vector.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-event',
     ),
     'disk' => '/rsrc/js/javelin/lib/Vector.js',
   ),
   'javelin-view' =>
   array(
     'uri' => '/res/b98657a7/rsrc/js/javelin/ext/view/View.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/ext/view/View.js',
   ),
   'javelin-view-html' =>
   array(
     'uri' => '/res/7e5a2122/rsrc/js/javelin/ext/view/HTMLView.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
     ),
     'disk' => '/rsrc/js/javelin/ext/view/HTMLView.js',
   ),
   'javelin-view-interpreter' =>
   array(
     'uri' => '/res/17e911ca/rsrc/js/javelin/ext/view/ViewInterpreter.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-view',
       1 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/javelin/ext/view/ViewInterpreter.js',
   ),
   'javelin-view-renderer' =>
   array(
     'uri' => '/res/db4ed5a2/rsrc/js/javelin/ext/view/ViewRenderer.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/javelin/ext/view/ViewRenderer.js',
   ),
   'javelin-view-visitor' =>
   array(
     'uri' => '/res/0ef9dc43/rsrc/js/javelin/ext/view/ViewVisitor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/javelin/ext/view/ViewVisitor.js',
   ),
   'javelin-workflow' =>
   array(
     'uri' => '/res/1535e366/rsrc/js/javelin/lib/Workflow.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-stratcom',
       1 => 'javelin-request',
       2 => 'javelin-dom',
       3 => 'javelin-vector',
       4 => 'javelin-install',
       5 => 'javelin-util',
       6 => 'javelin-mask',
       7 => 'javelin-uri',
     ),
     'disk' => '/rsrc/js/javelin/lib/Workflow.js',
   ),
   'lightbox-attachment-css' =>
   array(
     'uri' => '/res/4657e15d/rsrc/css/aphront/lightbox-attachment.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/lightbox-attachment.css',
   ),
   'maniphest-batch-editor' =>
   array(
     'uri' => '/res/fb15d744/rsrc/css/application/maniphest/batch-editor.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/maniphest/batch-editor.css',
   ),
   'maniphest-report-css' =>
   array(
     'uri' => '/res/2e633fcf/rsrc/css/application/maniphest/report.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/maniphest/report.css',
   ),
   'maniphest-task-edit-css' =>
   array(
     'uri' => '/res/68c7863e/rsrc/css/application/maniphest/task-edit.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/maniphest/task-edit.css',
   ),
   'maniphest-task-summary-css' =>
   array(
     'uri' => '/res/b3930263/rsrc/css/application/maniphest/task-summary.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/maniphest/task-summary.css',
   ),
   'maniphest-transaction-detail-css' =>
   array(
     'uri' => '/res/fb430d3e/rsrc/css/application/maniphest/transaction-detail.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/maniphest/transaction-detail.css',
   ),
   'multirow-row-manager' =>
   array(
     'uri' => '/res/0a9b3dee/rsrc/js/application/core/MultirowRowManager.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-stratcom',
       2 => 'javelin-dom',
       3 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/application/core/MultirowRowManager.js',
   ),
   'owners-path-editor' =>
   array(
     'uri' => '/res/29b68354/rsrc/js/application/owners/OwnersPathEditor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'multirow-row-manager',
       1 => 'javelin-install',
       2 => 'path-typeahead',
       3 => 'javelin-dom',
       4 => 'javelin-util',
       5 => 'phabricator-prefab',
     ),
     'disk' => '/rsrc/js/application/owners/OwnersPathEditor.js',
   ),
   'owners-path-editor-css' =>
   array(
     'uri' => '/res/4fcaabf6/rsrc/css/application/owners/owners-path-editor.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/owners/owners-path-editor.css',
   ),
   'paste-css' =>
   array(
-    'uri' => '/res/5081cf13/rsrc/css/application/paste/paste.css',
+    'uri' => '/res/044639be/rsrc/css/application/paste/paste.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/paste/paste.css',
   ),
   'path-typeahead' =>
   array(
     'uri' => '/res/50246fb6/rsrc/js/application/herald/PathTypeahead.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-typeahead',
       2 => 'javelin-dom',
       3 => 'javelin-request',
       4 => 'javelin-typeahead-ondemand-source',
       5 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/application/herald/PathTypeahead.js',
   ),
   'phabricator-action-list-view-css' =>
   array(
     'uri' => '/res/7a67c3b9/rsrc/css/layout/phabricator-action-list-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-action-list-view.css',
   ),
   'phabricator-application-launch-view-css' =>
   array(
     'uri' => '/res/13c3d7f3/rsrc/css/application/base/phabricator-application-launch-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/base/phabricator-application-launch-view.css',
   ),
   'phabricator-busy' =>
   array(
     'uri' => '/res/6ec372e1/rsrc/js/application/core/Busy.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/Busy.js',
   ),
   'phabricator-chatlog-css' =>
   array(
     'uri' => '/res/f6631adc/rsrc/css/application/chatlog/chatlog.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/chatlog/chatlog.css',
   ),
   'phabricator-content-source-view-css' =>
   array(
     'uri' => '/res/8c738a93/rsrc/css/application/contentsource/content-source-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/contentsource/content-source-view.css',
   ),
   'phabricator-core-buttons-css' =>
   array(
     'uri' => '/res/4e6b94c8/rsrc/css/core/buttons.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/core/buttons.css',
   ),
   'phabricator-core-css' =>
   array(
     'uri' => '/res/9df0488c/rsrc/css/core/core.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/core/core.css',
   ),
   'phabricator-countdown-css' =>
   array(
     'uri' => '/res/0f646281/rsrc/css/application/countdown/timer.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/countdown/timer.css',
   ),
   'phabricator-crumbs-view-css' =>
   array(
     'uri' => '/res/69fdba64/rsrc/css/layout/phabricator-crumbs-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-crumbs-view.css',
   ),
   'phabricator-directory-css' =>
   array(
     'uri' => '/res/61afca2b/rsrc/css/application/directory/phabricator-directory.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/directory/phabricator-directory.css',
   ),
   'phabricator-drag-and-drop-file-upload' =>
   array(
     'uri' => '/res/ce71f19a/rsrc/js/application/core/DragAndDropFileUpload.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-request',
       3 => 'javelin-dom',
       4 => 'javelin-uri',
       5 => 'phabricator-file-upload',
     ),
     'disk' => '/rsrc/js/application/core/DragAndDropFileUpload.js',
   ),
   'phabricator-dropdown-menu' =>
   array(
     'uri' => '/res/2b4aa4d8/rsrc/js/application/core/DropdownMenu.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-dom',
       3 => 'javelin-vector',
       4 => 'javelin-stratcom',
       5 => 'phabricator-menu-item',
     ),
     'disk' => '/rsrc/js/application/core/DropdownMenu.js',
   ),
   'phabricator-fatal-config-template-css' =>
   array(
     'uri' => '/res/6e1a8d22/rsrc/css/application/config/config-template.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/config/config-template.css',
   ),
   'phabricator-feed-css' =>
   array(
     'uri' => '/res/94a04b24/rsrc/css/application/feed/feed.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/feed/feed.css',
   ),
   'phabricator-file-upload' =>
   array(
     'uri' => '/res/2de10295/rsrc/js/application/core/FileUpload.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-dom',
       2 => 'phabricator-notification',
     ),
     'disk' => '/rsrc/js/application/core/FileUpload.js',
   ),
   'phabricator-filetree-view-css' =>
   array(
     'uri' => '/res/c912ed91/rsrc/css/layout/phabricator-filetree-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-filetree-view.css',
   ),
   'phabricator-flag-css' =>
   array(
     'uri' => '/res/2eee890a/rsrc/css/application/flag/flag.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/flag/flag.css',
   ),
   'phabricator-form-view-css' =>
   array(
     'uri' => '/res/676b1ad2/rsrc/css/layout/phabricator-form-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-form-view.css',
   ),
   'phabricator-header-view-css' =>
   array(
     'uri' => '/res/585b771c/rsrc/css/layout/phabricator-header-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-header-view.css',
   ),
   'phabricator-jump-nav' =>
   array(
     'uri' => '/res/2e0e2211/rsrc/css/application/directory/phabricator-jump-nav.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/directory/phabricator-jump-nav.css',
   ),
   'phabricator-keyboard-shortcut' =>
   array(
     'uri' => '/res/beed38cd/rsrc/js/application/core/KeyboardShortcut.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'phabricator-keyboard-shortcut-manager',
     ),
     'disk' => '/rsrc/js/application/core/KeyboardShortcut.js',
   ),
   'phabricator-keyboard-shortcut-manager' =>
   array(
     'uri' => '/res/d0bee7c7/rsrc/js/application/core/KeyboardShortcutManager.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-stratcom',
       3 => 'javelin-dom',
       4 => 'javelin-vector',
     ),
     'disk' => '/rsrc/js/application/core/KeyboardShortcutManager.js',
   ),
   'phabricator-main-menu-view' =>
   array(
     'uri' => '/res/c1a73bc2/rsrc/css/application/base/main-menu-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/base/main-menu-view.css',
   ),
   'phabricator-menu-item' =>
   array(
     'uri' => '/res/32fc2325/rsrc/js/application/core/DropdownMenuItem.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/DropdownMenuItem.js',
   ),
   'phabricator-nav-view-css' =>
   array(
     'uri' => '/res/f3c78a53/rsrc/css/aphront/phabricator-nav-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/phabricator-nav-view.css',
   ),
   'phabricator-notification' =>
   array(
     'uri' => '/res/ad727561/rsrc/js/application/core/Notification.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
       3 => 'javelin-util',
       4 => 'phabricator-notification-css',
     ),
     'disk' => '/rsrc/js/application/core/Notification.js',
   ),
   'phabricator-notification-css' =>
   array(
     'uri' => '/res/664b9bec/rsrc/css/aphront/notification.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/notification.css',
   ),
   'phabricator-notification-menu-css' =>
   array(
     'uri' => '/res/b7cc25af/rsrc/css/application/base/notification-menu.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/base/notification-menu.css',
   ),
   'phabricator-object-item-list-view-css' =>
   array(
     'uri' => '/res/3fed6faf/rsrc/css/layout/phabricator-object-item-list-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-object-item-list-view.css',
   ),
   'phabricator-object-list-view-css' =>
   array(
     'uri' => '/res/4f183668/rsrc/css/application/projects/phabricator-object-list-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/projects/phabricator-object-list-view.css',
   ),
   'phabricator-object-selector-css' =>
   array(
     'uri' => '/res/7eb4c705/rsrc/css/application/objectselector/object-selector.css',
     'type' => 'css',
     'requires' =>
     array(
       0 => 'aphront-dialog-view-css',
     ),
     'disk' => '/rsrc/css/application/objectselector/object-selector.css',
   ),
   'phabricator-paste-file-upload' =>
   array(
     'uri' => '/res/b0b8afd8/rsrc/js/application/core/PasteFileUpload.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-request',
       3 => 'javelin-dom',
       4 => 'javelin-uri',
     ),
     'disk' => '/rsrc/js/application/core/PasteFileUpload.js',
   ),
   'phabricator-pinboard-view-css' =>
   array(
     'uri' => '/res/61ecd7cf/rsrc/css/layout/phabricator-pinboard-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-pinboard-view.css',
   ),
   'phabricator-prefab' =>
   array(
     'uri' => '/res/2734e45f/rsrc/js/application/core/Prefab.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-dom',
       3 => 'javelin-typeahead',
       4 => 'javelin-tokenizer',
       5 => 'javelin-typeahead-preloaded-source',
       6 => 'javelin-typeahead-ondemand-source',
       7 => 'javelin-dom',
       8 => 'javelin-stratcom',
       9 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/application/core/Prefab.js',
   ),
   'phabricator-profile-css' =>
   array(
     'uri' => '/res/9869d10b/rsrc/css/application/profile/profile-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/profile/profile-view.css',
   ),
   'phabricator-profile-header-css' =>
   array(
     'uri' => '/res/4b1cb23b/rsrc/css/application/profile/profile-header-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/profile/profile-header-view.css',
   ),
   'phabricator-project-tag-css' =>
   array(
     'uri' => '/res/1b5efcb2/rsrc/css/application/projects/project-tag.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/projects/project-tag.css',
   ),
   'phabricator-property-list-view-css' =>
   array(
     'uri' => '/res/a04cc81d/rsrc/css/layout/phabricator-property-list-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-property-list-view.css',
   ),
   'phabricator-remarkup-css' =>
   array(
     'uri' => '/res/4265a372/rsrc/css/core/remarkup.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/core/remarkup.css',
   ),
   'phabricator-search-results-css' =>
   array(
     'uri' => '/res/f8a86e27/rsrc/css/application/search/search-results.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/search/search-results.css',
   ),
   'phabricator-shaped-request' =>
   array(
     'uri' => '/res/fbdb92db/rsrc/js/application/core/ShapedRequest.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-request',
     ),
     'disk' => '/rsrc/js/application/core/ShapedRequest.js',
   ),
   'phabricator-side-menu-view-css' =>
   array(
     'uri' => '/res/28a1e092/rsrc/css/layout/phabricator-side-menu-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-side-menu-view.css',
   ),
   'phabricator-slowvote-css' =>
   array(
     'uri' => '/res/94d20443/rsrc/css/application/slowvote/slowvote.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/slowvote/slowvote.css',
   ),
   'phabricator-source-code-view-css' =>
   array(
-    'uri' => '/res/9373e769/rsrc/css/layout/phabricator-source-code-view.css',
+    'uri' => '/res/979d5280/rsrc/css/layout/phabricator-source-code-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-source-code-view.css',
   ),
   'phabricator-standard-page-view' =>
   array(
     'uri' => '/res/70fa2da4/rsrc/css/application/base/standard-page-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/base/standard-page-view.css',
   ),
   'phabricator-tag-view-css' =>
   array(
     'uri' => '/res/e10bf844/rsrc/css/layout/phabricator-tag-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-tag-view.css',
   ),
   'phabricator-textareautils' =>
   array(
     'uri' => '/res/703614ea/rsrc/js/application/core/TextAreaUtils.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/application/core/TextAreaUtils.js',
   ),
   'phabricator-timeline-view-css' =>
   array(
     'uri' => '/res/5517bf1a/rsrc/css/layout/phabricator-timeline-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/layout/phabricator-timeline-view.css',
   ),
   'phabricator-tooltip' =>
   array(
     'uri' => '/res/55d76b9b/rsrc/js/application/core/ToolTip.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-dom',
       3 => 'javelin-vector',
     ),
     'disk' => '/rsrc/js/application/core/ToolTip.js',
   ),
   'phabricator-transaction-view-css' =>
   array(
     'uri' => '/res/00be4b1a/rsrc/css/aphront/transaction.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/transaction.css',
   ),
   'phabricator-ui-example-css' =>
   array(
     'uri' => '/res/376ab671/rsrc/css/application/uiexample/example.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/uiexample/example.css',
   ),
   'phabricator-uiexample-javelin-view' =>
   array(
     'uri' => '/res/a2ce2cfc/rsrc/js/application/uiexample/JavelinViewExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/JavelinViewExample.js',
   ),
   'phabricator-uiexample-reactor-button' =>
   array(
     'uri' => '/res/142127f6/rsrc/js/application/uiexample/ReactorButtonExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-reactor-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/ReactorButtonExample.js',
   ),
   'phabricator-uiexample-reactor-checkbox' =>
   array(
     'uri' => '/res/c75cb9e9/rsrc/js/application/uiexample/ReactorCheckboxExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-reactor-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/ReactorCheckboxExample.js',
   ),
   'phabricator-uiexample-reactor-focus' =>
   array(
     'uri' => '/res/3cc992eb/rsrc/js/application/uiexample/ReactorFocusExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-reactor-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/ReactorFocusExample.js',
   ),
   'phabricator-uiexample-reactor-input' =>
   array(
     'uri' => '/res/4953da16/rsrc/js/application/uiexample/ReactorInputExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-reactor-dom',
       5 => 'javelin-view-html',
       6 => 'javelin-view-interpreter',
       7 => 'javelin-view-renderer',
     ),
     'disk' => '/rsrc/js/application/uiexample/ReactorInputExample.js',
   ),
   'phabricator-uiexample-reactor-mouseover' =>
   array(
     'uri' => '/res/52a355b6/rsrc/js/application/uiexample/ReactorMouseoverExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-reactor-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/ReactorMouseoverExample.js',
   ),
   'phabricator-uiexample-reactor-radio' =>
   array(
     'uri' => '/res/ae87f3af/rsrc/js/application/uiexample/ReactorRadioExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-reactor-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/ReactorRadioExample.js',
   ),
   'phabricator-uiexample-reactor-select' =>
   array(
     'uri' => '/res/23cb448a/rsrc/js/application/uiexample/ReactorSelectExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-reactor-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/ReactorSelectExample.js',
   ),
   'phabricator-uiexample-reactor-sendclass' =>
   array(
     'uri' => '/res/8cd34264/rsrc/js/application/uiexample/ReactorSendClassExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-reactor-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/ReactorSendClassExample.js',
   ),
   'phabricator-uiexample-reactor-sendproperties' =>
   array(
     'uri' => '/res/18af54aa/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-view',
       2 => 'javelin-util',
       3 => 'javelin-dom',
       4 => 'javelin-reactor-dom',
     ),
     'disk' => '/rsrc/js/application/uiexample/ReactorSendPropertiesExample.js',
   ),
   'phabricator-zindex-css' =>
   array(
     'uri' => '/res/fcbf82ad/rsrc/css/core/z-index.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/core/z-index.css',
   ),
   'phame-css' =>
   array(
     'uri' => '/res/8e3edb71/rsrc/css/application/phame/phame.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/phame/phame.css',
   ),
   'pholio-css' =>
   array(
-    'uri' => '/res/bc10bf21/rsrc/css/application/pholio/pholio.css',
+    'uri' => '/res/b0947e46/rsrc/css/application/pholio/pholio.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/pholio/pholio.css',
   ),
   'pholio-inline-comments-css' =>
   array(
     'uri' => '/res/8fe0edc7/rsrc/css/application/pholio/pholio-inline-comments.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/pholio/pholio-inline-comments.css',
   ),
   'phriction-document-css' =>
   array(
     'uri' => '/res/8d09bd7f/rsrc/css/application/phriction/phriction-document-css.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/phriction/phriction-document-css.css',
   ),
   'ponder-comment-table-css' =>
   array(
     'uri' => '/res/a1bb9056/rsrc/css/application/ponder/comments.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/ponder/comments.css',
   ),
   'ponder-core-view-css' =>
   array(
     'uri' => '/res/3a2d5e18/rsrc/css/application/ponder/core.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/ponder/core.css',
   ),
   'ponder-feed-view-css' =>
   array(
     'uri' => '/res/df22bd20/rsrc/css/application/ponder/feed.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/ponder/feed.css',
   ),
   'ponder-post-css' =>
   array(
     'uri' => '/res/013b9e2c/rsrc/css/application/ponder/post.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/ponder/post.css',
   ),
   'ponder-vote-css' =>
   array(
     'uri' => '/res/ea8316c2/rsrc/css/application/ponder/vote.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/ponder/vote.css',
   ),
   'raphael-core' =>
   array(
     'uri' => '/res/3f48575a/rsrc/js/raphael/raphael.js',
     'type' => 'js',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/js/raphael/raphael.js',
   ),
   'raphael-g' =>
   array(
     'uri' => '/res/b07e5245/rsrc/js/raphael/g.raphael.js',
     'type' => 'js',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/js/raphael/g.raphael.js',
   ),
   'raphael-g-line' =>
   array(
     'uri' => '/res/a59c8556/rsrc/js/raphael/g.raphael.line.js',
     'type' => 'js',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/js/raphael/g.raphael.line.js',
   ),
+  'releeph-branch' =>
+  array(
+    'uri' => '/res/6ad6420d/rsrc/css/application/releeph/releeph-branch.css',
+    'type' => 'css',
+    'requires' =>
+    array(
+    ),
+    'disk' => '/rsrc/css/application/releeph/releeph-branch.css',
+  ),
+  'releeph-colors' =>
+  array(
+    'uri' => '/res/dff4b26a/rsrc/css/application/releeph/releeph-colors.css',
+    'type' => 'css',
+    'requires' =>
+    array(
+    ),
+    'disk' => '/rsrc/css/application/releeph/releeph-colors.css',
+  ),
+  'releeph-core' =>
+  array(
+    'uri' => '/res/853f4a73/rsrc/css/application/releeph/releeph-core.css',
+    'type' => 'css',
+    'requires' =>
+    array(
+    ),
+    'disk' => '/rsrc/css/application/releeph/releeph-core.css',
+  ),
+  'releeph-intents' =>
+  array(
+    'uri' => '/res/4e73e9dd/rsrc/css/application/releeph/releeph-intents.css',
+    'type' => 'css',
+    'requires' =>
+    array(
+    ),
+    'disk' => '/rsrc/css/application/releeph/releeph-intents.css',
+  ),
+  'releeph-preview-branch' =>
+  array(
+    'uri' => '/res/65e5dece/rsrc/css/application/releeph/releeph-preview-branch.css',
+    'type' => 'css',
+    'requires' =>
+    array(
+    ),
+    'disk' => '/rsrc/css/application/releeph/releeph-preview-branch.css',
+  ),
+  'releeph-project' =>
+  array(
+    'uri' => '/res/b9376e59/rsrc/css/application/releeph/releeph-project.css',
+    'type' => 'css',
+    'requires' =>
+    array(
+    ),
+    'disk' => '/rsrc/css/application/releeph/releeph-project.css',
+  ),
+  'releeph-request-differential-create-dialog' =>
+  array(
+    'uri' => '/res/4df30ce1/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css',
+    'type' => 'css',
+    'requires' =>
+    array(
+    ),
+    'disk' => '/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css',
+  ),
+  'releeph-request-typeahead-css' =>
+  array(
+    'uri' => '/res/9c9a1acf/rsrc/css/application/releeph/releeph-request-typeahead.css',
+    'type' => 'css',
+    'requires' =>
+    array(
+    ),
+    'disk' => '/rsrc/css/application/releeph/releeph-request-typeahead.css',
+  ),
+  'releeph-status' =>
+  array(
+    'uri' => '/res/588529df/rsrc/css/application/releeph/releeph-status.css',
+    'type' => 'css',
+    'requires' =>
+    array(
+    ),
+    'disk' => '/rsrc/css/application/releeph/releeph-status.css',
+  ),
   'setup-issue-css' =>
   array(
     'uri' => '/res/efbb3673/rsrc/css/application/config/setup-issue.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/config/setup-issue.css',
   ),
   'sprite-apps-css' =>
   array(
     'uri' => '/res/8de495b4/rsrc/css/sprite-apps.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/sprite-apps.css',
   ),
   'sprite-apps-large-css' =>
   array(
     'uri' => '/res/174143b7/rsrc/css/sprite-apps-large.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/sprite-apps-large.css',
   ),
   'sprite-apps-xlarge-css' =>
   array(
     'uri' => '/res/33a8e644/rsrc/css/sprite-apps-xlarge.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/sprite-apps-xlarge.css',
   ),
   'sprite-conpherence-css' =>
   array(
     'uri' => '/res/f6793453/rsrc/css/sprite-conpherence.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/sprite-conpherence.css',
   ),
   'sprite-docs-css' =>
   array(
     'uri' => '/res/b32f93bc/rsrc/css/sprite-docs.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/sprite-docs.css',
   ),
   'sprite-gradient-css' =>
   array(
     'uri' => '/res/e62e7a0f/rsrc/css/sprite-gradient.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/sprite-gradient.css',
   ),
   'sprite-icon-css' =>
   array(
     'uri' => '/res/e7d63fcf/rsrc/css/sprite-icon.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/sprite-icon.css',
   ),
   'sprite-menu-css' =>
   array(
     'uri' => '/res/50bb9cc5/rsrc/css/sprite-menu.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/sprite-menu.css',
   ),
   'sprite-tokens-css' =>
   array(
     'uri' => '/res/9ae0de5b/rsrc/css/sprite-tokens.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/sprite-tokens.css',
   ),
   'stripe-core' =>
   array(
     'uri' => '/res/3b0f0ad4/rsrc/js/stripe/stripe_core.js',
     'type' => 'js',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/js/stripe/stripe_core.js',
   ),
   'stripe-payment-form-css' =>
   array(
     'uri' => '/res/634a6371/rsrc/css/application/phortune/stripe-payment-form.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/phortune/stripe-payment-form.css',
   ),
   'syntax-highlighting-css' =>
   array(
     'uri' => '/res/cb3b9dc0/rsrc/css/core/syntax.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/core/syntax.css',
   ),
   'tokens-css' =>
   array(
     'uri' => '/res/6b3c65c7/rsrc/css/application/tokens/tokens.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/tokens/tokens.css',
   ),
 ), array(
   'packages' =>
   array(
     '7cb09b8b' =>
     array(
       'name' => 'core.pkg.css',
       'symbols' =>
       array(
         0 => 'phabricator-core-css',
         1 => 'phabricator-zindex-css',
         2 => 'phabricator-core-buttons-css',
         3 => 'phabricator-standard-page-view',
         4 => 'aphront-dialog-view-css',
         5 => 'aphront-form-view-css',
         6 => 'aphront-panel-view-css',
         7 => 'aphront-table-view-css',
         8 => 'aphront-tokenizer-control-css',
         9 => 'aphront-typeahead-control-css',
         10 => 'aphront-list-filter-view-css',
         11 => 'phabricator-directory-css',
         12 => 'phabricator-jump-nav',
         13 => 'phabricator-remarkup-css',
         14 => 'syntax-highlighting-css',
         15 => 'aphront-pager-view-css',
         16 => 'phabricator-transaction-view-css',
         17 => 'aphront-tooltip-css',
         18 => 'phabricator-flag-css',
         19 => 'aphront-error-view-css',
         20 => 'sprite-icon-css',
         21 => 'sprite-gradient-css',
         22 => 'sprite-menu-css',
         23 => 'sprite-apps-large-css',
         24 => 'phabricator-main-menu-view',
         25 => 'phabricator-notification-css',
         26 => 'phabricator-notification-menu-css',
         27 => 'lightbox-attachment-css',
         28 => 'phabricator-header-view-css',
         29 => 'phabricator-form-view-css',
         30 => 'phabricator-filetree-view-css',
         31 => 'phabricator-nav-view-css',
         32 => 'phabricator-side-menu-view-css',
         33 => 'phabricator-crumbs-view-css',
         34 => 'phabricator-object-item-list-view-css',
         35 => 'global-drag-and-drop-css',
       ),
       'uri' => '/res/pkg/7cb09b8b/core.pkg.css',
       'type' => 'css',
     ),
     '95ceba95' =>
     array(
       'name' => 'core.pkg.js',
       'symbols' =>
       array(
         0 => 'javelin-behavior-aphront-basic-tokenizer',
         1 => 'javelin-behavior-workflow',
         2 => 'javelin-behavior-aphront-form-disable-on-submit',
         3 => 'phabricator-keyboard-shortcut-manager',
         4 => 'phabricator-keyboard-shortcut',
         5 => 'javelin-behavior-phabricator-keyboard-shortcuts',
         6 => 'javelin-behavior-refresh-csrf',
         7 => 'javelin-behavior-phabricator-watch-anchor',
         8 => 'javelin-behavior-phabricator-autofocus',
         9 => 'phabricator-paste-file-upload',
         10 => 'phabricator-menu-item',
         11 => 'phabricator-dropdown-menu',
         12 => 'javelin-behavior-phabricator-oncopy',
         13 => 'phabricator-tooltip',
         14 => 'javelin-behavior-phabricator-tooltips',
         15 => 'phabricator-prefab',
         16 => 'javelin-behavior-device',
         17 => 'javelin-behavior-toggle-class',
         18 => 'javelin-behavior-lightbox-attachments',
         19 => 'phabricator-busy',
         20 => 'javelin-aphlict',
         21 => 'phabricator-notification',
         22 => 'javelin-behavior-aphlict-listen',
         23 => 'javelin-behavior-phabricator-search-typeahead',
         24 => 'javelin-behavior-konami',
         25 => 'javelin-behavior-aphlict-dropdown',
         26 => 'javelin-behavior-history-install',
         27 => 'javelin-behavior-phabricator-gesture',
         28 => 'javelin-behavior-phabricator-active-nav',
         29 => 'javelin-behavior-phabricator-nav',
         30 => 'javelin-behavior-phabricator-remarkup-assist',
         31 => 'phabricator-textareautils',
         32 => 'phabricator-file-upload',
         33 => 'javelin-behavior-global-drag-and-drop',
         34 => 'javelin-behavior-phabricator-reveal-content',
       ),
       'uri' => '/res/pkg/95ceba95/core.pkg.js',
       'type' => 'js',
     ),
     'dca4a03d' =>
     array(
       'name' => 'darkconsole.pkg.js',
       'symbols' =>
       array(
         0 => 'javelin-behavior-dark-console',
         1 => 'javelin-behavior-error-log',
       ),
       'uri' => '/res/pkg/dca4a03d/darkconsole.pkg.js',
       'type' => 'js',
     ),
     '8aaacd1b' =>
     array(
       'name' => 'differential.pkg.css',
       'symbols' =>
       array(
         0 => 'differential-core-view-css',
         1 => 'differential-changeset-view-css',
         2 => 'differential-results-table-css',
         3 => 'differential-revision-history-css',
         4 => 'differential-revision-list-css',
         5 => 'differential-table-of-contents-css',
         6 => 'differential-revision-comment-css',
         7 => 'differential-revision-add-comment-css',
         8 => 'differential-revision-comment-list-css',
         9 => 'phabricator-object-selector-css',
         10 => 'phabricator-content-source-view-css',
         11 => 'differential-local-commits-view-css',
         12 => 'inline-comment-summary-css',
       ),
       'uri' => '/res/pkg/8aaacd1b/differential.pkg.css',
       'type' => 'css',
     ),
     '322728f3' =>
     array(
       'name' => 'differential.pkg.js',
       'symbols' =>
       array(
         0 => 'phabricator-drag-and-drop-file-upload',
         1 => 'phabricator-shaped-request',
         2 => 'javelin-behavior-differential-feedback-preview',
         3 => 'javelin-behavior-differential-edit-inline-comments',
         4 => 'javelin-behavior-differential-populate',
         5 => 'javelin-behavior-differential-show-more',
         6 => 'javelin-behavior-differential-diff-radios',
         7 => 'javelin-behavior-differential-accept-with-errors',
         8 => 'javelin-behavior-differential-comment-jump',
         9 => 'javelin-behavior-differential-add-reviewers-and-ccs',
         10 => 'javelin-behavior-differential-keyboard-navigation',
         11 => 'javelin-behavior-aphront-drag-and-drop',
         12 => 'javelin-behavior-aphront-drag-and-drop-textarea',
         13 => 'javelin-behavior-phabricator-object-selector',
         14 => 'javelin-behavior-repository-crossreference',
         15 => 'javelin-behavior-load-blame',
         16 => 'differential-inline-comment-editor',
         17 => 'javelin-behavior-differential-dropdown-menus',
         18 => 'javelin-behavior-differential-toggle-files',
         19 => 'javelin-behavior-differential-user-select',
       ),
       'uri' => '/res/pkg/322728f3/differential.pkg.js',
       'type' => 'js',
     ),
     'c8ce2d88' =>
     array(
       'name' => 'diffusion.pkg.css',
       'symbols' =>
       array(
         0 => 'diffusion-commit-view-css',
         1 => 'diffusion-icons-css',
       ),
       'uri' => '/res/pkg/c8ce2d88/diffusion.pkg.css',
       'type' => 'css',
     ),
     'f96657b8' =>
     array(
       'name' => 'diffusion.pkg.js',
       'symbols' =>
       array(
         0 => 'javelin-behavior-diffusion-pull-lastmodified',
         1 => 'javelin-behavior-diffusion-commit-graph',
         2 => 'javelin-behavior-audit-preview',
       ),
       'uri' => '/res/pkg/f96657b8/diffusion.pkg.js',
       'type' => 'js',
     ),
     'cd1d650a' =>
     array(
       'name' => 'javelin.pkg.js',
       'symbols' =>
       array(
         0 => 'javelin-util',
         1 => 'javelin-install',
         2 => 'javelin-event',
         3 => 'javelin-stratcom',
         4 => 'javelin-behavior',
         5 => 'javelin-resource',
         6 => 'javelin-request',
         7 => 'javelin-vector',
         8 => 'javelin-dom',
         9 => 'javelin-json',
         10 => 'javelin-uri',
         11 => 'javelin-workflow',
         12 => 'javelin-mask',
         13 => 'javelin-typeahead',
         14 => 'javelin-typeahead-normalizer',
         15 => 'javelin-typeahead-source',
         16 => 'javelin-typeahead-preloaded-source',
         17 => 'javelin-typeahead-ondemand-source',
         18 => 'javelin-tokenizer',
       ),
       'uri' => '/res/pkg/cd1d650a/javelin.pkg.js',
       'type' => 'js',
     ),
     'c41b4907' =>
     array(
       'name' => 'maniphest.pkg.css',
       'symbols' =>
       array(
         0 => 'maniphest-task-summary-css',
         1 => 'maniphest-transaction-detail-css',
         2 => 'aphront-attached-file-view-css',
         3 => 'phabricator-project-tag-css',
       ),
       'uri' => '/res/pkg/c41b4907/maniphest.pkg.css',
       'type' => 'css',
     ),
     '7707de41' =>
     array(
       'name' => 'maniphest.pkg.js',
       'symbols' =>
       array(
         0 => 'javelin-behavior-maniphest-batch-selector',
         1 => 'javelin-behavior-maniphest-transaction-controls',
         2 => 'javelin-behavior-maniphest-transaction-preview',
         3 => 'javelin-behavior-maniphest-transaction-expand',
         4 => 'javelin-behavior-maniphest-subpriority-editor',
       ),
       'uri' => '/res/pkg/7707de41/maniphest.pkg.js',
       'type' => 'js',
     ),
   ),
   'reverse' =>
   array(
     'aphront-attached-file-view-css' => 'c41b4907',
     'aphront-dialog-view-css' => '7cb09b8b',
     'aphront-error-view-css' => '7cb09b8b',
     'aphront-form-view-css' => '7cb09b8b',
     'aphront-list-filter-view-css' => '7cb09b8b',
     'aphront-pager-view-css' => '7cb09b8b',
     'aphront-panel-view-css' => '7cb09b8b',
     'aphront-table-view-css' => '7cb09b8b',
     'aphront-tokenizer-control-css' => '7cb09b8b',
     'aphront-tooltip-css' => '7cb09b8b',
     'aphront-typeahead-control-css' => '7cb09b8b',
     'differential-changeset-view-css' => '8aaacd1b',
     'differential-core-view-css' => '8aaacd1b',
     'differential-inline-comment-editor' => '322728f3',
     'differential-local-commits-view-css' => '8aaacd1b',
     'differential-results-table-css' => '8aaacd1b',
     'differential-revision-add-comment-css' => '8aaacd1b',
     'differential-revision-comment-css' => '8aaacd1b',
     'differential-revision-comment-list-css' => '8aaacd1b',
     'differential-revision-history-css' => '8aaacd1b',
     'differential-revision-list-css' => '8aaacd1b',
     'differential-table-of-contents-css' => '8aaacd1b',
     'diffusion-commit-view-css' => 'c8ce2d88',
     'diffusion-icons-css' => 'c8ce2d88',
     'global-drag-and-drop-css' => '7cb09b8b',
     'inline-comment-summary-css' => '8aaacd1b',
     'javelin-aphlict' => '95ceba95',
     'javelin-behavior' => 'cd1d650a',
     'javelin-behavior-aphlict-dropdown' => '95ceba95',
     'javelin-behavior-aphlict-listen' => '95ceba95',
     'javelin-behavior-aphront-basic-tokenizer' => '95ceba95',
     'javelin-behavior-aphront-drag-and-drop' => '322728f3',
     'javelin-behavior-aphront-drag-and-drop-textarea' => '322728f3',
     'javelin-behavior-aphront-form-disable-on-submit' => '95ceba95',
     'javelin-behavior-audit-preview' => 'f96657b8',
     'javelin-behavior-dark-console' => 'dca4a03d',
     'javelin-behavior-device' => '95ceba95',
     'javelin-behavior-differential-accept-with-errors' => '322728f3',
     'javelin-behavior-differential-add-reviewers-and-ccs' => '322728f3',
     'javelin-behavior-differential-comment-jump' => '322728f3',
     'javelin-behavior-differential-diff-radios' => '322728f3',
     'javelin-behavior-differential-dropdown-menus' => '322728f3',
     'javelin-behavior-differential-edit-inline-comments' => '322728f3',
     'javelin-behavior-differential-feedback-preview' => '322728f3',
     'javelin-behavior-differential-keyboard-navigation' => '322728f3',
     'javelin-behavior-differential-populate' => '322728f3',
     'javelin-behavior-differential-show-more' => '322728f3',
     'javelin-behavior-differential-toggle-files' => '322728f3',
     'javelin-behavior-differential-user-select' => '322728f3',
     'javelin-behavior-diffusion-commit-graph' => 'f96657b8',
     'javelin-behavior-diffusion-pull-lastmodified' => 'f96657b8',
     'javelin-behavior-error-log' => 'dca4a03d',
     'javelin-behavior-global-drag-and-drop' => '95ceba95',
     'javelin-behavior-history-install' => '95ceba95',
     'javelin-behavior-konami' => '95ceba95',
     'javelin-behavior-lightbox-attachments' => '95ceba95',
     'javelin-behavior-load-blame' => '322728f3',
     'javelin-behavior-maniphest-batch-selector' => '7707de41',
     'javelin-behavior-maniphest-subpriority-editor' => '7707de41',
     'javelin-behavior-maniphest-transaction-controls' => '7707de41',
     'javelin-behavior-maniphest-transaction-expand' => '7707de41',
     'javelin-behavior-maniphest-transaction-preview' => '7707de41',
     'javelin-behavior-phabricator-active-nav' => '95ceba95',
     'javelin-behavior-phabricator-autofocus' => '95ceba95',
     'javelin-behavior-phabricator-gesture' => '95ceba95',
     'javelin-behavior-phabricator-keyboard-shortcuts' => '95ceba95',
     'javelin-behavior-phabricator-nav' => '95ceba95',
     'javelin-behavior-phabricator-object-selector' => '322728f3',
     'javelin-behavior-phabricator-oncopy' => '95ceba95',
     'javelin-behavior-phabricator-remarkup-assist' => '95ceba95',
     'javelin-behavior-phabricator-reveal-content' => '95ceba95',
     'javelin-behavior-phabricator-search-typeahead' => '95ceba95',
     'javelin-behavior-phabricator-tooltips' => '95ceba95',
     'javelin-behavior-phabricator-watch-anchor' => '95ceba95',
     'javelin-behavior-refresh-csrf' => '95ceba95',
     'javelin-behavior-repository-crossreference' => '322728f3',
     'javelin-behavior-toggle-class' => '95ceba95',
     'javelin-behavior-workflow' => '95ceba95',
     'javelin-dom' => 'cd1d650a',
     'javelin-event' => 'cd1d650a',
     'javelin-install' => 'cd1d650a',
     'javelin-json' => 'cd1d650a',
     'javelin-mask' => 'cd1d650a',
     'javelin-request' => 'cd1d650a',
     'javelin-resource' => 'cd1d650a',
     'javelin-stratcom' => 'cd1d650a',
     'javelin-tokenizer' => 'cd1d650a',
     'javelin-typeahead' => 'cd1d650a',
     'javelin-typeahead-normalizer' => 'cd1d650a',
     'javelin-typeahead-ondemand-source' => 'cd1d650a',
     'javelin-typeahead-preloaded-source' => 'cd1d650a',
     'javelin-typeahead-source' => 'cd1d650a',
     'javelin-uri' => 'cd1d650a',
     'javelin-util' => 'cd1d650a',
     'javelin-vector' => 'cd1d650a',
     'javelin-workflow' => 'cd1d650a',
     'lightbox-attachment-css' => '7cb09b8b',
     'maniphest-task-summary-css' => 'c41b4907',
     'maniphest-transaction-detail-css' => 'c41b4907',
     'phabricator-busy' => '95ceba95',
     'phabricator-content-source-view-css' => '8aaacd1b',
     'phabricator-core-buttons-css' => '7cb09b8b',
     'phabricator-core-css' => '7cb09b8b',
     'phabricator-crumbs-view-css' => '7cb09b8b',
     'phabricator-directory-css' => '7cb09b8b',
     'phabricator-drag-and-drop-file-upload' => '322728f3',
     'phabricator-dropdown-menu' => '95ceba95',
     'phabricator-file-upload' => '95ceba95',
     'phabricator-filetree-view-css' => '7cb09b8b',
     'phabricator-flag-css' => '7cb09b8b',
     'phabricator-form-view-css' => '7cb09b8b',
     'phabricator-header-view-css' => '7cb09b8b',
     'phabricator-jump-nav' => '7cb09b8b',
     'phabricator-keyboard-shortcut' => '95ceba95',
     'phabricator-keyboard-shortcut-manager' => '95ceba95',
     'phabricator-main-menu-view' => '7cb09b8b',
     'phabricator-menu-item' => '95ceba95',
     'phabricator-nav-view-css' => '7cb09b8b',
     'phabricator-notification' => '95ceba95',
     'phabricator-notification-css' => '7cb09b8b',
     'phabricator-notification-menu-css' => '7cb09b8b',
     'phabricator-object-item-list-view-css' => '7cb09b8b',
     'phabricator-object-selector-css' => '8aaacd1b',
     'phabricator-paste-file-upload' => '95ceba95',
     'phabricator-prefab' => '95ceba95',
     'phabricator-project-tag-css' => 'c41b4907',
     'phabricator-remarkup-css' => '7cb09b8b',
     'phabricator-shaped-request' => '322728f3',
     'phabricator-side-menu-view-css' => '7cb09b8b',
     'phabricator-standard-page-view' => '7cb09b8b',
     'phabricator-textareautils' => '95ceba95',
     'phabricator-tooltip' => '95ceba95',
     'phabricator-transaction-view-css' => '7cb09b8b',
     'phabricator-zindex-css' => '7cb09b8b',
     'sprite-apps-large-css' => '7cb09b8b',
     'sprite-gradient-css' => '7cb09b8b',
     'sprite-icon-css' => '7cb09b8b',
     'sprite-menu-css' => '7cb09b8b',
     'syntax-highlighting-css' => '7cb09b8b',
   ),
 ));
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index a13b97b6e..f22374905 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,3111 +1,3270 @@
 <?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(
     'Aphront304Response' => 'aphront/response/Aphront304Response.php',
     'Aphront400Response' => 'aphront/response/Aphront400Response.php',
     'Aphront403Response' => 'aphront/response/Aphront403Response.php',
     'Aphront404Response' => 'aphront/response/Aphront404Response.php',
     'AphrontAjaxResponse' => 'aphront/response/AphrontAjaxResponse.php',
     'AphrontApplicationConfiguration' => 'aphront/configuration/AphrontApplicationConfiguration.php',
     'AphrontAttachedFileView' => 'view/control/AphrontAttachedFileView.php',
     'AphrontBarView' => 'view/widget/bars/AphrontBarView.php',
     'AphrontCSRFException' => 'aphront/exception/AphrontCSRFException.php',
     'AphrontCalendarEventView' => 'applications/calendar/view/AphrontCalendarEventView.php',
     'AphrontCalendarMonthView' => 'applications/calendar/view/AphrontCalendarMonthView.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',
     'AphrontFormControl' => 'view/form/control/AphrontFormControl.php',
     'AphrontFormCountedToggleButtonsControl' => 'view/form/control/AphrontFormCountedToggleButtonsControl.php',
     'AphrontFormCropControl' => 'view/form/control/AphrontFormCropControl.php',
     'AphrontFormDateControl' => 'view/form/control/AphrontFormDateControl.php',
     'AphrontFormDividerControl' => 'view/form/control/AphrontFormDividerControl.php',
     'AphrontFormDragAndDropUploadControl' => 'view/form/control/AphrontFormDragAndDropUploadControl.php',
     'AphrontFormFileControl' => 'view/form/control/AphrontFormFileControl.php',
     'AphrontFormImageControl' => 'view/form/control/AphrontFormImageControl.php',
     'AphrontFormInsetView' => 'view/form/AphrontFormInsetView.php',
     'AphrontFormLayoutView' => 'view/form/AphrontFormLayoutView.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',
     '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',
     'AphrontFormToggleButtonsControl' => 'view/form/control/AphrontFormToggleButtonsControl.php',
     'AphrontFormTokenizerControl' => 'view/form/control/AphrontFormTokenizerControl.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',
     'AphrontMySQLDatabaseConnectionTestCase' => 'infrastructure/storage/__tests__/AphrontMySQLDatabaseConnectionTestCase.php',
     'AphrontNoteView' => 'view/widget/AphrontNoteView.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',
     'AphrontRedirectException' => 'aphront/exception/AphrontRedirectException.php',
     'AphrontRedirectResponse' => 'aphront/response/AphrontRedirectResponse.php',
     'AphrontReloadResponse' => 'aphront/response/AphrontReloadResponse.php',
     'AphrontRequest' => 'aphront/AphrontRequest.php',
     'AphrontRequestFailureView' => 'view/page/AphrontRequestFailureView.php',
     'AphrontRequestTestCase' => 'aphront/__tests__/AphrontRequestTestCase.php',
     'AphrontResponse' => 'aphront/response/AphrontResponse.php',
     'AphrontSideNavFilterView' => 'view/layout/AphrontSideNavFilterView.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',
     'AuditPeopleMenuEventListener' => 'applications/audit/events/AuditPeopleMenuEventListener.php',
     'CelerityAPI' => 'infrastructure/celerity/CelerityAPI.php',
     'CelerityPhabricatorResourceController' => 'infrastructure/celerity/CelerityPhabricatorResourceController.php',
     'CelerityResourceController' => 'infrastructure/celerity/CelerityResourceController.php',
     'CelerityResourceGraph' => 'infrastructure/celerity/CelerityResourceGraph.php',
     'CelerityResourceMap' => 'infrastructure/celerity/CelerityResourceMap.php',
     'CelerityResourceTransformer' => 'infrastructure/celerity/CelerityResourceTransformer.php',
     'CelerityResourceTransformerTestCase' => 'infrastructure/celerity/__tests__/CelerityResourceTransformerTestCase.php',
     'CeleritySpriteGenerator' => 'infrastructure/celerity/CeleritySpriteGenerator.php',
     'CelerityStaticResourceResponse' => 'infrastructure/celerity/CelerityStaticResourceResponse.php',
     'ConduitAPIMethod' => 'applications/conduit/method/ConduitAPIMethod.php',
     'ConduitAPIRequest' => 'applications/conduit/protocol/ConduitAPIRequest.php',
     'ConduitAPIResponse' => 'applications/conduit/protocol/ConduitAPIResponse.php',
     'ConduitAPI_arcanist_Method' => 'applications/arcanist/conduit/ConduitAPI_arcanist_Method.php',
     'ConduitAPI_arcanist_projectinfo_Method' => 'applications/arcanist/conduit/ConduitAPI_arcanist_projectinfo_Method.php',
     'ConduitAPI_audit_Method' => 'applications/audit/conduit/ConduitAPI_audit_Method.php',
     'ConduitAPI_audit_query_Method' => 'applications/audit/conduit/ConduitAPI_audit_query_Method.php',
     'ConduitAPI_chatlog_Method' => 'applications/chatlog/conduit/ConduitAPI_chatlog_Method.php',
     'ConduitAPI_chatlog_query_Method' => 'applications/chatlog/conduit/ConduitAPI_chatlog_query_Method.php',
     'ConduitAPI_chatlog_record_Method' => 'applications/chatlog/conduit/ConduitAPI_chatlog_record_Method.php',
     'ConduitAPI_conduit_connect_Method' => 'applications/conduit/method/ConduitAPI_conduit_connect_Method.php',
     'ConduitAPI_conduit_getcertificate_Method' => 'applications/conduit/method/ConduitAPI_conduit_getcertificate_Method.php',
     'ConduitAPI_conduit_ping_Method' => 'applications/conduit/method/ConduitAPI_conduit_ping_Method.php',
     'ConduitAPI_conduit_query_Method' => 'applications/conduit/method/ConduitAPI_conduit_query_Method.php',
     'ConduitAPI_daemon_launched_Method' => 'applications/daemon/conduit/ConduitAPI_daemon_launched_Method.php',
     'ConduitAPI_daemon_log_Method' => 'applications/daemon/conduit/ConduitAPI_daemon_log_Method.php',
     'ConduitAPI_daemon_setstatus_Method' => 'applications/daemon/conduit/ConduitAPI_daemon_setstatus_Method.php',
     'ConduitAPI_differential_Method' => 'applications/differential/conduit/ConduitAPI_differential_Method.php',
     'ConduitAPI_differential_close_Method' => 'applications/differential/conduit/ConduitAPI_differential_close_Method.php',
     'ConduitAPI_differential_createcomment_Method' => 'applications/differential/conduit/ConduitAPI_differential_createcomment_Method.php',
     'ConduitAPI_differential_creatediff_Method' => 'applications/differential/conduit/ConduitAPI_differential_creatediff_Method.php',
     'ConduitAPI_differential_createinline_Method' => 'applications/differential/conduit/ConduitAPI_differential_createinline_Method.php',
     'ConduitAPI_differential_createrawdiff_Method' => 'applications/differential/conduit/ConduitAPI_differential_createrawdiff_Method.php',
     'ConduitAPI_differential_createrevision_Method' => 'applications/differential/conduit/ConduitAPI_differential_createrevision_Method.php',
     'ConduitAPI_differential_find_Method' => 'applications/differential/conduit/ConduitAPI_differential_find_Method.php',
     'ConduitAPI_differential_finishpostponedlinters_Method' => 'applications/differential/conduit/ConduitAPI_differential_finishpostponedlinters_Method.php',
     'ConduitAPI_differential_getalldiffs_Method' => 'applications/differential/conduit/ConduitAPI_differential_getalldiffs_Method.php',
     'ConduitAPI_differential_getcommitmessage_Method' => 'applications/differential/conduit/ConduitAPI_differential_getcommitmessage_Method.php',
     'ConduitAPI_differential_getcommitpaths_Method' => 'applications/differential/conduit/ConduitAPI_differential_getcommitpaths_Method.php',
     'ConduitAPI_differential_getdiff_Method' => 'applications/differential/conduit/ConduitAPI_differential_getdiff_Method.php',
     'ConduitAPI_differential_getrevision_Method' => 'applications/differential/conduit/ConduitAPI_differential_getrevision_Method.php',
     'ConduitAPI_differential_getrevisioncomments_Method' => 'applications/differential/conduit/ConduitAPI_differential_getrevisioncomments_Method.php',
     'ConduitAPI_differential_getrevisionfeedback_Method' => 'applications/differential/conduit/ConduitAPI_differential_getrevisionfeedback_Method.php',
     'ConduitAPI_differential_markcommitted_Method' => 'applications/differential/conduit/ConduitAPI_differential_markcommitted_Method.php',
     'ConduitAPI_differential_parsecommitmessage_Method' => 'applications/differential/conduit/ConduitAPI_differential_parsecommitmessage_Method.php',
     'ConduitAPI_differential_query_Method' => 'applications/differential/conduit/ConduitAPI_differential_query_Method.php',
     'ConduitAPI_differential_setdiffproperty_Method' => 'applications/differential/conduit/ConduitAPI_differential_setdiffproperty_Method.php',
     'ConduitAPI_differential_updaterevision_Method' => 'applications/differential/conduit/ConduitAPI_differential_updaterevision_Method.php',
     'ConduitAPI_differential_updateunitresults_Method' => 'applications/differential/conduit/ConduitAPI_differential_updateunitresults_Method.php',
     'ConduitAPI_diffusion_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_Method.php',
     'ConduitAPI_diffusion_findsymbols_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_findsymbols_Method.php',
     'ConduitAPI_diffusion_getcommits_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_getcommits_Method.php',
     'ConduitAPI_diffusion_getlintmessages_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_getlintmessages_Method.php',
     'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'applications/diffusion/conduit/ConduitAPI_diffusion_getrecentcommitsbypath_Method.php',
     'ConduitAPI_feed_Method' => 'applications/feed/conduit/ConduitAPI_feed_Method.php',
     'ConduitAPI_feed_publish_Method' => 'applications/feed/conduit/ConduitAPI_feed_publish_Method.php',
     'ConduitAPI_feed_query_Method' => 'applications/feed/conduit/ConduitAPI_feed_query_Method.php',
     'ConduitAPI_file_Method' => 'applications/files/conduit/ConduitAPI_file_Method.php',
     'ConduitAPI_file_download_Method' => 'applications/files/conduit/ConduitAPI_file_download_Method.php',
     'ConduitAPI_file_info_Method' => 'applications/files/conduit/ConduitAPI_file_info_Method.php',
     'ConduitAPI_file_upload_Method' => 'applications/files/conduit/ConduitAPI_file_upload_Method.php',
     'ConduitAPI_file_uploadhash_Method' => 'applications/files/conduit/ConduitAPI_file_uploadhash_Method.php',
     'ConduitAPI_flag_Method' => 'applications/flag/conduit/ConduitAPI_flag_Method.php',
     'ConduitAPI_flag_delete_Method' => 'applications/flag/conduit/ConduitAPI_flag_delete_Method.php',
     'ConduitAPI_flag_edit_Method' => 'applications/flag/conduit/ConduitAPI_flag_edit_Method.php',
     'ConduitAPI_flag_query_Method' => 'applications/flag/conduit/ConduitAPI_flag_query_Method.php',
     'ConduitAPI_macro_Method' => 'applications/macro/conduit/ConduitAPI_macro_Method.php',
     'ConduitAPI_macro_query_Method' => 'applications/macro/conduit/ConduitAPI_macro_query_Method.php',
     'ConduitAPI_maniphest_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_Method.php',
     'ConduitAPI_maniphest_createtask_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_createtask_Method.php',
     'ConduitAPI_maniphest_find_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_find_Method.php',
     'ConduitAPI_maniphest_gettasktransactions_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_gettasktransactions_Method.php',
     'ConduitAPI_maniphest_info_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_info_Method.php',
     'ConduitAPI_maniphest_query_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_query_Method.php',
     'ConduitAPI_maniphest_update_Method' => 'applications/maniphest/conduit/ConduitAPI_maniphest_update_Method.php',
     'ConduitAPI_owners_Method' => 'applications/owners/conduit/ConduitAPI_owners_Method.php',
     'ConduitAPI_owners_query_Method' => 'applications/owners/conduit/ConduitAPI_owners_query_Method.php',
     'ConduitAPI_paste_Method' => 'applications/paste/conduit/ConduitAPI_paste_Method.php',
     'ConduitAPI_paste_create_Method' => 'applications/paste/conduit/ConduitAPI_paste_create_Method.php',
     'ConduitAPI_paste_info_Method' => 'applications/paste/conduit/ConduitAPI_paste_info_Method.php',
     'ConduitAPI_paste_query_Method' => 'applications/paste/conduit/ConduitAPI_paste_query_Method.php',
     'ConduitAPI_phid_Method' => 'applications/phid/conduit/ConduitAPI_phid_Method.php',
     'ConduitAPI_phid_info_Method' => 'applications/phid/conduit/ConduitAPI_phid_info_Method.php',
     'ConduitAPI_phid_lookup_Method' => 'applications/phid/conduit/ConduitAPI_phid_lookup_Method.php',
     'ConduitAPI_phid_query_Method' => 'applications/phid/conduit/ConduitAPI_phid_query_Method.php',
     'ConduitAPI_phpast_Method' => 'applications/phpast/conduit/ConduitAPI_phpast_Method.php',
     'ConduitAPI_phpast_getast_Method' => 'applications/phpast/conduit/ConduitAPI_phpast_getast_Method.php',
     'ConduitAPI_phpast_version_Method' => 'applications/phpast/conduit/ConduitAPI_phpast_version_Method.php',
     'ConduitAPI_phriction_Method' => 'applications/phriction/conduit/ConduitAPI_phriction_Method.php',
     'ConduitAPI_phriction_edit_Method' => 'applications/phriction/conduit/ConduitAPI_phriction_edit_Method.php',
     'ConduitAPI_phriction_history_Method' => 'applications/phriction/conduit/ConduitAPI_phriction_history_Method.php',
     'ConduitAPI_phriction_info_Method' => 'applications/phriction/conduit/ConduitAPI_phriction_info_Method.php',
     'ConduitAPI_project_Method' => 'applications/project/conduit/ConduitAPI_project_Method.php',
     'ConduitAPI_project_query_Method' => 'applications/project/conduit/ConduitAPI_project_query_Method.php',
+    'ConduitAPI_releeph_Method' => 'applications/releeph/conduit/ConduitAPI_releeph_Method.php',
+    'ConduitAPI_releeph_getbranches_Method' => 'applications/releeph/conduit/ConduitAPI_releeph_getbranches_Method.php',
+    'ConduitAPI_releeph_projectinfo_Method' => 'applications/releeph/conduit/ConduitAPI_releeph_projectinfo_Method.php',
+    'ConduitAPI_releeph_request_Method' => 'applications/releeph/conduit/ConduitAPI_releeph_request_Method.php',
+    'ConduitAPI_releephwork_canpush_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_canpush_Method.php',
+    'ConduitAPI_releephwork_getauthorinfo_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getauthorinfo_Method.php',
+    'ConduitAPI_releephwork_getbranch_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getbranch_Method.php',
+    'ConduitAPI_releephwork_getbranchcommitmessage_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getbranchcommitmessage_Method.php',
+    'ConduitAPI_releephwork_getcommitmessage_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php',
+    'ConduitAPI_releephwork_getorigcommitmessage_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_getorigcommitmessage_Method.php',
+    'ConduitAPI_releephwork_nextrequest_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php',
+    'ConduitAPI_releephwork_record_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php',
+    'ConduitAPI_releephwork_recordpickstatus_Method' => 'applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php',
     'ConduitAPI_remarkup_process_Method' => 'applications/remarkup/conduit/ConduitAPI_remarkup_process_Method.php',
     'ConduitAPI_repository_Method' => 'applications/repository/conduit/ConduitAPI_repository_Method.php',
     'ConduitAPI_repository_create_Method' => 'applications/repository/conduit/ConduitAPI_repository_create_Method.php',
     'ConduitAPI_repository_query_Method' => 'applications/repository/conduit/ConduitAPI_repository_query_Method.php',
     'ConduitAPI_slowvote_Method' => 'applications/slowvote/conduit/ConduitAPI_slowvote_Method.php',
     'ConduitAPI_slowvote_info_Method' => 'applications/slowvote/conduit/ConduitAPI_slowvote_info_Method.php',
     'ConduitAPI_token_Method' => 'applications/tokens/conduit/ConduitAPI_token_Method.php',
     'ConduitAPI_token_give_Method' => 'applications/tokens/conduit/ConduitAPI_token_give_Method.php',
     'ConduitAPI_token_given_Method' => 'applications/tokens/conduit/ConduitAPI_token_given_Method.php',
     'ConduitAPI_token_query_Method' => 'applications/tokens/conduit/ConduitAPI_token_query_Method.php',
     'ConduitAPI_user_Method' => 'applications/people/conduit/ConduitAPI_user_Method.php',
     'ConduitAPI_user_addstatus_Method' => 'applications/people/conduit/ConduitAPI_user_addstatus_Method.php',
     'ConduitAPI_user_disable_Method' => 'applications/people/conduit/ConduitAPI_user_disable_Method.php',
     'ConduitAPI_user_enable_Method' => 'applications/people/conduit/ConduitAPI_user_enable_Method.php',
     'ConduitAPI_user_find_Method' => 'applications/people/conduit/ConduitAPI_user_find_Method.php',
     'ConduitAPI_user_info_Method' => 'applications/people/conduit/ConduitAPI_user_info_Method.php',
     'ConduitAPI_user_query_Method' => 'applications/people/conduit/ConduitAPI_user_query_Method.php',
     'ConduitAPI_user_removestatus_Method' => 'applications/people/conduit/ConduitAPI_user_removestatus_Method.php',
     'ConduitAPI_user_whoami_Method' => 'applications/people/conduit/ConduitAPI_user_whoami_Method.php',
     'ConduitCall' => 'applications/conduit/call/ConduitCall.php',
     'ConduitCallTestCase' => 'applications/conduit/call/__tests__/ConduitCallTestCase.php',
     'ConduitException' => 'applications/conduit/protocol/ConduitException.php',
     'ConduitSSHWorkflow' => 'applications/conduit/ssh/ConduitSSHWorkflow.php',
     'ConpherenceConfigOptions' => 'applications/conpherence/config/ConpherenceConfigOptions.php',
     'ConpherenceConstants' => 'applications/conpherence/constants/ConpherenceConstants.php',
     'ConpherenceController' => 'applications/conpherence/controller/ConpherenceController.php',
     'ConpherenceDAO' => 'applications/conpherence/storage/ConpherenceDAO.php',
     'ConpherenceEditor' => 'applications/conpherence/editor/ConpherenceEditor.php',
     'ConpherenceFileWidgetView' => 'applications/conpherence/view/ConpherenceFileWidgetView.php',
     'ConpherenceFormDragAndDropUploadControl' => 'applications/conpherence/view/ConpherenceFormDragAndDropUploadControl.php',
     'ConpherenceImageData' => 'applications/conpherence/constants/ConpherenceImageData.php',
     'ConpherenceListController' => 'applications/conpherence/controller/ConpherenceListController.php',
     'ConpherenceMenuItemView' => 'applications/conpherence/view/ConpherenceMenuItemView.php',
     'ConpherenceNewController' => 'applications/conpherence/controller/ConpherenceNewController.php',
     'ConpherenceParticipant' => 'applications/conpherence/storage/ConpherenceParticipant.php',
     'ConpherenceParticipantQuery' => 'applications/conpherence/query/ConpherenceParticipantQuery.php',
     'ConpherenceParticipationStatus' => 'applications/conpherence/constants/ConpherenceParticipationStatus.php',
     'ConpherencePeopleMenuEventListener' => 'applications/conpherence/events/ConpherencePeopleMenuEventListener.php',
     'ConpherencePontificateControl' => 'applications/conpherence/view/ConpherencePontificateControl.php',
     'ConpherenceReplyHandler' => 'applications/conpherence/mail/ConpherenceReplyHandler.php',
     'ConpherenceThread' => 'applications/conpherence/storage/ConpherenceThread.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',
     'ConpherenceUpdateController' => 'applications/conpherence/controller/ConpherenceUpdateController.php',
     'ConpherenceViewController' => 'applications/conpherence/controller/ConpherenceViewController.php',
     'ConpherenceWidgetController' => 'applications/conpherence/controller/ConpherenceWidgetController.php',
     'DarkConsoleController' => 'aphront/console/DarkConsoleController.php',
     'DarkConsoleCore' => 'aphront/console/DarkConsoleCore.php',
     'DarkConsoleDataController' => 'aphront/console/DarkConsoleDataController.php',
     'DarkConsoleErrorLogPlugin' => 'aphront/console/plugin/DarkConsoleErrorLogPlugin.php',
     'DarkConsoleErrorLogPluginAPI' => 'aphront/console/plugin/errorlog/DarkConsoleErrorLogPluginAPI.php',
     'DarkConsoleEventPlugin' => 'aphront/console/plugin/DarkConsoleEventPlugin.php',
     'DarkConsoleEventPluginAPI' => 'aphront/console/plugin/event/DarkConsoleEventPluginAPI.php',
     'DarkConsolePlugin' => 'aphront/console/plugin/DarkConsolePlugin.php',
     'DarkConsoleRequestPlugin' => 'aphront/console/plugin/DarkConsoleRequestPlugin.php',
     'DarkConsoleServicesPlugin' => 'aphront/console/plugin/DarkConsoleServicesPlugin.php',
     'DarkConsoleXHProfPlugin' => 'aphront/console/plugin/DarkConsoleXHProfPlugin.php',
     'DarkConsoleXHProfPluginAPI' => 'aphront/console/plugin/xhprof/DarkConsoleXHProfPluginAPI.php',
     'DatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DatabaseConfigurationProvider.php',
     'DefaultDatabaseConfigurationProvider' => 'infrastructure/storage/configuration/DefaultDatabaseConfigurationProvider.php',
     'DifferentialAction' => 'applications/differential/constants/DifferentialAction.php',
     'DifferentialActionHasNoEffectException' => 'applications/differential/exception/DifferentialActionHasNoEffectException.php',
     'DifferentialAddCommentView' => 'applications/differential/view/DifferentialAddCommentView.php',
     'DifferentialAffectedPath' => 'applications/differential/storage/DifferentialAffectedPath.php',
     'DifferentialApplyPatchFieldSpecification' => 'applications/differential/field/specification/DifferentialApplyPatchFieldSpecification.php',
     'DifferentialArcanistProjectFieldSpecification' => 'applications/differential/field/specification/DifferentialArcanistProjectFieldSpecification.php',
     'DifferentialAuditorsFieldSpecification' => 'applications/differential/field/specification/DifferentialAuditorsFieldSpecification.php',
     'DifferentialAuthorFieldSpecification' => 'applications/differential/field/specification/DifferentialAuthorFieldSpecification.php',
     'DifferentialAuxiliaryField' => 'applications/differential/storage/DifferentialAuxiliaryField.php',
     'DifferentialBlameRevisionFieldSpecification' => 'applications/differential/field/specification/DifferentialBlameRevisionFieldSpecification.php',
     'DifferentialBranchFieldSpecification' => 'applications/differential/field/specification/DifferentialBranchFieldSpecification.php',
     'DifferentialCCWelcomeMail' => 'applications/differential/mail/DifferentialCCWelcomeMail.php',
     'DifferentialCCsFieldSpecification' => 'applications/differential/field/specification/DifferentialCCsFieldSpecification.php',
     'DifferentialChangeType' => 'applications/differential/constants/DifferentialChangeType.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',
     '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',
     'DifferentialComment' => 'applications/differential/storage/DifferentialComment.php',
     'DifferentialCommentEditor' => 'applications/differential/editor/DifferentialCommentEditor.php',
     'DifferentialCommentMail' => 'applications/differential/mail/DifferentialCommentMail.php',
     'DifferentialCommentPreviewController' => 'applications/differential/controller/DifferentialCommentPreviewController.php',
     'DifferentialCommentSaveController' => 'applications/differential/controller/DifferentialCommentSaveController.php',
     'DifferentialCommitsFieldSpecification' => 'applications/differential/field/specification/DifferentialCommitsFieldSpecification.php',
     'DifferentialConflictsFieldSpecification' => 'applications/differential/field/specification/DifferentialConflictsFieldSpecification.php',
     'DifferentialController' => 'applications/differential/controller/DifferentialController.php',
     'DifferentialDAO' => 'applications/differential/storage/DifferentialDAO.php',
     'DifferentialDateCreatedFieldSpecification' => 'applications/differential/field/specification/DifferentialDateCreatedFieldSpecification.php',
     'DifferentialDateModifiedFieldSpecification' => 'applications/differential/field/specification/DifferentialDateModifiedFieldSpecification.php',
     'DifferentialDefaultFieldSelector' => 'applications/differential/field/selector/DifferentialDefaultFieldSelector.php',
     'DifferentialDependenciesFieldSpecification' => 'applications/differential/field/specification/DifferentialDependenciesFieldSpecification.php',
     'DifferentialDependsOnFieldSpecification' => 'applications/differential/field/specification/DifferentialDependsOnFieldSpecification.php',
     'DifferentialDiff' => 'applications/differential/storage/DifferentialDiff.php',
     'DifferentialDiffContentMail' => 'applications/differential/mail/DifferentialDiffContentMail.php',
     'DifferentialDiffCreateController' => 'applications/differential/controller/DifferentialDiffCreateController.php',
     'DifferentialDiffProperty' => 'applications/differential/storage/DifferentialDiffProperty.php',
     'DifferentialDiffTableOfContentsView' => 'applications/differential/view/DifferentialDiffTableOfContentsView.php',
     'DifferentialDiffTestCase' => 'applications/differential/storage/__tests__/DifferentialDiffTestCase.php',
     'DifferentialDiffViewController' => 'applications/differential/controller/DifferentialDiffViewController.php',
     'DifferentialException' => 'applications/differential/exception/DifferentialException.php',
     'DifferentialExceptionMail' => 'applications/differential/mail/DifferentialExceptionMail.php',
     'DifferentialExportPatchFieldSpecification' => 'applications/differential/field/specification/DifferentialExportPatchFieldSpecification.php',
     'DifferentialFieldDataNotAvailableException' => 'applications/differential/field/exception/DifferentialFieldDataNotAvailableException.php',
     'DifferentialFieldParseException' => 'applications/differential/field/exception/DifferentialFieldParseException.php',
     'DifferentialFieldSelector' => 'applications/differential/field/selector/DifferentialFieldSelector.php',
     'DifferentialFieldSpecification' => 'applications/differential/field/specification/DifferentialFieldSpecification.php',
     'DifferentialFieldSpecificationIncompleteException' => 'applications/differential/field/exception/DifferentialFieldSpecificationIncompleteException.php',
     'DifferentialFieldValidationException' => 'applications/differential/field/exception/DifferentialFieldValidationException.php',
     'DifferentialFreeformFieldSpecification' => 'applications/differential/field/specification/DifferentialFreeformFieldSpecification.php',
     'DifferentialGitSVNIDFieldSpecification' => 'applications/differential/field/specification/DifferentialGitSVNIDFieldSpecification.php',
     'DifferentialHostFieldSpecification' => 'applications/differential/field/specification/DifferentialHostFieldSpecification.php',
     'DifferentialHunk' => 'applications/differential/storage/DifferentialHunk.php',
     'DifferentialHunkParser' => 'applications/differential/parser/DifferentialHunkParser.php',
     'DifferentialHunkParserTestCase' => 'applications/differential/parser/__tests__/DifferentialHunkParserTestCase.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',
     'DifferentialInlineCommentView' => 'applications/differential/view/DifferentialInlineCommentView.php',
     'DifferentialLinesFieldSpecification' => 'applications/differential/field/specification/DifferentialLinesFieldSpecification.php',
     'DifferentialLintFieldSpecification' => 'applications/differential/field/specification/DifferentialLintFieldSpecification.php',
     'DifferentialLintStatus' => 'applications/differential/constants/DifferentialLintStatus.php',
     'DifferentialLocalCommitsView' => 'applications/differential/view/DifferentialLocalCommitsView.php',
     'DifferentialMail' => 'applications/differential/mail/DifferentialMail.php',
     'DifferentialMailPhase' => 'applications/differential/constants/DifferentialMailPhase.php',
     'DifferentialManiphestTasksFieldSpecification' => 'applications/differential/field/specification/DifferentialManiphestTasksFieldSpecification.php',
     'DifferentialNewDiffMail' => 'applications/differential/mail/DifferentialNewDiffMail.php',
     'DifferentialParseRenderTestCase' => 'applications/differential/__tests__/DifferentialParseRenderTestCase.php',
     'DifferentialPathFieldSpecification' => 'applications/differential/field/specification/DifferentialPathFieldSpecification.php',
     'DifferentialPeopleMenuEventListener' => 'applications/differential/events/DifferentialPeopleMenuEventListener.php',
     'DifferentialPrimaryPaneView' => 'applications/differential/view/DifferentialPrimaryPaneView.php',
+    'DifferentialReleephRequestFieldSpecification' => 'applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php',
     'DifferentialRemarkupRule' => 'applications/differential/remarkup/DifferentialRemarkupRule.php',
     'DifferentialReplyHandler' => 'applications/differential/DifferentialReplyHandler.php',
     'DifferentialResultsTableView' => 'applications/differential/view/DifferentialResultsTableView.php',
     'DifferentialRevertPlanFieldSpecification' => 'applications/differential/field/specification/DifferentialRevertPlanFieldSpecification.php',
     'DifferentialReviewRequestMail' => 'applications/differential/mail/DifferentialReviewRequestMail.php',
     'DifferentialReviewedByFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewedByFieldSpecification.php',
     'DifferentialReviewerStats' => 'applications/differential/stats/DifferentialReviewerStats.php',
     'DifferentialReviewerStatsTestCase' => 'applications/differential/stats/__tests__/DifferentialReviewerStatsTestCase.php',
     'DifferentialReviewersFieldSpecification' => 'applications/differential/field/specification/DifferentialReviewersFieldSpecification.php',
     'DifferentialRevision' => 'applications/differential/storage/DifferentialRevision.php',
     'DifferentialRevisionCommentListView' => 'applications/differential/view/DifferentialRevisionCommentListView.php',
     'DifferentialRevisionCommentView' => 'applications/differential/view/DifferentialRevisionCommentView.php',
     'DifferentialRevisionControlSystem' => 'applications/differential/constants/DifferentialRevisionControlSystem.php',
     'DifferentialRevisionDetailRenderer' => 'applications/differential/controller/DifferentialRevisionDetailRenderer.php',
     'DifferentialRevisionDetailView' => 'applications/differential/view/DifferentialRevisionDetailView.php',
     'DifferentialRevisionEditController' => 'applications/differential/controller/DifferentialRevisionEditController.php',
     'DifferentialRevisionEditor' => 'applications/differential/editor/DifferentialRevisionEditor.php',
     'DifferentialRevisionIDFieldParserTestCase' => 'applications/differential/field/specification/__tests__/DifferentialRevisionIDFieldParserTestCase.php',
     'DifferentialRevisionIDFieldSpecification' => 'applications/differential/field/specification/DifferentialRevisionIDFieldSpecification.php',
     'DifferentialRevisionListController' => 'applications/differential/controller/DifferentialRevisionListController.php',
     'DifferentialRevisionListData' => 'applications/differential/data/DifferentialRevisionListData.php',
     'DifferentialRevisionListView' => 'applications/differential/view/DifferentialRevisionListView.php',
     'DifferentialRevisionQuery' => 'applications/differential/query/DifferentialRevisionQuery.php',
     'DifferentialRevisionStatsController' => 'applications/differential/controller/DifferentialRevisionStatsController.php',
     'DifferentialRevisionStatsView' => 'applications/differential/view/DifferentialRevisionStatsView.php',
     'DifferentialRevisionStatus' => 'applications/differential/constants/DifferentialRevisionStatus.php',
     'DifferentialRevisionStatusFieldSpecification' => 'applications/differential/field/specification/DifferentialRevisionStatusFieldSpecification.php',
     'DifferentialRevisionUpdateHistoryView' => 'applications/differential/view/DifferentialRevisionUpdateHistoryView.php',
     'DifferentialRevisionViewController' => 'applications/differential/controller/DifferentialRevisionViewController.php',
     'DifferentialSearchIndexer' => 'applications/differential/search/DifferentialSearchIndexer.php',
     'DifferentialSubscribeController' => 'applications/differential/controller/DifferentialSubscribeController.php',
     'DifferentialSummaryFieldSpecification' => 'applications/differential/field/specification/DifferentialSummaryFieldSpecification.php',
     'DifferentialTasksAttacher' => 'applications/differential/DifferentialTasksAttacher.php',
     'DifferentialTestPlanFieldSpecification' => 'applications/differential/field/specification/DifferentialTestPlanFieldSpecification.php',
     'DifferentialTitleFieldSpecification' => 'applications/differential/field/specification/DifferentialTitleFieldSpecification.php',
     'DifferentialUnitFieldSpecification' => 'applications/differential/field/specification/DifferentialUnitFieldSpecification.php',
     'DifferentialUnitStatus' => 'applications/differential/constants/DifferentialUnitStatus.php',
     'DifferentialUnitTestResult' => 'applications/differential/constants/DifferentialUnitTestResult.php',
     'DiffusionBranchInformation' => 'applications/diffusion/data/DiffusionBranchInformation.php',
     'DiffusionBranchQuery' => 'applications/diffusion/query/branch/DiffusionBranchQuery.php',
     'DiffusionBranchTableController' => 'applications/diffusion/controller/DiffusionBranchTableController.php',
     'DiffusionBranchTableView' => 'applications/diffusion/view/DiffusionBranchTableView.php',
     'DiffusionBrowseController' => 'applications/diffusion/controller/DiffusionBrowseController.php',
     'DiffusionBrowseFileController' => 'applications/diffusion/controller/DiffusionBrowseFileController.php',
     'DiffusionBrowseQuery' => 'applications/diffusion/query/browse/DiffusionBrowseQuery.php',
     'DiffusionBrowseTableView' => 'applications/diffusion/view/DiffusionBrowseTableView.php',
     'DiffusionChangeController' => 'applications/diffusion/controller/DiffusionChangeController.php',
     'DiffusionCommentListView' => 'applications/diffusion/view/DiffusionCommentListView.php',
     'DiffusionCommentView' => 'applications/diffusion/view/DiffusionCommentView.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',
     'DiffusionCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionCommitParentsQuery.php',
     'DiffusionCommitQuery' => 'applications/diffusion/query/DiffusionCommitQuery.php',
     'DiffusionCommitTagsController' => 'applications/diffusion/controller/DiffusionCommitTagsController.php',
     'DiffusionCommitTagsQuery' => 'applications/diffusion/query/committags/DiffusionCommitTagsQuery.php',
     'DiffusionContainsQuery' => 'applications/diffusion/query/contains/DiffusionContainsQuery.php',
     'DiffusionController' => 'applications/diffusion/controller/DiffusionController.php',
     'DiffusionDiffController' => 'applications/diffusion/controller/DiffusionDiffController.php',
     'DiffusionDiffQuery' => 'applications/diffusion/query/diff/DiffusionDiffQuery.php',
     'DiffusionEmptyResultView' => 'applications/diffusion/view/DiffusionEmptyResultView.php',
     'DiffusionExistsQuery' => 'applications/diffusion/query/exists/DiffusionExistsQuery.php',
     'DiffusionExternalController' => 'applications/diffusion/controller/DiffusionExternalController.php',
     'DiffusionFileContent' => 'applications/diffusion/data/DiffusionFileContent.php',
     'DiffusionFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionFileContentQuery.php',
     'DiffusionGitBranchQuery' => 'applications/diffusion/query/branch/DiffusionGitBranchQuery.php',
     'DiffusionGitBranchQueryTestCase' => 'applications/diffusion/query/branch/__tests__/DiffusionGitBranchQueryTestCase.php',
     'DiffusionGitBrowseQuery' => 'applications/diffusion/query/browse/DiffusionGitBrowseQuery.php',
     'DiffusionGitCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionGitCommitParentsQuery.php',
     'DiffusionGitCommitTagsQuery' => 'applications/diffusion/query/committags/DiffusionGitCommitTagsQuery.php',
     'DiffusionGitContainsQuery' => 'applications/diffusion/query/contains/DiffusionGitContainsQuery.php',
     'DiffusionGitDiffQuery' => 'applications/diffusion/query/diff/DiffusionGitDiffQuery.php',
     'DiffusionGitExistsQuery' => 'applications/diffusion/query/exists/DiffusionGitExistsQuery.php',
     'DiffusionGitFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionGitFileContentQuery.php',
     'DiffusionGitHistoryQuery' => 'applications/diffusion/query/history/DiffusionGitHistoryQuery.php',
     'DiffusionGitLastModifiedQuery' => 'applications/diffusion/query/lastmodified/DiffusionGitLastModifiedQuery.php',
     'DiffusionGitMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionGitMergedCommitsQuery.php',
     'DiffusionGitRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionGitRawDiffQuery.php',
     'DiffusionGitRequest' => 'applications/diffusion/request/DiffusionGitRequest.php',
     'DiffusionGitTagListQuery' => 'applications/diffusion/query/taglist/DiffusionGitTagListQuery.php',
     'DiffusionHistoryController' => 'applications/diffusion/controller/DiffusionHistoryController.php',
     'DiffusionHistoryQuery' => 'applications/diffusion/query/history/DiffusionHistoryQuery.php',
     'DiffusionHistoryTableView' => 'applications/diffusion/view/DiffusionHistoryTableView.php',
     'DiffusionHomeController' => 'applications/diffusion/controller/DiffusionHomeController.php',
     'DiffusionInlineCommentController' => 'applications/diffusion/controller/DiffusionInlineCommentController.php',
     'DiffusionInlineCommentPreviewController' => 'applications/diffusion/controller/DiffusionInlineCommentPreviewController.php',
     'DiffusionLastModifiedController' => 'applications/diffusion/controller/DiffusionLastModifiedController.php',
     'DiffusionLastModifiedQuery' => 'applications/diffusion/query/lastmodified/DiffusionLastModifiedQuery.php',
     'DiffusionLintController' => 'applications/diffusion/controller/DiffusionLintController.php',
     'DiffusionLintDetailsController' => 'applications/diffusion/controller/DiffusionLintDetailsController.php',
     'DiffusionLintSaveRunner' => 'applications/diffusion/DiffusionLintSaveRunner.php',
     'DiffusionMercurialBranchQuery' => 'applications/diffusion/query/branch/DiffusionMercurialBranchQuery.php',
     'DiffusionMercurialBrowseQuery' => 'applications/diffusion/query/browse/DiffusionMercurialBrowseQuery.php',
     'DiffusionMercurialCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionMercurialCommitParentsQuery.php',
     'DiffusionMercurialCommitTagsQuery' => 'applications/diffusion/query/committags/DiffusionMercurialCommitTagsQuery.php',
     'DiffusionMercurialContainsQuery' => 'applications/diffusion/query/contains/DiffusionMercurialContainsQuery.php',
     'DiffusionMercurialDiffQuery' => 'applications/diffusion/query/diff/DiffusionMercurialDiffQuery.php',
     'DiffusionMercurialExistsQuery' => 'applications/diffusion/query/exists/DiffusionMercurialExistsQuery.php',
     'DiffusionMercurialFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionMercurialFileContentQuery.php',
     'DiffusionMercurialHistoryQuery' => 'applications/diffusion/query/history/DiffusionMercurialHistoryQuery.php',
     'DiffusionMercurialLastModifiedQuery' => 'applications/diffusion/query/lastmodified/DiffusionMercurialLastModifiedQuery.php',
     'DiffusionMercurialMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionMercurialMergedCommitsQuery.php',
     'DiffusionMercurialRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionMercurialRawDiffQuery.php',
     'DiffusionMercurialRequest' => 'applications/diffusion/request/DiffusionMercurialRequest.php',
     'DiffusionMercurialTagListQuery' => 'applications/diffusion/query/taglist/DiffusionMercurialTagListQuery.php',
     'DiffusionMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionMergedCommitsQuery.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',
     'DiffusionPathValidateController' => 'applications/diffusion/controller/DiffusionPathValidateController.php',
     'DiffusionPeopleMenuEventListener' => 'applications/diffusion/events/DiffusionPeopleMenuEventListener.php',
     'DiffusionQuery' => 'applications/diffusion/query/DiffusionQuery.php',
     'DiffusionRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionRawDiffQuery.php',
     'DiffusionRemarkupRule' => 'applications/diffusion/remarkup/DiffusionRemarkupRule.php',
     'DiffusionRenameHistoryQuery' => 'applications/diffusion/query/DiffusionRenameHistoryQuery.php',
     'DiffusionRepositoryController' => 'applications/diffusion/controller/DiffusionRepositoryController.php',
     'DiffusionRepositoryPath' => 'applications/diffusion/data/DiffusionRepositoryPath.php',
     'DiffusionRepositoryTag' => 'applications/diffusion/DiffusionRepositoryTag.php',
     'DiffusionRequest' => 'applications/diffusion/request/DiffusionRequest.php',
     'DiffusionSetupException' => 'applications/diffusion/exception/DiffusionSetupException.php',
     'DiffusionSvnBrowseQuery' => 'applications/diffusion/query/browse/DiffusionSvnBrowseQuery.php',
     'DiffusionSvnCommitParentsQuery' => 'applications/diffusion/query/parents/DiffusionSvnCommitParentsQuery.php',
     'DiffusionSvnCommitTagsQuery' => 'applications/diffusion/query/committags/DiffusionSvnCommitTagsQuery.php',
     'DiffusionSvnContainsQuery' => 'applications/diffusion/query/contains/DiffusionSvnContainsQuery.php',
     'DiffusionSvnDiffQuery' => 'applications/diffusion/query/diff/DiffusionSvnDiffQuery.php',
     'DiffusionSvnExistsQuery' => 'applications/diffusion/query/exists/DiffusionSvnExistsQuery.php',
     'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/DiffusionSvnFileContentQuery.php',
     'DiffusionSvnHistoryQuery' => 'applications/diffusion/query/history/DiffusionSvnHistoryQuery.php',
     'DiffusionSvnLastModifiedQuery' => 'applications/diffusion/query/lastmodified/DiffusionSvnLastModifiedQuery.php',
     'DiffusionSvnMergedCommitsQuery' => 'applications/diffusion/query/mergedcommits/DiffusionSvnMergedCommitsQuery.php',
     'DiffusionSvnRawDiffQuery' => 'applications/diffusion/query/rawdiff/DiffusionSvnRawDiffQuery.php',
     'DiffusionSvnRequest' => 'applications/diffusion/request/DiffusionSvnRequest.php',
     'DiffusionSvnTagListQuery' => 'applications/diffusion/query/taglist/DiffusionSvnTagListQuery.php',
     'DiffusionSymbolController' => 'applications/diffusion/controller/DiffusionSymbolController.php',
     'DiffusionSymbolQuery' => 'applications/diffusion/query/DiffusionSymbolQuery.php',
     'DiffusionTagListController' => 'applications/diffusion/controller/DiffusionTagListController.php',
     'DiffusionTagListQuery' => 'applications/diffusion/query/taglist/DiffusionTagListQuery.php',
     'DiffusionTagListView' => 'applications/diffusion/view/DiffusionTagListView.php',
     'DiffusionURITestCase' => 'applications/diffusion/request/__tests__/DiffusionURITestCase.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',
     'DivinerAtomRef' => 'applications/diviner/atom/DivinerAtomRef.php',
     'DivinerAtomizeWorkflow' => 'applications/diviner/workflow/DivinerAtomizeWorkflow.php',
     'DivinerAtomizer' => 'applications/diviner/atomizer/DivinerAtomizer.php',
     'DivinerDefaultRenderer' => 'applications/diviner/renderer/DivinerDefaultRenderer.php',
     'DivinerDiskCache' => 'applications/diviner/cache/DivinerDiskCache.php',
     'DivinerFileAtomizer' => 'applications/diviner/atomizer/DivinerFileAtomizer.php',
     'DivinerGenerateWorkflow' => 'applications/diviner/workflow/DivinerGenerateWorkflow.php',
     'DivinerListController' => 'applications/diviner/controller/DivinerListController.php',
     'DivinerPublishCache' => 'applications/diviner/cache/DivinerPublishCache.php',
     'DivinerPublisher' => 'applications/diviner/publisher/DivinerPublisher.php',
     'DivinerRemarkupRuleSymbol' => 'applications/diviner/markup/DivinerRemarkupRuleSymbol.php',
     'DivinerRenderer' => 'applications/diviner/renderer/DivinerRenderer.php',
     'DivinerStaticPublisher' => 'applications/diviner/publisher/DivinerStaticPublisher.php',
     'DivinerWorkflow' => 'applications/diviner/workflow/DivinerWorkflow.php',
     'DrydockAllocatorWorker' => 'applications/drydock/worker/DrydockAllocatorWorker.php',
     'DrydockApacheWebrootInterface' => 'applications/drydock/interface/webroot/DrydockApacheWebrootInterface.php',
     'DrydockBlueprint' => 'applications/drydock/blueprint/DrydockBlueprint.php',
     'DrydockBlueprintScopeGuard' => 'applications/drydock/util/DrydockBlueprintScopeGuard.php',
     'DrydockCommandInterface' => 'applications/drydock/interface/command/DrydockCommandInterface.php',
     'DrydockConstants' => 'applications/drydock/constants/DrydockConstants.php',
     'DrydockController' => 'applications/drydock/controller/DrydockController.php',
     'DrydockDAO' => 'applications/drydock/storage/DrydockDAO.php',
     'DrydockInterface' => 'applications/drydock/interface/DrydockInterface.php',
     'DrydockLease' => 'applications/drydock/storage/DrydockLease.php',
     'DrydockLeaseListController' => 'applications/drydock/controller/DrydockLeaseListController.php',
     'DrydockLeaseQuery' => 'applications/drydock/query/DrydockLeaseQuery.php',
     'DrydockLeaseReleaseController' => 'applications/drydock/controller/DrydockLeaseReleaseController.php',
     'DrydockLeaseStatus' => 'applications/drydock/constants/DrydockLeaseStatus.php',
     'DrydockLeaseViewController' => 'applications/drydock/controller/DrydockLeaseViewController.php',
     'DrydockLocalCommandInterface' => 'applications/drydock/interface/command/DrydockLocalCommandInterface.php',
     'DrydockLocalHostBlueprint' => 'applications/drydock/blueprint/DrydockLocalHostBlueprint.php',
     'DrydockLog' => 'applications/drydock/storage/DrydockLog.php',
     'DrydockLogController' => 'applications/drydock/controller/DrydockLogController.php',
     'DrydockLogQuery' => 'applications/drydock/query/DrydockLogQuery.php',
     'DrydockManagementCloseWorkflow' => 'applications/drydock/management/DrydockManagementCloseWorkflow.php',
     'DrydockManagementLeaseWorkflow' => 'applications/drydock/management/DrydockManagementLeaseWorkflow.php',
     'DrydockManagementReleaseWorkflow' => 'applications/drydock/management/DrydockManagementReleaseWorkflow.php',
     'DrydockManagementWaitForLeaseWorkflow' => 'applications/drydock/management/DrydockManagementWaitForLeaseWorkflow.php',
     'DrydockManagementWorkflow' => 'applications/drydock/management/DrydockManagementWorkflow.php',
     'DrydockResource' => 'applications/drydock/storage/DrydockResource.php',
     'DrydockResourceCloseController' => 'applications/drydock/controller/DrydockResourceCloseController.php',
     'DrydockResourceListController' => 'applications/drydock/controller/DrydockResourceListController.php',
     'DrydockResourceQuery' => 'applications/drydock/query/DrydockResourceQuery.php',
     'DrydockResourceStatus' => 'applications/drydock/constants/DrydockResourceStatus.php',
     'DrydockResourceViewController' => 'applications/drydock/controller/DrydockResourceViewController.php',
     'DrydockSSHCommandInterface' => 'applications/drydock/interface/command/DrydockSSHCommandInterface.php',
     'DrydockWebrootInterface' => 'applications/drydock/interface/webroot/DrydockWebrootInterface.php',
     'DrydockWorkingCopyBlueprint' => 'applications/drydock/blueprint/DrydockWorkingCopyBlueprint.php',
     'FeedPublisherWorker' => 'applications/feed/worker/FeedPublisherWorker.php',
     'HarbormasterDAO' => 'applications/harbormaster/storage/HarbormasterDAO.php',
     'HarbormasterObject' => 'applications/harbormaster/storage/HarbormasterObject.php',
     'HarbormasterRunnerWorker' => 'applications/harbormaster/worker/HarbormasterRunnerWorker.php',
     'HarbormasterScratchTable' => 'applications/harbormaster/storage/HarbormasterScratchTable.php',
     'HeraldAction' => 'applications/herald/storage/HeraldAction.php',
     'HeraldActionConfig' => 'applications/herald/config/HeraldActionConfig.php',
     'HeraldApplyTranscript' => 'applications/herald/storage/transcript/HeraldApplyTranscript.php',
     'HeraldCommitAdapter' => 'applications/herald/adapter/HeraldCommitAdapter.php',
     'HeraldCondition' => 'applications/herald/storage/HeraldCondition.php',
     'HeraldConditionConfig' => 'applications/herald/config/HeraldConditionConfig.php',
     'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php',
     'HeraldContentTypeConfig' => 'applications/herald/config/HeraldContentTypeConfig.php',
     'HeraldController' => 'applications/herald/controller/HeraldController.php',
     'HeraldDAO' => 'applications/herald/storage/HeraldDAO.php',
     'HeraldDeleteController' => 'applications/herald/controller/HeraldDeleteController.php',
     'HeraldDifferentialRevisionAdapter' => 'applications/herald/adapter/HeraldDifferentialRevisionAdapter.php',
     'HeraldDryRunAdapter' => 'applications/herald/adapter/HeraldDryRunAdapter.php',
     'HeraldEditLogQuery' => 'applications/herald/query/HeraldEditLogQuery.php',
     'HeraldEffect' => 'applications/herald/engine/HeraldEffect.php',
     'HeraldEngine' => 'applications/herald/engine/HeraldEngine.php',
     'HeraldFieldConfig' => 'applications/herald/config/HeraldFieldConfig.php',
     'HeraldHomeController' => 'applications/herald/controller/HeraldHomeController.php',
     'HeraldInvalidConditionException' => 'applications/herald/engine/engine/HeraldInvalidConditionException.php',
     'HeraldInvalidFieldException' => 'applications/herald/engine/engine/HeraldInvalidFieldException.php',
     'HeraldNewController' => 'applications/herald/controller/HeraldNewController.php',
     'HeraldObjectAdapter' => 'applications/herald/adapter/HeraldObjectAdapter.php',
     'HeraldObjectTranscript' => 'applications/herald/storage/transcript/HeraldObjectTranscript.php',
     'HeraldRecursiveConditionsException' => 'applications/herald/engine/engine/HeraldRecursiveConditionsException.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',
     'HeraldRuleListView' => 'applications/herald/view/HeraldRuleListView.php',
     'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php',
     'HeraldRuleTranscript' => 'applications/herald/storage/transcript/HeraldRuleTranscript.php',
     'HeraldRuleTypeConfig' => 'applications/herald/config/HeraldRuleTypeConfig.php',
     'HeraldTestConsoleController' => 'applications/herald/controller/HeraldTestConsoleController.php',
     'HeraldTranscript' => 'applications/herald/storage/transcript/HeraldTranscript.php',
     'HeraldTranscriptController' => 'applications/herald/controller/HeraldTranscriptController.php',
     'HeraldTranscriptListController' => 'applications/herald/controller/HeraldTranscriptListController.php',
     'HeraldValueTypeConfig' => 'applications/herald/config/HeraldValueTypeConfig.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',
     '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',
     'ManiphestAction' => 'applications/maniphest/constants/ManiphestAction.php',
     'ManiphestAuxiliaryFieldDefaultSpecification' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldDefaultSpecification.php',
     'ManiphestAuxiliaryFieldSpecification' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldSpecification.php',
     'ManiphestAuxiliaryFieldTypeException' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldTypeException.php',
     'ManiphestAuxiliaryFieldValidationException' => 'applications/maniphest/auxiliaryfield/ManiphestAuxiliaryFieldValidationException.php',
     'ManiphestBatchEditController' => 'applications/maniphest/controller/ManiphestBatchEditController.php',
     'ManiphestConstants' => 'applications/maniphest/constants/ManiphestConstants.php',
     'ManiphestController' => 'applications/maniphest/controller/ManiphestController.php',
     'ManiphestDAO' => 'applications/maniphest/storage/ManiphestDAO.php',
     'ManiphestDefaultTaskExtensions' => 'applications/maniphest/extensions/ManiphestDefaultTaskExtensions.php',
     'ManiphestEdgeEventListener' => 'applications/maniphest/event/ManiphestEdgeEventListener.php',
     'ManiphestExportController' => 'applications/maniphest/controller/ManiphestExportController.php',
     'ManiphestPeopleMenuEventListener' => 'applications/maniphest/event/ManiphestPeopleMenuEventListener.php',
     'ManiphestRemarkupRule' => 'applications/maniphest/remarkup/ManiphestRemarkupRule.php',
     'ManiphestReplyHandler' => 'applications/maniphest/ManiphestReplyHandler.php',
     'ManiphestReportController' => 'applications/maniphest/controller/ManiphestReportController.php',
     'ManiphestSavedQuery' => 'applications/maniphest/storage/ManiphestSavedQuery.php',
     'ManiphestSavedQueryDeleteController' => 'applications/maniphest/controller/ManiphestSavedQueryDeleteController.php',
     'ManiphestSavedQueryEditController' => 'applications/maniphest/controller/ManiphestSavedQueryEditController.php',
     'ManiphestSavedQueryListController' => 'applications/maniphest/controller/ManiphestSavedQueryListController.php',
     'ManiphestSearchIndexer' => 'applications/maniphest/search/ManiphestSearchIndexer.php',
     'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php',
     'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php',
     'ManiphestTaskAuxiliaryStorage' => 'applications/maniphest/storage/ManiphestTaskAuxiliaryStorage.php',
     'ManiphestTaskDescriptionChangeController' => 'applications/maniphest/controller/ManiphestTaskDescriptionChangeController.php',
     'ManiphestTaskDescriptionPreviewController' => 'applications/maniphest/controller/ManiphestTaskDescriptionPreviewController.php',
     'ManiphestTaskDetailController' => 'applications/maniphest/controller/ManiphestTaskDetailController.php',
     'ManiphestTaskEditController' => 'applications/maniphest/controller/ManiphestTaskEditController.php',
     'ManiphestTaskExtensions' => 'applications/maniphest/extensions/ManiphestTaskExtensions.php',
     'ManiphestTaskListController' => 'applications/maniphest/controller/ManiphestTaskListController.php',
     'ManiphestTaskListView' => 'applications/maniphest/view/ManiphestTaskListView.php',
     'ManiphestTaskOwner' => 'applications/maniphest/constants/ManiphestTaskOwner.php',
     'ManiphestTaskPriority' => 'applications/maniphest/constants/ManiphestTaskPriority.php',
     'ManiphestTaskProject' => 'applications/maniphest/storage/ManiphestTaskProject.php',
     'ManiphestTaskProjectsView' => 'applications/maniphest/view/ManiphestTaskProjectsView.php',
     'ManiphestTaskQuery' => 'applications/maniphest/ManiphestTaskQuery.php',
     'ManiphestTaskStatus' => 'applications/maniphest/constants/ManiphestTaskStatus.php',
     'ManiphestTaskSubscriber' => 'applications/maniphest/storage/ManiphestTaskSubscriber.php',
     'ManiphestTaskSummaryView' => 'applications/maniphest/view/ManiphestTaskSummaryView.php',
     'ManiphestTransaction' => 'applications/maniphest/storage/ManiphestTransaction.php',
     'ManiphestTransactionDetailView' => 'applications/maniphest/view/ManiphestTransactionDetailView.php',
     'ManiphestTransactionEditor' => 'applications/maniphest/editor/ManiphestTransactionEditor.php',
     'ManiphestTransactionListView' => 'applications/maniphest/view/ManiphestTransactionListView.php',
     'ManiphestTransactionPreviewController' => 'applications/maniphest/controller/ManiphestTransactionPreviewController.php',
     'ManiphestTransactionSaveController' => 'applications/maniphest/controller/ManiphestTransactionSaveController.php',
     'ManiphestTransactionType' => 'applications/maniphest/constants/ManiphestTransactionType.php',
     'ManiphestView' => 'applications/maniphest/view/ManiphestView.php',
     'MetaMTAConstants' => 'applications/metamta/constants/MetaMTAConstants.php',
     'MetaMTANotificationType' => 'applications/metamta/constants/MetaMTANotificationType.php',
     'ObjectHandleLoader' => 'applications/phid/handle/ObjectHandleLoader.php',
     'OwnersPackageReplyHandler' => 'applications/owners/OwnersPackageReplyHandler.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',
     'PasteEmbedView' => 'applications/paste/view/PasteEmbedView.php',
     'Phabricator404Controller' => 'applications/base/controller/Phabricator404Controller.php',
     'PhabricatorAWSConfigOptions' => 'applications/config/option/PhabricatorAWSConfigOptions.php',
     'PhabricatorAccessLog' => 'infrastructure/PhabricatorAccessLog.php',
     'PhabricatorAccessLogConfigOptions' => 'applications/config/option/PhabricatorAccessLogConfigOptions.php',
     'PhabricatorActionListExample' => 'applications/uiexample/examples/PhabricatorActionListExample.php',
     'PhabricatorActionListView' => 'view/layout/PhabricatorActionListView.php',
     'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php',
     'PhabricatorAllCapsTranslation' => 'infrastructure/internationalization/PhabricatorAllCapsTranslation.php',
     'PhabricatorAnchorView' => 'view/layout/PhabricatorAnchorView.php',
     'PhabricatorAphrontBarExample' => 'applications/uiexample/examples/PhabricatorAphrontBarExample.php',
     'PhabricatorApplication' => 'applications/base/PhabricatorApplication.php',
     'PhabricatorApplicationApplications' => 'applications/meta/application/PhabricatorApplicationApplications.php',
     'PhabricatorApplicationAudit' => 'applications/audit/application/PhabricatorApplicationAudit.php',
     'PhabricatorApplicationAuth' => 'applications/auth/application/PhabricatorApplicationAuth.php',
     'PhabricatorApplicationCalendar' => 'applications/calendar/application/PhabricatorApplicationCalendar.php',
     'PhabricatorApplicationChatLog' => 'applications/chatlog/applications/PhabricatorApplicationChatLog.php',
     'PhabricatorApplicationConduit' => 'applications/conduit/application/PhabricatorApplicationConduit.php',
     'PhabricatorApplicationConfig' => 'applications/config/application/PhabricatorApplicationConfig.php',
     'PhabricatorApplicationConfigOptions' => 'applications/config/option/PhabricatorApplicationConfigOptions.php',
     'PhabricatorApplicationConpherence' => 'applications/conpherence/application/PhabricatorApplicationConpherence.php',
     'PhabricatorApplicationCountdown' => 'applications/countdown/application/PhabricatorApplicationCountdown.php',
     'PhabricatorApplicationDaemons' => 'applications/daemon/application/PhabricatorApplicationDaemons.php',
     'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php',
     'PhabricatorApplicationDifferential' => 'applications/differential/application/PhabricatorApplicationDifferential.php',
     'PhabricatorApplicationDiffusion' => 'applications/diffusion/application/PhabricatorApplicationDiffusion.php',
     'PhabricatorApplicationDiviner' => 'applications/diviner/application/PhabricatorApplicationDiviner.php',
     'PhabricatorApplicationDrydock' => 'applications/drydock/application/PhabricatorApplicationDrydock.php',
     'PhabricatorApplicationFact' => 'applications/fact/application/PhabricatorApplicationFact.php',
     'PhabricatorApplicationFeed' => 'applications/feed/application/PhabricatorApplicationFeed.php',
     'PhabricatorApplicationFiles' => 'applications/files/application/PhabricatorApplicationFiles.php',
     'PhabricatorApplicationFlags' => 'applications/flag/application/PhabricatorApplicationFlags.php',
     'PhabricatorApplicationHerald' => 'applications/herald/application/PhabricatorApplicationHerald.php',
     'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php',
     'PhabricatorApplicationMacro' => 'applications/macro/application/PhabricatorApplicationMacro.php',
     'PhabricatorApplicationMailingLists' => 'applications/mailinglists/application/PhabricatorApplicationMailingLists.php',
     'PhabricatorApplicationManiphest' => 'applications/maniphest/application/PhabricatorApplicationManiphest.php',
     'PhabricatorApplicationMetaMTA' => 'applications/metamta/application/PhabricatorApplicationMetaMTA.php',
     'PhabricatorApplicationOwners' => 'applications/owners/application/PhabricatorApplicationOwners.php',
     'PhabricatorApplicationPHID' => 'applications/phid/application/PhabricatorApplicationPHID.php',
     'PhabricatorApplicationPHPAST' => 'applications/phpast/application/PhabricatorApplicationPHPAST.php',
     'PhabricatorApplicationPaste' => 'applications/paste/application/PhabricatorApplicationPaste.php',
     'PhabricatorApplicationPeople' => 'applications/people/application/PhabricatorApplicationPeople.php',
     'PhabricatorApplicationPhame' => 'applications/phame/application/PhabricatorApplicationPhame.php',
     'PhabricatorApplicationPholio' => 'applications/pholio/application/PhabricatorApplicationPholio.php',
     'PhabricatorApplicationPhriction' => 'applications/phriction/application/PhabricatorApplicationPhriction.php',
     'PhabricatorApplicationPonder' => 'applications/ponder/application/PhabricatorApplicationPonder.php',
     'PhabricatorApplicationProject' => 'applications/project/application/PhabricatorApplicationProject.php',
+    'PhabricatorApplicationReleeph' => 'applications/releeph/application/PhabricatorApplicationReleeph.php',
+    'PhabricatorApplicationReleephConfigOptions' => 'applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php',
     'PhabricatorApplicationRepositories' => 'applications/repository/application/PhabricatorApplicationRepositories.php',
     'PhabricatorApplicationSettings' => 'applications/settings/application/PhabricatorApplicationSettings.php',
     'PhabricatorApplicationSlowvote' => 'applications/slowvote/application/PhabricatorApplicationSlowvote.php',
     'PhabricatorApplicationStatusView' => 'applications/meta/view/PhabricatorApplicationStatusView.php',
     'PhabricatorApplicationSubscriptions' => 'applications/subscriptions/application/PhabricatorApplicationSubscriptions.php',
     'PhabricatorApplicationTokens' => 'applications/tokens/application/PhabricatorApplicationTokens.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',
     'PhabricatorApplicationTransactionCommentView' => 'applications/transactions/view/PhabricatorApplicationTransactionCommentView.php',
     'PhabricatorApplicationTransactionController' => 'applications/transactions/controller/PhabricatorApplicationTransactionController.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',
     'PhabricatorApplicationTransactionTextDiffDetailView' => 'applications/transactions/view/PhabricatorApplicationTransactionTextDiffDetailView.php',
     'PhabricatorApplicationTransactionView' => 'applications/transactions/view/PhabricatorApplicationTransactionView.php',
     'PhabricatorApplicationTransactions' => 'applications/transactions/application/PhabricatorApplicationTransactions.php',
     'PhabricatorApplicationUIExamples' => 'applications/uiexample/application/PhabricatorApplicationUIExamples.php',
     'PhabricatorApplicationUninstallController' => 'applications/meta/controller/PhabricatorApplicationUninstallController.php',
     'PhabricatorApplicationsController' => 'applications/meta/controller/PhabricatorApplicationsController.php',
     'PhabricatorApplicationsListController' => 'applications/meta/controller/PhabricatorApplicationsListController.php',
     'PhabricatorAuditActionConstants' => 'applications/audit/constants/PhabricatorAuditActionConstants.php',
     'PhabricatorAuditAddCommentController' => 'applications/audit/controller/PhabricatorAuditAddCommentController.php',
     'PhabricatorAuditComment' => 'applications/audit/storage/PhabricatorAuditComment.php',
     'PhabricatorAuditCommentEditor' => 'applications/audit/editor/PhabricatorAuditCommentEditor.php',
     'PhabricatorAuditCommitListView' => 'applications/audit/view/PhabricatorAuditCommitListView.php',
     'PhabricatorAuditCommitQuery' => 'applications/audit/query/PhabricatorAuditCommitQuery.php',
     'PhabricatorAuditCommitStatusConstants' => 'applications/audit/constants/PhabricatorAuditCommitStatusConstants.php',
     'PhabricatorAuditController' => 'applications/audit/controller/PhabricatorAuditController.php',
     'PhabricatorAuditDAO' => 'applications/audit/storage/PhabricatorAuditDAO.php',
     'PhabricatorAuditInlineComment' => 'applications/audit/storage/PhabricatorAuditInlineComment.php',
     'PhabricatorAuditListController' => 'applications/audit/controller/PhabricatorAuditListController.php',
     'PhabricatorAuditListView' => 'applications/audit/view/PhabricatorAuditListView.php',
     'PhabricatorAuditPreviewController' => 'applications/audit/controller/PhabricatorAuditPreviewController.php',
     'PhabricatorAuditQuery' => 'applications/audit/query/PhabricatorAuditQuery.php',
     'PhabricatorAuditReplyHandler' => 'applications/audit/PhabricatorAuditReplyHandler.php',
     'PhabricatorAuditStatusConstants' => 'applications/audit/constants/PhabricatorAuditStatusConstants.php',
     'PhabricatorAuthController' => 'applications/auth/controller/PhabricatorAuthController.php',
     'PhabricatorAuthenticationConfigOptions' => 'applications/config/option/PhabricatorAuthenticationConfigOptions.php',
     'PhabricatorBarePageExample' => 'applications/uiexample/examples/PhabricatorBarePageExample.php',
     'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php',
     'PhabricatorBaseEnglishTranslation' => 'infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php',
     'PhabricatorBaseProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBaseProtocolAdapter.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',
     'PhabricatorBotDifferentialNotificationHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotDifferentialNotificationHandler.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',
     'PhabricatorButtonsExample' => 'applications/uiexample/examples/PhabricatorButtonsExample.php',
     'PhabricatorCacheDAO' => 'applications/cache/storage/PhabricatorCacheDAO.php',
     'PhabricatorCaches' => 'applications/cache/PhabricatorCaches.php',
     'PhabricatorCalendarBrowseController' => 'applications/calendar/controller/PhabricatorCalendarBrowseController.php',
     'PhabricatorCalendarController' => 'applications/calendar/controller/PhabricatorCalendarController.php',
     'PhabricatorCalendarDAO' => 'applications/calendar/storage/PhabricatorCalendarDAO.php',
     'PhabricatorCalendarDeleteStatusController' => 'applications/calendar/controller/PhabricatorCalendarDeleteStatusController.php',
     'PhabricatorCalendarEditStatusController' => 'applications/calendar/controller/PhabricatorCalendarEditStatusController.php',
     'PhabricatorCalendarHoliday' => 'applications/calendar/storage/PhabricatorCalendarHoliday.php',
     'PhabricatorCalendarHolidayTestCase' => 'applications/calendar/storage/__tests__/PhabricatorCalendarHolidayTestCase.php',
     'PhabricatorCalendarViewStatusController' => 'applications/calendar/controller/PhabricatorCalendarViewStatusController.php',
     'PhabricatorCampfireProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorCampfireProtocolAdapter.php',
     'PhabricatorChangesetResponse' => 'infrastructure/diff/PhabricatorChangesetResponse.php',
     'PhabricatorChatLogChannel' => 'applications/chatlog/storage/PhabricatorChatLogChannel.php',
     'PhabricatorChatLogChannelListController' => 'applications/chatlog/controller/PhabricatorChatLogChannelListController.php',
     'PhabricatorChatLogChannelLogController' => 'applications/chatlog/controller/PhabricatorChatLogChannelLogController.php',
     'PhabricatorChatLogChannelQuery' => 'applications/chatlog/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/PhabricatorChatLogQuery.php',
     'PhabricatorConduitAPIController' => 'applications/conduit/controller/PhabricatorConduitAPIController.php',
     'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/PhabricatorConduitCertificateToken.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',
     'PhabricatorConduitMethodCallLog' => 'applications/conduit/storage/PhabricatorConduitMethodCallLog.php',
     'PhabricatorConduitTokenController' => 'applications/conduit/controller/PhabricatorConduitTokenController.php',
     'PhabricatorConfigAllController' => 'applications/config/controller/PhabricatorConfigAllController.php',
     'PhabricatorConfigController' => 'applications/config/controller/PhabricatorConfigController.php',
     'PhabricatorConfigDatabaseSource' => 'infrastructure/env/PhabricatorConfigDatabaseSource.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',
     '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',
     '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',
     'PhabricatorConfigManagementSetWorkflow' => 'applications/config/management/PhabricatorConfigManagementSetWorkflow.php',
     'PhabricatorConfigManagementWorkflow' => 'applications/config/management/PhabricatorConfigManagementWorkflow.php',
     'PhabricatorConfigOption' => 'applications/config/option/PhabricatorConfigOption.php',
     'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php',
     'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php',
     'PhabricatorConfigSource' => 'infrastructure/env/PhabricatorConfigSource.php',
     'PhabricatorConfigStackSource' => 'infrastructure/env/PhabricatorConfigStackSource.php',
     'PhabricatorConfigTransaction' => 'applications/config/storage/PhabricatorConfigTransaction.php',
     'PhabricatorConfigTransactionQuery' => 'applications/config/query/PhabricatorConfigTransactionQuery.php',
     'PhabricatorConfigValidationException' => 'applications/config/exception/PhabricatorConfigValidationException.php',
     'PhabricatorContentSource' => 'applications/metamta/contentsource/PhabricatorContentSource.php',
     'PhabricatorContentSourceView' => 'applications/metamta/contentsource/PhabricatorContentSourceView.php',
     'PhabricatorController' => 'applications/base/controller/PhabricatorController.php',
     'PhabricatorCoreConfigOptions' => 'applications/config/option/PhabricatorCoreConfigOptions.php',
     'PhabricatorCountdownController' => 'applications/countdown/controller/PhabricatorCountdownController.php',
     'PhabricatorCountdownDAO' => 'applications/countdown/storage/PhabricatorCountdownDAO.php',
     'PhabricatorCountdownDeleteController' => 'applications/countdown/controller/PhabricatorCountdownDeleteController.php',
     'PhabricatorCountdownEditController' => 'applications/countdown/controller/PhabricatorCountdownEditController.php',
     'PhabricatorCountdownListController' => 'applications/countdown/controller/PhabricatorCountdownListController.php',
     'PhabricatorCountdownRemarkupRule' => 'applications/countdown/remarkup/PhabricatorCountdownRemarkupRule.php',
     'PhabricatorCountdownViewController' => 'applications/countdown/controller/PhabricatorCountdownViewController.php',
     'PhabricatorCountedToggleButtonsExample' => 'applications/uiexample/examples/PhabricatorCountedToggleButtonsExample.php',
     'PhabricatorCrumbView' => 'view/layout/PhabricatorCrumbView.php',
     'PhabricatorCrumbsView' => 'view/layout/PhabricatorCrumbsView.php',
     'PhabricatorCursorPagedPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php',
     'PhabricatorDaemon' => 'infrastructure/daemon/PhabricatorDaemon.php',
     'PhabricatorDaemonCombinedLogController' => 'applications/daemon/controller/PhabricatorDaemonCombinedLogController.php',
     'PhabricatorDaemonConsoleController' => 'applications/daemon/controller/PhabricatorDaemonConsoleController.php',
     'PhabricatorDaemonControl' => 'infrastructure/daemon/PhabricatorDaemonControl.php',
     'PhabricatorDaemonController' => 'applications/daemon/controller/PhabricatorDaemonController.php',
     'PhabricatorDaemonDAO' => 'infrastructure/daemon/storage/PhabricatorDaemonDAO.php',
     'PhabricatorDaemonLog' => 'infrastructure/daemon/storage/PhabricatorDaemonLog.php',
     'PhabricatorDaemonLogEvent' => 'infrastructure/daemon/storage/PhabricatorDaemonLogEvent.php',
     'PhabricatorDaemonLogEventsView' => 'applications/daemon/view/PhabricatorDaemonLogEventsView.php',
     'PhabricatorDaemonLogListController' => 'applications/daemon/controller/PhabricatorDaemonLogListController.php',
     'PhabricatorDaemonLogListView' => 'applications/daemon/view/PhabricatorDaemonLogListView.php',
     'PhabricatorDaemonLogViewController' => 'applications/daemon/controller/PhabricatorDaemonLogViewController.php',
     'PhabricatorDaemonReference' => 'infrastructure/daemon/control/PhabricatorDaemonReference.php',
     'PhabricatorDebugController' => 'applications/system/PhabricatorDebugController.php',
     'PhabricatorDefaultFileStorageEngineSelector' => 'applications/files/engineselector/PhabricatorDefaultFileStorageEngineSelector.php',
     'PhabricatorDefaultSearchEngineSelector' => 'applications/search/selector/PhabricatorDefaultSearchEngineSelector.php',
     'PhabricatorDeveloperConfigOptions' => 'applications/config/option/PhabricatorDeveloperConfigOptions.php',
     'PhabricatorDifferenceEngine' => 'infrastructure/diff/PhabricatorDifferenceEngine.php',
     'PhabricatorDifferentialConfigOptions' => 'applications/differential/config/PhabricatorDifferentialConfigOptions.php',
     'PhabricatorDiffusionConfigOptions' => 'applications/diffusion/config/PhabricatorDiffusionConfigOptions.php',
     'PhabricatorDirectoryController' => 'applications/directory/controller/PhabricatorDirectoryController.php',
     'PhabricatorDirectoryMainController' => 'applications/directory/controller/PhabricatorDirectoryMainController.php',
     'PhabricatorDisabledUserController' => 'applications/auth/controller/PhabricatorDisabledUserController.php',
     'PhabricatorDisqusConfigOptions' => 'applications/config/option/PhabricatorDisqusConfigOptions.php',
     'PhabricatorDraft' => 'applications/draft/storage/PhabricatorDraft.php',
     'PhabricatorDraftDAO' => 'applications/draft/storage/PhabricatorDraftDAO.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',
     'PhabricatorEditor' => 'infrastructure/PhabricatorEditor.php',
     'PhabricatorEmailLoginController' => 'applications/auth/controller/PhabricatorEmailLoginController.php',
     'PhabricatorEmailTokenController' => 'applications/auth/controller/PhabricatorEmailTokenController.php',
     'PhabricatorEmailVerificationController' => 'applications/people/controller/PhabricatorEmailVerificationController.php',
     'PhabricatorEmptyQueryException' => 'infrastructure/query/PhabricatorEmptyQueryException.php',
     'PhabricatorEnglishTranslation' => 'infrastructure/internationalization/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',
     'PhabricatorEventType' => 'infrastructure/events/constant/PhabricatorEventType.php',
     'PhabricatorExampleEventListener' => 'infrastructure/events/PhabricatorExampleEventListener.php',
     'PhabricatorExtendingPhabricatorConfigOptions' => 'applications/config/option/PhabricatorExtendingPhabricatorConfigOptions.php',
     'PhabricatorFacebookConfigOptions' => 'applications/config/option/PhabricatorFacebookConfigOptions.php',
     'PhabricatorFactAggregate' => 'applications/fact/storage/PhabricatorFactAggregate.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',
     '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',
     'PhabricatorFeedMainController' => 'applications/feed/controller/PhabricatorFeedMainController.php',
     'PhabricatorFeedPublicStreamController' => 'applications/feed/controller/PhabricatorFeedPublicStreamController.php',
     'PhabricatorFeedQuery' => 'applications/feed/PhabricatorFeedQuery.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',
     'PhabricatorFeedStoryManiphest' => 'applications/feed/story/PhabricatorFeedStoryManiphest.php',
     'PhabricatorFeedStoryManiphestAggregate' => 'applications/feed/story/PhabricatorFeedStoryManiphestAggregate.php',
     'PhabricatorFeedStoryNotification' => 'applications/notification/storage/PhabricatorFeedStoryNotification.php',
     'PhabricatorFeedStoryPhriction' => 'applications/feed/story/PhabricatorFeedStoryPhriction.php',
     'PhabricatorFeedStoryProject' => 'applications/feed/story/PhabricatorFeedStoryProject.php',
     'PhabricatorFeedStoryPublisher' => 'applications/feed/PhabricatorFeedStoryPublisher.php',
     'PhabricatorFeedStoryReference' => 'applications/feed/storage/PhabricatorFeedStoryReference.php',
     'PhabricatorFeedStoryStatus' => 'applications/feed/story/PhabricatorFeedStoryStatus.php',
     'PhabricatorFeedStoryTypeConstants' => 'applications/feed/constants/PhabricatorFeedStoryTypeConstants.php',
     'PhabricatorFeedStoryView' => 'applications/feed/view/PhabricatorFeedStoryView.php',
     'PhabricatorFeedView' => 'applications/feed/view/PhabricatorFeedView.php',
     'PhabricatorFile' => 'applications/files/storage/PhabricatorFile.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',
     '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',
     'PhabricatorFileShortcutController' => 'applications/files/controller/PhabricatorFileShortcutController.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',
     'PhabricatorFileTestCase' => 'applications/files/storage/__tests__/PhabricatorFileTestCase.php',
     'PhabricatorFileTransformController' => 'applications/files/controller/PhabricatorFileTransformController.php',
     'PhabricatorFileUploadController' => 'applications/files/controller/PhabricatorFileUploadController.php',
     'PhabricatorFileUploadException' => 'applications/files/exception/PhabricatorFileUploadException.php',
     'PhabricatorFilesConfigOptions' => 'applications/files/config/PhabricatorFilesConfigOptions.php',
     'PhabricatorFilesManagementEnginesWorkflow' => 'applications/files/management/PhabricatorFilesManagementEnginesWorkflow.php',
     'PhabricatorFilesManagementMetadataWorkflow' => 'applications/files/management/PhabricatorFilesManagementMetadataWorkflow.php',
     'PhabricatorFilesManagementMigrateWorkflow' => 'applications/files/management/PhabricatorFilesManagementMigrateWorkflow.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',
     'PhabricatorFlagListView' => 'applications/flag/view/PhabricatorFlagListView.php',
     'PhabricatorFlagQuery' => 'applications/flag/query/PhabricatorFlagQuery.php',
     'PhabricatorFlagsUIEventListener' => 'applications/flag/events/PhabricatorFlagsUIEventListener.php',
     'PhabricatorFormExample' => 'applications/uiexample/examples/PhabricatorFormExample.php',
     'PhabricatorGarbageCollectorConfigOptions' => 'applications/config/option/PhabricatorGarbageCollectorConfigOptions.php',
     'PhabricatorGarbageCollectorDaemon' => 'infrastructure/daemon/PhabricatorGarbageCollectorDaemon.php',
     'PhabricatorGestureExample' => 'applications/uiexample/examples/PhabricatorGestureExample.php',
     'PhabricatorGitGraphStream' => 'applications/repository/daemon/PhabricatorGitGraphStream.php',
     'PhabricatorGitHubConfigOptions' => 'applications/config/option/PhabricatorGitHubConfigOptions.php',
     'PhabricatorGlobalLock' => 'infrastructure/util/PhabricatorGlobalLock.php',
     'PhabricatorGlobalUploadTargetView' => 'applications/files/view/PhabricatorGlobalUploadTargetView.php',
     'PhabricatorGoogleConfigOptions' => 'applications/config/option/PhabricatorGoogleConfigOptions.php',
     'PhabricatorHandleObjectSelectorDataView' => 'applications/phid/handle/view/PhabricatorHandleObjectSelectorDataView.php',
     'PhabricatorHash' => 'infrastructure/util/PhabricatorHash.php',
     'PhabricatorHashTestCase' => 'infrastructure/util/__tests__/PhabricatorHashTestCase.php',
     'PhabricatorHeaderView' => 'view/layout/PhabricatorHeaderView.php',
     'PhabricatorHelpController' => 'applications/help/controller/PhabricatorHelpController.php',
     'PhabricatorHelpKeyboardShortcutController' => 'applications/help/controller/PhabricatorHelpKeyboardShortcutController.php',
     'PhabricatorIRCBot' => 'infrastructure/daemon/bot/PhabricatorIRCBot.php',
     'PhabricatorIRCProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorIRCProtocolAdapter.php',
     'PhabricatorIRCProtocolHandler' => 'infrastructure/daemon/bot/handler/PhabricatorIRCProtocolHandler.php',
     'PhabricatorImageTransformer' => 'applications/files/PhabricatorImageTransformer.php',
     'PhabricatorInfrastructureTestCase' => 'infrastructure/__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',
     'PhabricatorJavelinLinter' => 'infrastructure/lint/linter/PhabricatorJavelinLinter.php',
     'PhabricatorJumpNavHandler' => 'applications/search/engine/PhabricatorJumpNavHandler.php',
     'PhabricatorKeyValueDatabaseCache' => 'applications/cache/PhabricatorKeyValueDatabaseCache.php',
     'PhabricatorLDAPConfigOptions' => 'applications/config/option/PhabricatorLDAPConfigOptions.php',
     'PhabricatorLDAPLoginController' => 'applications/auth/controller/PhabricatorLDAPLoginController.php',
     'PhabricatorLDAPProvider' => 'applications/auth/ldap/PhabricatorLDAPProvider.php',
     'PhabricatorLDAPRegistrationController' => 'applications/auth/controller/PhabricatorLDAPRegistrationController.php',
     'PhabricatorLDAPUnknownUserException' => 'applications/auth/ldap/PhabricatorLDAPUnknownUserException.php',
     'PhabricatorLDAPUnlinkController' => 'applications/auth/controller/PhabricatorLDAPUnlinkController.php',
     'PhabricatorLintEngine' => 'infrastructure/lint/PhabricatorLintEngine.php',
     'PhabricatorLiskDAO' => 'infrastructure/storage/lisk/PhabricatorLiskDAO.php',
     'PhabricatorLocalDiskFileStorageEngine' => 'applications/files/engine/PhabricatorLocalDiskFileStorageEngine.php',
     'PhabricatorLocalTimeTestCase' => 'view/__tests__/PhabricatorLocalTimeTestCase.php',
     'PhabricatorLoginController' => 'applications/auth/controller/PhabricatorLoginController.php',
     'PhabricatorLoginValidateController' => 'applications/auth/controller/PhabricatorLoginValidateController.php',
     'PhabricatorLogoutController' => 'applications/auth/controller/PhabricatorLogoutController.php',
     'PhabricatorMacroCommentController' => 'applications/macro/controller/PhabricatorMacroCommentController.php',
     'PhabricatorMacroConfigOptions' => 'applications/macro/config/PhabricatorMacroConfigOptions.php',
     'PhabricatorMacroController' => 'applications/macro/controller/PhabricatorMacroController.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',
     'PhabricatorMacroMemeController' => 'applications/macro/controller/PhabricatorMacroMemeController.php',
     'PhabricatorMacroMemeDialogController' => 'applications/macro/controller/PhabricatorMacroMemeDialogController.php',
     'PhabricatorMacroReplyHandler' => 'applications/macro/mail/PhabricatorMacroReplyHandler.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',
     'PhabricatorMailImplementationPHPMailerAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php',
     'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php',
     'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php',
     'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php',
     'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/PhabricatorMailReplyHandler.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',
     'PhabricatorManiphestConfigOptions' => 'applications/maniphest/config/PhabricatorManiphestConfigOptions.php',
     'PhabricatorMarkupCache' => 'applications/cache/storage/PhabricatorMarkupCache.php',
     'PhabricatorMarkupEngine' => 'infrastructure/markup/PhabricatorMarkupEngine.php',
     'PhabricatorMarkupInterface' => 'infrastructure/markup/PhabricatorMarkupInterface.php',
     'PhabricatorMenuItemView' => 'view/layout/PhabricatorMenuItemView.php',
     'PhabricatorMenuView' => 'view/layout/PhabricatorMenuView.php',
     'PhabricatorMenuViewTestCase' => 'view/layout/__tests__/PhabricatorMenuViewTestCase.php',
     'PhabricatorMercurialGraphStream' => 'applications/repository/daemon/PhabricatorMercurialGraphStream.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/PhabricatorMetaMTAEmailBodyParser.php',
     'PhabricatorMetaMTAEmailBodyParserTestCase' => 'applications/metamta/__tests__/PhabricatorMetaMTAEmailBodyParserTestCase.php',
     'PhabricatorMetaMTAListController' => 'applications/metamta/controller/PhabricatorMetaMTAListController.php',
     'PhabricatorMetaMTAMail' => 'applications/metamta/storage/PhabricatorMetaMTAMail.php',
     'PhabricatorMetaMTAMailBody' => 'applications/metamta/view/PhabricatorMetaMTAMailBody.php',
     'PhabricatorMetaMTAMailBodyTestCase' => 'applications/metamta/view/__tests__/PhabricatorMetaMTAMailBodyTestCase.php',
     'PhabricatorMetaMTAMailTestCase' => 'applications/metamta/storage/__tests__/PhabricatorMetaMTAMailTestCase.php',
     'PhabricatorMetaMTAMailingList' => 'applications/mailinglists/storage/PhabricatorMetaMTAMailingList.php',
     'PhabricatorMetaMTAReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTAReceiveController.php',
     'PhabricatorMetaMTAReceivedListController' => 'applications/metamta/controller/PhabricatorMetaMTAReceivedListController.php',
     'PhabricatorMetaMTAReceivedMail' => 'applications/metamta/storage/PhabricatorMetaMTAReceivedMail.php',
     'PhabricatorMetaMTASendController' => 'applications/metamta/controller/PhabricatorMetaMTASendController.php',
     'PhabricatorMetaMTASendGridReceiveController' => 'applications/metamta/controller/PhabricatorMetaMTASendGridReceiveController.php',
     'PhabricatorMetaMTAViewController' => 'applications/metamta/controller/PhabricatorMetaMTAViewController.php',
     'PhabricatorMetaMTAWorker' => 'applications/metamta/PhabricatorMetaMTAWorker.php',
     'PhabricatorMustVerifyEmailController' => 'applications/auth/controller/PhabricatorMustVerifyEmailController.php',
     'PhabricatorMySQLConfigOptions' => 'applications/config/option/PhabricatorMySQLConfigOptions.php',
     'PhabricatorMySQLFileStorageEngine' => 'applications/files/engine/PhabricatorMySQLFileStorageEngine.php',
     'PhabricatorNoteExample' => 'applications/uiexample/examples/PhabricatorNoteExample.php',
     'PhabricatorNotificationBuilder' => 'applications/notification/builder/PhabricatorNotificationBuilder.php',
     'PhabricatorNotificationClearController' => 'applications/notification/controller/PhabricatorNotificationClearController.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/PhabricatorNotificationQuery.php',
     'PhabricatorNotificationStatusController' => 'applications/notification/controller/PhabricatorNotificationStatusController.php',
     'PhabricatorOAuthClientAuthorization' => 'applications/oauthserver/storage/PhabricatorOAuthClientAuthorization.php',
     'PhabricatorOAuthClientAuthorizationBaseController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationBaseController.php',
     'PhabricatorOAuthClientAuthorizationDeleteController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationDeleteController.php',
     'PhabricatorOAuthClientAuthorizationEditController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationEditController.php',
     'PhabricatorOAuthClientAuthorizationListController' => 'applications/oauthserver/controller/clientauthorization/PhabricatorOAuthClientAuthorizationListController.php',
     'PhabricatorOAuthClientAuthorizationQuery' => 'applications/oauthserver/query/PhabricatorOAuthClientAuthorizationQuery.php',
     'PhabricatorOAuthClientBaseController' => 'applications/oauthserver/controller/client/PhabricatorOAuthClientBaseController.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',
     'PhabricatorOAuthDefaultRegistrationController' => 'applications/auth/controller/oauthregistration/PhabricatorOAuthDefaultRegistrationController.php',
     'PhabricatorOAuthDiagnosticsController' => 'applications/auth/controller/PhabricatorOAuthDiagnosticsController.php',
     'PhabricatorOAuthFailureView' => 'applications/auth/view/PhabricatorOAuthFailureView.php',
     'PhabricatorOAuthLoginController' => 'applications/auth/controller/PhabricatorOAuthLoginController.php',
     'PhabricatorOAuthProvider' => 'applications/auth/oauth/provider/PhabricatorOAuthProvider.php',
     'PhabricatorOAuthProviderDisqus' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderDisqus.php',
     'PhabricatorOAuthProviderException' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderException.php',
     'PhabricatorOAuthProviderFacebook' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderFacebook.php',
     'PhabricatorOAuthProviderGitHub' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderGitHub.php',
     'PhabricatorOAuthProviderGoogle' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderGoogle.php',
     'PhabricatorOAuthProviderPhabricator' => 'applications/auth/oauth/provider/PhabricatorOAuthProviderPhabricator.php',
     'PhabricatorOAuthRegistrationController' => 'applications/auth/controller/oauthregistration/PhabricatorOAuthRegistrationController.php',
     'PhabricatorOAuthResponse' => 'applications/oauthserver/PhabricatorOAuthResponse.php',
     'PhabricatorOAuthServer' => 'applications/oauthserver/PhabricatorOAuthServer.php',
     'PhabricatorOAuthServerAccessToken' => 'applications/oauthserver/storage/PhabricatorOAuthServerAccessToken.php',
     'PhabricatorOAuthServerAuthController' => 'applications/oauthserver/controller/PhabricatorOAuthServerAuthController.php',
     'PhabricatorOAuthServerAuthorizationCode' => 'applications/oauthserver/storage/PhabricatorOAuthServerAuthorizationCode.php',
     'PhabricatorOAuthServerClient' => 'applications/oauthserver/storage/PhabricatorOAuthServerClient.php',
     'PhabricatorOAuthServerClientQuery' => 'applications/oauthserver/query/PhabricatorOAuthServerClientQuery.php',
     'PhabricatorOAuthServerController' => 'applications/oauthserver/controller/PhabricatorOAuthServerController.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',
     'PhabricatorOAuthUnlinkController' => 'applications/auth/controller/PhabricatorOAuthUnlinkController.php',
     'PhabricatorObjectHandle' => 'applications/phid/PhabricatorObjectHandle.php',
     'PhabricatorObjectHandleConstants' => 'applications/phid/handle/const/PhabricatorObjectHandleConstants.php',
     'PhabricatorObjectHandleData' => 'applications/phid/handle/PhabricatorObjectHandleData.php',
     'PhabricatorObjectHandleStatus' => 'applications/phid/handle/const/PhabricatorObjectHandleStatus.php',
     'PhabricatorObjectItemListExample' => 'applications/uiexample/examples/PhabricatorObjectItemListExample.php',
     'PhabricatorObjectItemListView' => 'view/layout/PhabricatorObjectItemListView.php',
     'PhabricatorObjectItemView' => 'view/layout/PhabricatorObjectItemView.php',
     'PhabricatorObjectListView' => 'view/control/PhabricatorObjectListView.php',
     'PhabricatorObjectSelectorDialog' => 'view/control/PhabricatorObjectSelectorDialog.php',
     'PhabricatorOffsetPagedQuery' => 'infrastructure/query/PhabricatorOffsetPagedQuery.php',
     'PhabricatorOwnerPathQuery' => 'applications/owners/query/PhabricatorOwnerPathQuery.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',
     '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',
     'PhabricatorPHIDConfigOptions' => 'applications/phid/config/PhabricatorPHIDConfigOptions.php',
     'PhabricatorPHIDConstants' => 'applications/phid/PhabricatorPHIDConstants.php',
     'PhabricatorPHIDController' => 'applications/phid/controller/PhabricatorPHIDController.php',
     'PhabricatorPHIDLookupController' => 'applications/phid/controller/PhabricatorPHIDLookupController.php',
     'PhabricatorPHPMailerConfigOptions' => 'applications/config/option/PhabricatorPHPMailerConfigOptions.php',
     'PhabricatorPaste' => 'applications/paste/storage/PhabricatorPaste.php',
     'PhabricatorPasteController' => 'applications/paste/controller/PhabricatorPasteController.php',
     'PhabricatorPasteDAO' => 'applications/paste/storage/PhabricatorPasteDAO.php',
     'PhabricatorPasteEditController' => 'applications/paste/controller/PhabricatorPasteEditController.php',
     'PhabricatorPasteListController' => 'applications/paste/controller/PhabricatorPasteListController.php',
     'PhabricatorPasteQuery' => 'applications/paste/query/PhabricatorPasteQuery.php',
     'PhabricatorPasteRemarkupRule' => 'applications/paste/remarkup/PhabricatorPasteRemarkupRule.php',
     'PhabricatorPasteViewController' => 'applications/paste/controller/PhabricatorPasteViewController.php',
     'PhabricatorPeopleController' => 'applications/people/controller/PhabricatorPeopleController.php',
     'PhabricatorPeopleEditController' => 'applications/people/controller/PhabricatorPeopleEditController.php',
     'PhabricatorPeopleLdapController' => 'applications/people/controller/PhabricatorPeopleLdapController.php',
     'PhabricatorPeopleListController' => 'applications/people/controller/PhabricatorPeopleListController.php',
     'PhabricatorPeopleLogsController' => 'applications/people/controller/PhabricatorPeopleLogsController.php',
     'PhabricatorPeopleProfileController' => 'applications/people/controller/PhabricatorPeopleProfileController.php',
     'PhabricatorPeopleQuery' => 'applications/people/PhabricatorPeopleQuery.php',
     'PhabricatorPhabricatorOAuthConfigOptions' => 'applications/config/option/PhabricatorPhabricatorOAuthConfigOptions.php',
     'PhabricatorPhameConfigOptions' => 'applications/phame/config/PhabricatorPhameConfigOptions.php',
     'PhabricatorPholioConfigOptions' => 'applications/pholio/config/PhabricatorPholioConfigOptions.php',
     'PhabricatorPhrictionConfigOptions' => 'applications/phriction/config/PhabricatorPhrictionConfigOptions.php',
     'PhabricatorPinboardItemView' => 'view/layout/PhabricatorPinboardItemView.php',
     'PhabricatorPinboardView' => 'view/layout/PhabricatorPinboardView.php',
     'PhabricatorPolicies' => 'applications/policy/constants/PhabricatorPolicies.php',
     'PhabricatorPolicy' => 'applications/policy/filter/PhabricatorPolicy.php',
     'PhabricatorPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorPolicyAwareQuery.php',
     'PhabricatorPolicyAwareTestQuery' => 'applications/policy/__tests__/PhabricatorPolicyAwareTestQuery.php',
     'PhabricatorPolicyCapability' => 'applications/policy/constants/PhabricatorPolicyCapability.php',
     'PhabricatorPolicyConfigOptions' => 'applications/config/option/PhabricatorPolicyConfigOptions.php',
     'PhabricatorPolicyConstants' => 'applications/policy/constants/PhabricatorPolicyConstants.php',
     'PhabricatorPolicyException' => 'applications/policy/exception/PhabricatorPolicyException.php',
     'PhabricatorPolicyFilter' => 'applications/policy/filter/PhabricatorPolicyFilter.php',
     'PhabricatorPolicyInterface' => 'applications/policy/interface/PhabricatorPolicyInterface.php',
     'PhabricatorPolicyQuery' => 'applications/policy/query/PhabricatorPolicyQuery.php',
     'PhabricatorPolicyTestCase' => 'applications/policy/__tests__/PhabricatorPolicyTestCase.php',
     'PhabricatorPolicyTestObject' => 'applications/policy/__tests__/PhabricatorPolicyTestObject.php',
     'PhabricatorPolicyType' => 'applications/policy/constants/PhabricatorPolicyType.php',
     'PhabricatorProfileHeaderView' => 'view/layout/PhabricatorProfileHeaderView.php',
     'PhabricatorProject' => 'applications/project/storage/PhabricatorProject.php',
     'PhabricatorProjectConstants' => 'applications/project/constants/PhabricatorProjectConstants.php',
     'PhabricatorProjectController' => 'applications/project/controller/PhabricatorProjectController.php',
     'PhabricatorProjectCreateController' => 'applications/project/controller/PhabricatorProjectCreateController.php',
     'PhabricatorProjectDAO' => 'applications/project/storage/PhabricatorProjectDAO.php',
     'PhabricatorProjectEditor' => 'applications/project/editor/PhabricatorProjectEditor.php',
     'PhabricatorProjectEditorTestCase' => 'applications/project/editor/__tests__/PhabricatorProjectEditorTestCase.php',
     'PhabricatorProjectListController' => 'applications/project/controller/PhabricatorProjectListController.php',
     'PhabricatorProjectMembersEditController' => 'applications/project/controller/PhabricatorProjectMembersEditController.php',
     'PhabricatorProjectNameCollisionException' => 'applications/project/exception/PhabricatorProjectNameCollisionException.php',
     'PhabricatorProjectProfile' => 'applications/project/storage/PhabricatorProjectProfile.php',
     'PhabricatorProjectProfileController' => 'applications/project/controller/PhabricatorProjectProfileController.php',
     'PhabricatorProjectProfileEditController' => 'applications/project/controller/PhabricatorProjectProfileEditController.php',
     'PhabricatorProjectQuery' => 'applications/project/query/PhabricatorProjectQuery.php',
     'PhabricatorProjectStatus' => 'applications/project/constants/PhabricatorProjectStatus.php',
     'PhabricatorProjectTransaction' => 'applications/project/storage/PhabricatorProjectTransaction.php',
     'PhabricatorProjectTransactionType' => 'applications/project/constants/PhabricatorProjectTransactionType.php',
     'PhabricatorProjectUpdateController' => 'applications/project/controller/PhabricatorProjectUpdateController.php',
     'PhabricatorPropertyListExample' => 'applications/uiexample/examples/PhabricatorPropertyListExample.php',
     'PhabricatorPropertyListView' => 'view/layout/PhabricatorPropertyListView.php',
     'PhabricatorQuery' => 'infrastructure/query/PhabricatorQuery.php',
     'PhabricatorRecaptchaConfigOptions' => 'applications/config/option/PhabricatorRecaptchaConfigOptions.php',
     'PhabricatorRedirectController' => 'applications/base/controller/PhabricatorRedirectController.php',
     'PhabricatorRefreshCSRFController' => 'applications/auth/controller/PhabricatorRefreshCSRFController.php',
     'PhabricatorRemarkupControl' => 'view/form/control/PhabricatorRemarkupControl.php',
     'PhabricatorRemarkupRuleEmbedFile' => 'applications/files/remarkup/PhabricatorRemarkupRuleEmbedFile.php',
     'PhabricatorRemarkupRuleImageMacro' => 'applications/macro/remarkup/PhabricatorRemarkupRuleImageMacro.php',
     'PhabricatorRemarkupRuleMeme' => 'applications/macro/remarkup/PhabricatorRemarkupRuleMeme.php',
     'PhabricatorRemarkupRuleMention' => 'applications/people/remarkup/PhabricatorRemarkupRuleMention.php',
     'PhabricatorRemarkupRuleObject' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleObject.php',
     'PhabricatorRemarkupRuleYoutube' => 'infrastructure/markup/rule/PhabricatorRemarkupRuleYoutube.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',
     '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',
     'PhabricatorRepositoryCommitParserWorker' => 'applications/repository/worker/PhabricatorRepositoryCommitParserWorker.php',
     'PhabricatorRepositoryCommitSearchIndexer' => 'applications/repository/search/PhabricatorRepositoryCommitSearchIndexer.php',
     'PhabricatorRepositoryConfigOptions' => 'applications/repository/PhabricatorRepositoryConfigOptions.php',
     'PhabricatorRepositoryController' => 'applications/repository/controller/PhabricatorRepositoryController.php',
     'PhabricatorRepositoryCreateController' => 'applications/repository/controller/PhabricatorRepositoryCreateController.php',
     'PhabricatorRepositoryDAO' => 'applications/repository/storage/PhabricatorRepositoryDAO.php',
     'PhabricatorRepositoryDeleteController' => 'applications/repository/controller/PhabricatorRepositoryDeleteController.php',
     'PhabricatorRepositoryEditController' => 'applications/repository/controller/PhabricatorRepositoryEditController.php',
     'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryGitCommitChangeParserWorker.php',
     'PhabricatorRepositoryGitCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryGitCommitMessageParserWorker.php',
     'PhabricatorRepositoryListController' => 'applications/repository/controller/PhabricatorRepositoryListController.php',
     'PhabricatorRepositoryManagementDeleteWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDeleteWorkflow.php',
     'PhabricatorRepositoryManagementDiscoverWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementDiscoverWorkflow.php',
     'PhabricatorRepositoryManagementListWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementListWorkflow.php',
     'PhabricatorRepositoryManagementPullWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementPullWorkflow.php',
     'PhabricatorRepositoryManagementWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementWorkflow.php',
     'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryMercurialCommitChangeParserWorker.php',
     'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryMercurialCommitMessageParserWorker.php',
     'PhabricatorRepositoryPullLocalDaemon' => 'applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php',
     'PhabricatorRepositoryPullLocalDaemonTestCase' => 'applications/repository/daemon/__tests__/PhabricatorRepositoryPullLocalDaemonTestCase.php',
     'PhabricatorRepositoryQuery' => 'applications/repository/query/PhabricatorRepositoryQuery.php',
     'PhabricatorRepositoryShortcut' => 'applications/repository/storage/PhabricatorRepositoryShortcut.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',
     'PhabricatorRepositoryType' => 'applications/repository/constants/PhabricatorRepositoryType.php',
     'PhabricatorS3FileStorageEngine' => 'applications/files/engine/PhabricatorS3FileStorageEngine.php',
     'PhabricatorSQLPatchList' => 'infrastructure/storage/patch/PhabricatorSQLPatchList.php',
     'PhabricatorSSHWorkflow' => 'infrastructure/ssh/PhabricatorSSHWorkflow.php',
     'PhabricatorScopedEnv' => 'infrastructure/env/PhabricatorScopedEnv.php',
     'PhabricatorSearchAbstractDocument' => 'applications/search/index/PhabricatorSearchAbstractDocument.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',
     'PhabricatorSearchDocument' => 'applications/search/storage/document/PhabricatorSearchDocument.php',
     'PhabricatorSearchDocumentField' => 'applications/search/storage/document/PhabricatorSearchDocumentField.php',
     'PhabricatorSearchDocumentIndexer' => 'applications/search/index/PhabricatorSearchDocumentIndexer.php',
     'PhabricatorSearchDocumentRelationship' => 'applications/search/storage/document/PhabricatorSearchDocumentRelationship.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',
     'PhabricatorSearchIndexer' => 'applications/search/index/PhabricatorSearchIndexer.php',
     'PhabricatorSearchManagementIndexWorkflow' => 'applications/search/management/PhabricatorSearchManagementIndexWorkflow.php',
     'PhabricatorSearchManagementWorkflow' => 'applications/search/management/PhabricatorSearchManagementWorkflow.php',
     'PhabricatorSearchQuery' => 'applications/search/storage/PhabricatorSearchQuery.php',
     'PhabricatorSearchRelationship' => 'applications/search/constants/PhabricatorSearchRelationship.php',
     'PhabricatorSearchResultView' => 'applications/search/view/PhabricatorSearchResultView.php',
     'PhabricatorSearchScope' => 'applications/search/constants/PhabricatorSearchScope.php',
     'PhabricatorSearchSelectController' => 'applications/search/controller/PhabricatorSearchSelectController.php',
     'PhabricatorSecurityConfigOptions' => 'applications/config/option/PhabricatorSecurityConfigOptions.php',
     'PhabricatorSendGridConfigOptions' => 'applications/config/option/PhabricatorSendGridConfigOptions.php',
     'PhabricatorSettingsAdjustController' => 'applications/settings/controller/PhabricatorSettingsAdjustController.php',
     'PhabricatorSettingsMainController' => 'applications/settings/controller/PhabricatorSettingsMainController.php',
     'PhabricatorSettingsPanel' => 'applications/settings/panel/PhabricatorSettingsPanel.php',
     'PhabricatorSettingsPanelAccount' => 'applications/settings/panel/PhabricatorSettingsPanelAccount.php',
     'PhabricatorSettingsPanelConduit' => 'applications/settings/panel/PhabricatorSettingsPanelConduit.php',
     'PhabricatorSettingsPanelDiffPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDiffPreferences.php',
     'PhabricatorSettingsPanelDisplayPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php',
     'PhabricatorSettingsPanelEmailAddresses' => 'applications/settings/panel/PhabricatorSettingsPanelEmailAddresses.php',
     'PhabricatorSettingsPanelEmailPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelEmailPreferences.php',
     'PhabricatorSettingsPanelHomePreferences' => 'applications/settings/panel/PhabricatorSettingsPanelHomePreferences.php',
     'PhabricatorSettingsPanelLDAP' => 'applications/settings/panel/PhabricatorSettingsPanelLDAP.php',
     'PhabricatorSettingsPanelOAuth' => 'applications/settings/panel/PhabricatorSettingsPanelOAuth.php',
     'PhabricatorSettingsPanelPassword' => 'applications/settings/panel/PhabricatorSettingsPanelPassword.php',
     'PhabricatorSettingsPanelProfile' => 'applications/settings/panel/PhabricatorSettingsPanelProfile.php',
     'PhabricatorSettingsPanelSSHKeys' => 'applications/settings/panel/PhabricatorSettingsPanelSSHKeys.php',
     'PhabricatorSettingsPanelSearchPreferences' => 'applications/settings/panel/PhabricatorSettingsPanelSearchPreferences.php',
     'PhabricatorSetupCheck' => 'applications/config/check/PhabricatorSetupCheck.php',
     'PhabricatorSetupCheckAPC' => 'applications/config/check/PhabricatorSetupCheckAPC.php',
     'PhabricatorSetupCheckBaseURI' => 'applications/config/check/PhabricatorSetupCheckBaseURI.php',
     'PhabricatorSetupCheckDatabase' => 'applications/config/check/PhabricatorSetupCheckDatabase.php',
     'PhabricatorSetupCheckExtensions' => 'applications/config/check/PhabricatorSetupCheckExtensions.php',
     'PhabricatorSetupCheckExtraConfig' => 'applications/config/check/PhabricatorSetupCheckExtraConfig.php',
     'PhabricatorSetupCheckFacebook' => 'applications/config/check/PhabricatorSetupCheckFacebook.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',
     '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',
     'PhabricatorSlowvoteChoice' => 'applications/slowvote/storage/PhabricatorSlowvoteChoice.php',
     'PhabricatorSlowvoteComment' => 'applications/slowvote/storage/PhabricatorSlowvoteComment.php',
     'PhabricatorSlowvoteController' => 'applications/slowvote/controller/PhabricatorSlowvoteController.php',
     'PhabricatorSlowvoteCreateController' => 'applications/slowvote/controller/PhabricatorSlowvoteCreateController.php',
     'PhabricatorSlowvoteDAO' => 'applications/slowvote/storage/PhabricatorSlowvoteDAO.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',
     'PhabricatorSlug' => 'infrastructure/util/PhabricatorSlug.php',
     'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php',
     'PhabricatorSortTableExample' => 'applications/uiexample/examples/PhabricatorSortTableExample.php',
     'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php',
     'PhabricatorStandardPageView' => 'view/page/PhabricatorStandardPageView.php',
     'PhabricatorStatusController' => 'applications/system/PhabricatorStatusController.php',
     'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php',
     'PhabricatorStorageManagementAPI' => 'infrastructure/storage/management/PhabricatorStorageManagementAPI.php',
     'PhabricatorStorageManagementDatabasesWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDatabasesWorkflow.php',
     'PhabricatorStorageManagementDestroyWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDestroyWorkflow.php',
     'PhabricatorStorageManagementDumpWorkflow' => 'infrastructure/storage/management/workflow/PhabricatorStorageManagementDumpWorkflow.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',
     'PhabricatorSubscribableInterface' => 'applications/subscriptions/interface/PhabricatorSubscribableInterface.php',
     'PhabricatorSubscribersQuery' => 'applications/subscriptions/query/PhabricatorSubscribersQuery.php',
     'PhabricatorSubscriptionsEditController' => 'applications/subscriptions/controller/PhabricatorSubscriptionsEditController.php',
     'PhabricatorSubscriptionsEditor' => 'applications/subscriptions/editor/PhabricatorSubscriptionsEditor.php',
     'PhabricatorSubscriptionsUIEventListener' => 'applications/subscriptions/events/PhabricatorSubscriptionsUIEventListener.php',
     'PhabricatorSymbolNameLinter' => 'infrastructure/lint/hook/PhabricatorSymbolNameLinter.php',
     'PhabricatorSyntaxHighlighter' => 'infrastructure/markup/PhabricatorSyntaxHighlighter.php',
     'PhabricatorSyntaxHighlightingConfigOptions' => 'applications/config/option/PhabricatorSyntaxHighlightingConfigOptions.php',
     'PhabricatorTagExample' => 'applications/uiexample/examples/PhabricatorTagExample.php',
     'PhabricatorTagView' => 'view/layout/PhabricatorTagView.php',
     'PhabricatorTaskmasterDaemon' => 'infrastructure/daemon/workers/PhabricatorTaskmasterDaemon.php',
     'PhabricatorTestCase' => 'infrastructure/testing/PhabricatorTestCase.php',
     'PhabricatorTestStorageEngine' => 'applications/files/engine/PhabricatorTestStorageEngine.php',
     'PhabricatorTestWorker' => 'infrastructure/daemon/workers/__tests__/PhabricatorTestWorker.php',
     'PhabricatorTimelineCursor' => 'infrastructure/daemon/timeline/storage/PhabricatorTimelineCursor.php',
     'PhabricatorTimelineDAO' => 'infrastructure/daemon/timeline/storage/PhabricatorTimelineDAO.php',
     'PhabricatorTimelineEvent' => 'infrastructure/daemon/timeline/storage/PhabricatorTimelineEvent.php',
     'PhabricatorTimelineEventData' => 'infrastructure/daemon/timeline/storage/PhabricatorTimelineEventData.php',
     'PhabricatorTimelineEventView' => 'view/layout/PhabricatorTimelineEventView.php',
     'PhabricatorTimelineExample' => 'applications/uiexample/examples/PhabricatorTimelineExample.php',
     'PhabricatorTimelineIterator' => 'infrastructure/daemon/timeline/cursor/PhabricatorTimelineIterator.php',
     'PhabricatorTimelineView' => 'view/layout/PhabricatorTimelineView.php',
     'PhabricatorTimer' => 'applications/countdown/storage/PhabricatorTimer.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',
     'PhabricatorTokenQuery' => 'applications/tokens/query/PhabricatorTokenQuery.php',
     'PhabricatorTokenReceiverInterface' => 'applications/tokens/interface/PhabricatorTokenReceiverInterface.php',
     'PhabricatorTokenUIEventListener' => 'applications/tokens/event/PhabricatorTokenUIEventListener.php',
     'PhabricatorTransactionView' => 'view/layout/PhabricatorTransactionView.php',
     'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php',
     'PhabricatorTransformedFile' => 'applications/files/storage/PhabricatorTransformedFile.php',
     'PhabricatorTranslation' => 'infrastructure/internationalization/PhabricatorTranslation.php',
     'PhabricatorTranslationsConfigOptions' => 'applications/config/option/PhabricatorTranslationsConfigOptions.php',
     'PhabricatorTrivialTestCase' => 'infrastructure/testing/__tests__/PhabricatorTrivialTestCase.php',
     'PhabricatorTwoColumnExample' => 'applications/uiexample/examples/PhabricatorTwoColumnExample.php',
     'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/PhabricatorTypeaheadCommonDatasourceController.php',
     'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/PhabricatorTypeaheadDatasourceController.php',
     'PhabricatorTypeaheadResult' => 'applications/typeahead/storage/PhabricatorTypeaheadResult.php',
     'PhabricatorUIExample' => 'applications/uiexample/examples/PhabricatorUIExample.php',
     'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/PhabricatorUIExampleRenderController.php',
     'PhabricatorUIListFilterExample' => 'applications/uiexample/examples/PhabricatorUIListFilterExample.php',
     'PhabricatorUINotificationExample' => 'applications/uiexample/examples/PhabricatorUINotificationExample.php',
     'PhabricatorUIPagerExample' => 'applications/uiexample/examples/PhabricatorUIPagerExample.php',
     'PhabricatorUITooltipExample' => 'applications/uiexample/examples/PhabricatorUITooltipExample.php',
     'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php',
     'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php',
     'PhabricatorUserDAO' => 'applications/people/storage/PhabricatorUserDAO.php',
     'PhabricatorUserEditor' => 'applications/people/PhabricatorUserEditor.php',
     'PhabricatorUserEmail' => 'applications/people/storage/PhabricatorUserEmail.php',
     'PhabricatorUserLDAPInfo' => 'applications/people/storage/PhabricatorUserLDAPInfo.php',
     'PhabricatorUserLog' => 'applications/people/storage/PhabricatorUserLog.php',
     'PhabricatorUserOAuthInfo' => 'applications/people/storage/PhabricatorUserOAuthInfo.php',
     'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
     'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
     'PhabricatorUserSSHKey' => 'applications/settings/storage/PhabricatorUserSSHKey.php',
     'PhabricatorUserSearchIndexer' => 'applications/people/search/PhabricatorUserSearchIndexer.php',
     'PhabricatorUserStatus' => 'applications/people/storage/PhabricatorUserStatus.php',
     'PhabricatorUserStatusInvalidEpochException' => 'applications/people/exception/PhabricatorUserStatusInvalidEpochException.php',
     'PhabricatorUserStatusOverlapException' => 'applications/people/exception/PhabricatorUserStatusOverlapException.php',
     'PhabricatorUserTestCase' => 'applications/people/storage/__tests__/PhabricatorUserTestCase.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',
     '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',
     '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',
     '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',
     'PhabricatorXHProfSampleListView' => 'applications/xhprof/view/PhabricatorXHProfSampleListView.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',
     'PhameController' => 'applications/phame/controller/PhameController.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',
     'PhameResourceController' => 'applications/phame/controller/PhameResourceController.php',
     'PhameSkinSpecification' => 'applications/phame/skins/PhameSkinSpecification.php',
     'PholioConstants' => 'applications/pholio/constants/PholioConstants.php',
     'PholioController' => 'applications/pholio/controller/PholioController.php',
     'PholioDAO' => 'applications/pholio/storage/PholioDAO.php',
     'PholioImage' => 'applications/pholio/storage/PholioImage.php',
     'PholioInlineCommentEditView' => 'applications/pholio/view/PholioInlineCommentEditView.php',
     'PholioInlineCommentSaveView' => 'applications/pholio/view/PholioInlineCommentSaveView.php',
     'PholioInlineCommentView' => 'applications/pholio/view/PholioInlineCommentView.php',
     'PholioInlineController' => 'applications/pholio/controller/PholioInlineController.php',
     'PholioInlineDeleteController' => 'applications/pholio/controller/PholioInlineDeleteController.php',
     'PholioInlineEditController' => 'applications/pholio/controller/PholioInlineEditController.php',
     'PholioInlineSaveController' => 'applications/pholio/controller/PholioInlineSaveController.php',
     'PholioInlineViewController' => 'applications/pholio/controller/PholioInlineViewController.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',
     'PholioMockQuery' => 'applications/pholio/query/PholioMockQuery.php',
     'PholioMockViewController' => 'applications/pholio/controller/PholioMockViewController.php',
     'PholioRemarkupRule' => 'applications/pholio/remarkup/PholioRemarkupRule.php',
     'PholioReplyHandler' => 'applications/pholio/mail/PholioReplyHandler.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',
     'PhortuneMonthYearExpiryControl' => 'applications/phortune/control/PhortuneMonthYearExpiryControl.php',
     'PhortuneStripeBaseController' => 'applications/phortune/stripe/controller/PhortuneStripeBaseController.php',
     'PhortuneStripePaymentFormView' => 'applications/phortune/stripe/view/PhortuneStripePaymentFormView.php',
     'PhortuneStripeTestPaymentFormController' => 'applications/phortune/stripe/controller/PhortuneStripeTestPaymentFormController.php',
     'PhrictionActionConstants' => 'applications/phriction/constants/PhrictionActionConstants.php',
     'PhrictionChangeType' => 'applications/phriction/constants/PhrictionChangeType.php',
     'PhrictionConstants' => 'applications/phriction/constants/PhrictionConstants.php',
     'PhrictionContent' => 'applications/phriction/storage/PhrictionContent.php',
     'PhrictionController' => 'applications/phriction/controller/PhrictionController.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',
     'PhrictionDocumentEditor' => 'applications/phriction/editor/PhrictionDocumentEditor.php',
     'PhrictionDocumentPreviewController' => 'applications/phriction/controller/PhrictionDocumentPreviewController.php',
     'PhrictionDocumentQuery' => 'applications/phriction/query/PhrictionDocumentQuery.php',
     'PhrictionDocumentStatus' => 'applications/phriction/constants/PhrictionDocumentStatus.php',
     'PhrictionDocumentTestCase' => 'applications/phriction/storage/__tests__/PhrictionDocumentTestCase.php',
     'PhrictionEditController' => 'applications/phriction/controller/PhrictionEditController.php',
     'PhrictionHistoryController' => 'applications/phriction/controller/PhrictionHistoryController.php',
     'PhrictionListController' => 'applications/phriction/controller/PhrictionListController.php',
     'PhrictionMoveController' => 'applications/phriction/controller/PhrictionMoveController.php',
     'PhrictionNewController' => 'applications/phriction/controller/PhrictionNewController.php',
     'PhrictionRemarkupRule' => 'applications/phriction/remarkup/PhrictionRemarkupRule.php',
     'PhrictionSearchIndexer' => 'applications/phriction/search/PhrictionSearchIndexer.php',
     'PonderAddAnswerView' => 'applications/ponder/view/PonderAddAnswerView.php',
     'PonderAddCommentView' => 'applications/ponder/view/PonderAddCommentView.php',
     'PonderAnswer' => 'applications/ponder/storage/PonderAnswer.php',
     'PonderAnswerEditor' => 'applications/ponder/editor/PonderAnswerEditor.php',
     'PonderAnswerListView' => 'applications/ponder/view/PonderAnswerListView.php',
     'PonderAnswerPreviewController' => 'applications/ponder/controller/PonderAnswerPreviewController.php',
     'PonderAnswerQuery' => 'applications/ponder/query/PonderAnswerQuery.php',
     'PonderAnswerSaveController' => 'applications/ponder/controller/PonderAnswerSaveController.php',
     'PonderAnswerViewController' => 'applications/ponder/controller/PonderAnswerViewController.php',
     'PonderAnsweredMail' => 'applications/ponder/mail/PonderAnsweredMail.php',
     'PonderComment' => 'applications/ponder/storage/PonderComment.php',
     'PonderCommentEditor' => 'applications/ponder/editor/PonderCommentEditor.php',
     'PonderCommentListView' => 'applications/ponder/view/PonderCommentListView.php',
     'PonderCommentMail' => 'applications/ponder/mail/PonderCommentMail.php',
     'PonderCommentQuery' => 'applications/ponder/query/PonderCommentQuery.php',
     'PonderCommentSaveController' => 'applications/ponder/controller/PonderCommentSaveController.php',
     'PonderConstants' => 'applications/ponder/PonderConstants.php',
     'PonderController' => 'applications/ponder/controller/PonderController.php',
     'PonderDAO' => 'applications/ponder/storage/PonderDAO.php',
     'PonderFeedController' => 'applications/ponder/controller/PonderFeedController.php',
     'PonderMail' => 'applications/ponder/mail/PonderMail.php',
     'PonderMentionMail' => 'applications/ponder/mail/PonderMentionMail.php',
     'PonderPostBodyView' => 'applications/ponder/view/PonderPostBodyView.php',
     'PonderQuestion' => 'applications/ponder/storage/PonderQuestion.php',
     'PonderQuestionAskController' => 'applications/ponder/controller/PonderQuestionAskController.php',
     'PonderQuestionDetailView' => 'applications/ponder/view/PonderQuestionDetailView.php',
     'PonderQuestionEditor' => 'applications/ponder/editor/PonderQuestionEditor.php',
     'PonderQuestionPreviewController' => 'applications/ponder/controller/PonderQuestionPreviewController.php',
     'PonderQuestionQuery' => 'applications/ponder/query/PonderQuestionQuery.php',
     'PonderQuestionSummaryView' => 'applications/ponder/view/PonderQuestionSummaryView.php',
     'PonderQuestionViewController' => 'applications/ponder/controller/PonderQuestionViewController.php',
     'PonderRemarkupRule' => 'applications/ponder/remarkup/PonderRemarkupRule.php',
     'PonderReplyHandler' => 'applications/ponder/PonderReplyHandler.php',
     'PonderSearchIndexer' => 'applications/ponder/search/PonderSearchIndexer.php',
     'PonderUserProfileView' => 'applications/ponder/view/PonderUserProfileView.php',
     'PonderVotableInterface' => 'applications/ponder/storage/PonderVotableInterface.php',
     'PonderVotableView' => 'applications/ponder/view/PonderVotableView.php',
     'PonderVoteEditor' => 'applications/ponder/editor/PonderVoteEditor.php',
     'PonderVoteSaveController' => 'applications/ponder/controller/PonderVoteSaveController.php',
     'QueryFormattingTestCase' => 'infrastructure/storage/__tests__/QueryFormattingTestCase.php',
+    'ReleephActiveProjectListView' => 'applications/releeph/view/project/list/ReleephActiveProjectListView.php',
+    'ReleephAuthorFieldSpecification' => 'applications/releeph/field/specification/ReleephAuthorFieldSpecification.php',
+    'ReleephBranch' => 'applications/releeph/storage/ReleephBranch.php',
+    'ReleephBranchAccessController' => 'applications/releeph/controller/branch/ReleephBranchAccessController.php',
+    'ReleephBranchBoxView' => 'applications/releeph/view/branch/ReleephBranchBoxView.php',
+    'ReleephBranchCommitFieldSpecification' => 'applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php',
+    'ReleephBranchCreateController' => 'applications/releeph/controller/branch/ReleephBranchCreateController.php',
+    'ReleephBranchEditController' => 'applications/releeph/controller/branch/ReleephBranchEditController.php',
+    'ReleephBranchEditor' => 'applications/releeph/editor/ReleephBranchEditor.php',
+    'ReleephBranchNamePreviewController' => 'applications/releeph/controller/branch/ReleephBranchNamePreviewController.php',
+    'ReleephBranchPreviewView' => 'applications/releeph/view/branch/ReleephBranchPreviewView.php',
+    'ReleephBranchTemplate' => 'applications/releeph/view/branch/ReleephBranchTemplate.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',
+    'ReleephController' => 'applications/releeph/controller/ReleephController.php',
+    'ReleephDAO' => 'applications/releeph/storage/ReleephDAO.php',
+    'ReleephDefaultFieldSelector' => 'applications/releeph/field/selector/ReleephDefaultFieldSelector.php',
+    'ReleephDefaultUserView' => 'applications/releeph/view/user/ReleephDefaultUserView.php',
+    'ReleephDiffChurnFieldSpecification' => 'applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php',
+    'ReleephDiffMessageFieldSpecification' => 'applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php',
+    'ReleephDiffSizeFieldSpecification' => 'applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php',
+    'ReleephDifferentialRevisionDetailRenderer' => 'applications/releeph/differential/ReleephDifferentialRevisionDetailRenderer.php',
+    'ReleephEvent' => 'applications/releeph/storage/event/ReleephEvent.php',
+    'ReleephFieldParseException' => 'applications/releeph/field/exception/ReleephFieldParseException.php',
+    'ReleephFieldSelector' => 'applications/releeph/field/selector/ReleephFieldSelector.php',
+    'ReleephFieldSpecification' => 'applications/releeph/field/specification/ReleephFieldSpecification.php',
+    'ReleephFieldSpecificationIncompleteException' => 'applications/releeph/field/exception/ReleephFieldSpecificationIncompleteException.php',
+    'ReleephInactiveProjectListView' => 'applications/releeph/view/project/list/ReleephInactiveProjectListView.php',
+    'ReleephIntentFieldSpecification' => 'applications/releeph/field/specification/ReleephIntentFieldSpecification.php',
+    'ReleephLevelFieldSpecification' => 'applications/releeph/field/specification/ReleephLevelFieldSpecification.php',
+    'ReleephObjectHandleLoader' => 'applications/releeph/ReleephObjectHandleLoader.php',
+    'ReleephOriginalCommitFieldSpecification' => 'applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php',
+    'ReleephPHIDConstants' => 'applications/releeph/ReleephPHIDConstants.php',
+    'ReleephProject' => 'applications/releeph/storage/ReleephProject.php',
+    'ReleephProjectActionController' => 'applications/releeph/controller/project/ReleephProjectActionController.php',
+    'ReleephProjectCreateController' => 'applications/releeph/controller/project/ReleephProjectCreateController.php',
+    'ReleephProjectEditController' => 'applications/releeph/controller/project/ReleephProjectEditController.php',
+    'ReleephProjectListController' => 'applications/releeph/controller/project/ReleephProjectListController.php',
+    'ReleephProjectView' => 'applications/releeph/view/ReleephProjectView.php',
+    'ReleephProjectViewController' => 'applications/releeph/controller/project/ReleephProjectViewController.php',
+    'ReleephReasonFieldSpecification' => 'applications/releeph/field/specification/ReleephReasonFieldSpecification.php',
+    'ReleephRequest' => 'applications/releeph/storage/ReleephRequest.php',
+    'ReleephRequestActionController' => 'applications/releeph/controller/request/ReleephRequestActionController.php',
+    'ReleephRequestCreateController' => 'applications/releeph/controller/request/ReleephRequestCreateController.php',
+    'ReleephRequestDifferentialCreateController' => 'applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php',
+    'ReleephRequestEditController' => 'applications/releeph/controller/request/ReleephRequestEditController.php',
+    'ReleephRequestEditor' => 'applications/releeph/editor/ReleephRequestEditor.php',
+    'ReleephRequestEvent' => 'applications/releeph/storage/request/ReleephRequestEvent.php',
+    'ReleephRequestEventListView' => 'applications/releeph/view/requestevent/ReleephRequestEventListView.php',
+    'ReleephRequestException' => 'applications/releeph/storage/request/exception/ReleephRequestException.php',
+    'ReleephRequestHeaderListView' => 'applications/releeph/view/request/header/ReleephRequestHeaderListView.php',
+    'ReleephRequestHeaderView' => 'applications/releeph/view/request/header/ReleephRequestHeaderView.php',
+    'ReleephRequestIntentsView' => 'applications/releeph/view/request/ReleephRequestIntentsView.php',
+    'ReleephRequestMail' => 'applications/releeph/editor/mail/ReleephRequestMail.php',
+    'ReleephRequestStatusView' => 'applications/releeph/view/request/ReleephRequestStatusView.php',
+    'ReleephRequestTypeaheadControl' => 'applications/releeph/view/request/ReleephRequestTypeaheadControl.php',
+    'ReleephRequestTypeaheadController' => 'applications/releeph/controller/request/ReleephRequestTypeaheadController.php',
+    'ReleephRequestViewController' => 'applications/releeph/controller/request/ReleephRequestViewController.php',
+    'ReleephRequestorFieldSpecification' => 'applications/releeph/field/specification/ReleephRequestorFieldSpecification.php',
+    'ReleephRevisionFieldSpecification' => 'applications/releeph/field/specification/ReleephRevisionFieldSpecification.php',
+    'ReleephRiskFieldSpecification' => 'applications/releeph/field/specification/ReleephRiskFieldSpecification.php',
+    'ReleephSeverityFieldSpecification' => 'applications/releeph/field/specification/ReleephSeverityFieldSpecification.php',
+    'ReleephStatusFieldSpecification' => 'applications/releeph/field/specification/ReleephStatusFieldSpecification.php',
+    'ReleephSummaryFieldSpecification' => 'applications/releeph/field/specification/ReleephSummaryFieldSpecification.php',
+    'ReleephUserView' => 'applications/releeph/view/user/ReleephUserView.php',
   ),
   'function' =>
   array(
     '_phabricator_date_format' => 'view/viewutils.php',
     'celerity_generate_unique_node_id' => 'infrastructure/celerity/api.php',
     'celerity_get_resource_uri' => 'infrastructure/celerity/api.php',
     'celerity_register_resource_map' => 'infrastructure/celerity/map.php',
     'javelin_render_tag' => 'infrastructure/javelin/markup.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_bytes' => 'view/viewutils.php',
     'phabricator_format_local_time' => 'view/viewutils.php',
     'phabricator_format_relative_time' => 'view/viewutils.php',
     'phabricator_format_relative_time_detailed' => 'view/viewutils.php',
     'phabricator_format_units_generic' => 'view/viewutils.php',
     'phabricator_on_relative_date' => 'view/viewutils.php',
     'phabricator_parse_bytes' => 'view/viewutils.php',
     'phabricator_relative_date' => 'view/viewutils.php',
     'phabricator_render_form' => 'infrastructure/javelin/markup.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' => 'infrastructure/celerity/api.php',
   ),
   'xmap' =>
   array(
     'Aphront304Response' => 'AphrontResponse',
     'Aphront400Response' => 'AphrontResponse',
     'Aphront403Response' => 'AphrontHTMLResponse',
     'Aphront404Response' => 'AphrontHTMLResponse',
     'AphrontAjaxResponse' => 'AphrontResponse',
     'AphrontAttachedFileView' => 'AphrontView',
     'AphrontBarView' => 'AphrontView',
     'AphrontCSRFException' => 'AphrontException',
     'AphrontCalendarEventView' => 'AphrontView',
     'AphrontCalendarMonthView' => 'AphrontView',
     'AphrontContextBarView' => 'AphrontView',
     'AphrontController' => 'Phobject',
     'AphrontCursorPagerView' => 'AphrontView',
     'AphrontDefaultApplicationConfiguration' => 'AphrontApplicationConfiguration',
     'AphrontDialogResponse' => 'AphrontResponse',
     'AphrontDialogView' => 'AphrontView',
     'AphrontErrorView' => 'AphrontView',
     'AphrontException' => 'Exception',
     'AphrontFileResponse' => 'AphrontResponse',
     'AphrontFormCheckboxControl' => 'AphrontFormControl',
     'AphrontFormControl' => 'AphrontView',
     'AphrontFormCountedToggleButtonsControl' => 'AphrontFormControl',
     'AphrontFormCropControl' => 'AphrontFormControl',
     'AphrontFormDateControl' => 'AphrontFormControl',
     'AphrontFormDividerControl' => 'AphrontFormControl',
     'AphrontFormDragAndDropUploadControl' => 'AphrontFormControl',
     'AphrontFormFileControl' => 'AphrontFormControl',
     'AphrontFormImageControl' => 'AphrontFormControl',
     'AphrontFormInsetView' => 'AphrontView',
     'AphrontFormLayoutView' => 'AphrontView',
     'AphrontFormMarkupControl' => 'AphrontFormControl',
     'AphrontFormPasswordControl' => 'AphrontFormControl',
     'AphrontFormPolicyControl' => 'AphrontFormControl',
     'AphrontFormRadioButtonControl' => 'AphrontFormControl',
     'AphrontFormRecaptchaControl' => 'AphrontFormControl',
     'AphrontFormSelectControl' => 'AphrontFormControl',
     'AphrontFormStaticControl' => 'AphrontFormControl',
     'AphrontFormSubmitControl' => 'AphrontFormControl',
     'AphrontFormTextAreaControl' => 'AphrontFormControl',
     'AphrontFormTextControl' => 'AphrontFormControl',
     'AphrontFormToggleButtonsControl' => 'AphrontFormControl',
     'AphrontFormTokenizerControl' => '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',
     'AphrontMySQLDatabaseConnectionTestCase' => 'PhabricatorTestCase',
     'AphrontNoteView' => 'AphrontView',
     'AphrontNullView' => 'AphrontView',
     'AphrontPHPHTTPSink' => 'AphrontHTTPSink',
     'AphrontPageView' => 'AphrontView',
     'AphrontPagerView' => 'AphrontView',
     'AphrontPanelView' => 'AphrontView',
     'AphrontPlainTextResponse' => 'AphrontResponse',
     'AphrontProgressBarView' => 'AphrontBarView',
     'AphrontProxyResponse' => 'AphrontResponse',
     'AphrontRedirectException' => 'AphrontException',
     'AphrontRedirectResponse' => 'AphrontResponse',
     'AphrontReloadResponse' => 'AphrontRedirectResponse',
     'AphrontRequestFailureView' => 'AphrontView',
     'AphrontRequestTestCase' => 'PhabricatorTestCase',
     'AphrontSideNavFilterView' => 'AphrontView',
     'AphrontTableView' => 'AphrontView',
     'AphrontTagView' => 'AphrontView',
     'AphrontTokenizerTemplateView' => 'AphrontView',
     'AphrontTwoColumnView' => 'AphrontView',
     'AphrontTypeaheadTemplateView' => 'AphrontView',
     'AphrontUsageException' => 'AphrontException',
     'AphrontView' =>
     array(
       0 => 'Phobject',
       1 => 'PhutilSafeHTMLProducerInterface',
     ),
     'AphrontWebpageResponse' => 'AphrontHTMLResponse',
     'AuditPeopleMenuEventListener' => 'PhutilEventListener',
     'CelerityPhabricatorResourceController' => 'CelerityResourceController',
     'CelerityResourceController' => 'PhabricatorController',
     'CelerityResourceGraph' => 'AbstractDirectedGraph',
     'CelerityResourceTransformerTestCase' => 'PhabricatorTestCase',
     'ConduitAPI_arcanist_Method' => 'ConduitAPIMethod',
     'ConduitAPI_arcanist_projectinfo_Method' => 'ConduitAPI_arcanist_Method',
     'ConduitAPI_audit_Method' => 'ConduitAPIMethod',
     'ConduitAPI_audit_query_Method' => 'ConduitAPI_audit_Method',
     'ConduitAPI_chatlog_Method' => 'ConduitAPIMethod',
     'ConduitAPI_chatlog_query_Method' => 'ConduitAPI_chatlog_Method',
     'ConduitAPI_chatlog_record_Method' => 'ConduitAPI_chatlog_Method',
     'ConduitAPI_conduit_connect_Method' => 'ConduitAPIMethod',
     'ConduitAPI_conduit_getcertificate_Method' => 'ConduitAPIMethod',
     'ConduitAPI_conduit_ping_Method' => 'ConduitAPIMethod',
     'ConduitAPI_conduit_query_Method' => 'ConduitAPIMethod',
     'ConduitAPI_daemon_launched_Method' => 'ConduitAPIMethod',
     'ConduitAPI_daemon_log_Method' => 'ConduitAPIMethod',
     'ConduitAPI_daemon_setstatus_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_close_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_createcomment_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_creatediff_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_createinline_Method' => 'ConduitAPI_differential_Method',
     'ConduitAPI_differential_createrawdiff_Method' => 'ConduitAPI_differential_Method',
     'ConduitAPI_differential_createrevision_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_find_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_finishpostponedlinters_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_getalldiffs_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_getcommitmessage_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_getcommitpaths_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_getdiff_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_getrevision_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_getrevisioncomments_Method' => 'ConduitAPI_differential_Method',
     'ConduitAPI_differential_getrevisionfeedback_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_markcommitted_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_parsecommitmessage_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_query_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_setdiffproperty_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_updaterevision_Method' => 'ConduitAPIMethod',
     'ConduitAPI_differential_updateunitresults_Method' => 'ConduitAPIMethod',
     'ConduitAPI_diffusion_Method' => 'ConduitAPIMethod',
     'ConduitAPI_diffusion_findsymbols_Method' => 'ConduitAPI_diffusion_Method',
     'ConduitAPI_diffusion_getcommits_Method' => 'ConduitAPI_diffusion_Method',
     'ConduitAPI_diffusion_getlintmessages_Method' => 'ConduitAPI_diffusion_Method',
     'ConduitAPI_diffusion_getrecentcommitsbypath_Method' => 'ConduitAPI_diffusion_Method',
     'ConduitAPI_feed_Method' => 'ConduitAPIMethod',
     'ConduitAPI_feed_publish_Method' => 'ConduitAPI_feed_Method',
     'ConduitAPI_feed_query_Method' => 'ConduitAPI_feed_Method',
     'ConduitAPI_file_Method' => 'ConduitAPIMethod',
     'ConduitAPI_file_download_Method' => 'ConduitAPI_file_Method',
     'ConduitAPI_file_info_Method' => 'ConduitAPI_file_Method',
     'ConduitAPI_file_upload_Method' => 'ConduitAPI_file_Method',
     'ConduitAPI_file_uploadhash_Method' => 'ConduitAPI_file_Method',
     'ConduitAPI_flag_Method' => 'ConduitAPIMethod',
     'ConduitAPI_flag_delete_Method' => 'ConduitAPI_flag_Method',
     'ConduitAPI_flag_edit_Method' => 'ConduitAPI_flag_Method',
     'ConduitAPI_flag_query_Method' => 'ConduitAPI_flag_Method',
     'ConduitAPI_macro_Method' => 'ConduitAPIMethod',
     'ConduitAPI_macro_query_Method' => 'ConduitAPI_macro_Method',
     'ConduitAPI_maniphest_Method' => 'ConduitAPIMethod',
     'ConduitAPI_maniphest_createtask_Method' => 'ConduitAPI_maniphest_Method',
     'ConduitAPI_maniphest_find_Method' => 'ConduitAPI_maniphest_query_Method',
     'ConduitAPI_maniphest_gettasktransactions_Method' => 'ConduitAPI_maniphest_Method',
     'ConduitAPI_maniphest_info_Method' => 'ConduitAPI_maniphest_Method',
     'ConduitAPI_maniphest_query_Method' => 'ConduitAPI_maniphest_Method',
     'ConduitAPI_maniphest_update_Method' => 'ConduitAPI_maniphest_Method',
     'ConduitAPI_owners_Method' => 'ConduitAPIMethod',
     'ConduitAPI_owners_query_Method' => 'ConduitAPI_owners_Method',
     'ConduitAPI_paste_Method' => 'ConduitAPIMethod',
     'ConduitAPI_paste_create_Method' => 'ConduitAPI_paste_Method',
     'ConduitAPI_paste_info_Method' => 'ConduitAPI_paste_Method',
     'ConduitAPI_paste_query_Method' => 'ConduitAPI_paste_Method',
     'ConduitAPI_phid_Method' => 'ConduitAPIMethod',
     'ConduitAPI_phid_info_Method' => 'ConduitAPI_phid_Method',
     'ConduitAPI_phid_lookup_Method' => 'ConduitAPI_phid_Method',
     'ConduitAPI_phid_query_Method' => 'ConduitAPI_phid_Method',
     'ConduitAPI_phpast_Method' => 'ConduitAPIMethod',
     'ConduitAPI_phpast_getast_Method' => 'ConduitAPI_phpast_Method',
     'ConduitAPI_phpast_version_Method' => 'ConduitAPI_phpast_Method',
     'ConduitAPI_phriction_Method' => 'ConduitAPIMethod',
     'ConduitAPI_phriction_edit_Method' => 'ConduitAPI_phriction_Method',
     'ConduitAPI_phriction_history_Method' => 'ConduitAPI_phriction_Method',
     'ConduitAPI_phriction_info_Method' => 'ConduitAPI_phriction_Method',
     'ConduitAPI_project_Method' => 'ConduitAPIMethod',
     'ConduitAPI_project_query_Method' => 'ConduitAPI_project_Method',
+    'ConduitAPI_releeph_Method' => 'ConduitAPIMethod',
+    'ConduitAPI_releeph_getbranches_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releeph_projectinfo_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releeph_request_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releephwork_canpush_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releephwork_getauthorinfo_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releephwork_getbranch_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releephwork_getbranchcommitmessage_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releephwork_getcommitmessage_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releephwork_getorigcommitmessage_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releephwork_nextrequest_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releephwork_record_Method' => 'ConduitAPI_releeph_Method',
+    'ConduitAPI_releephwork_recordpickstatus_Method' => 'ConduitAPI_releeph_Method',
     'ConduitAPI_remarkup_process_Method' => 'ConduitAPIMethod',
     'ConduitAPI_repository_Method' => 'ConduitAPIMethod',
     'ConduitAPI_repository_create_Method' => 'ConduitAPI_repository_Method',
     'ConduitAPI_repository_query_Method' => 'ConduitAPI_repository_Method',
     'ConduitAPI_slowvote_Method' => 'ConduitAPIMethod',
     'ConduitAPI_slowvote_info_Method' => 'ConduitAPI_slowvote_Method',
     'ConduitAPI_token_Method' => 'ConduitAPIMethod',
     'ConduitAPI_token_give_Method' => 'ConduitAPI_token_Method',
     'ConduitAPI_token_given_Method' => 'ConduitAPI_token_Method',
     'ConduitAPI_token_query_Method' => 'ConduitAPI_token_Method',
     'ConduitAPI_user_Method' => 'ConduitAPIMethod',
     'ConduitAPI_user_addstatus_Method' => 'ConduitAPI_user_Method',
     'ConduitAPI_user_disable_Method' => 'ConduitAPI_user_Method',
     'ConduitAPI_user_enable_Method' => 'ConduitAPI_user_Method',
     'ConduitAPI_user_find_Method' => 'ConduitAPI_user_Method',
     'ConduitAPI_user_info_Method' => 'ConduitAPI_user_Method',
     'ConduitAPI_user_query_Method' => 'ConduitAPI_user_Method',
     'ConduitAPI_user_removestatus_Method' => 'ConduitAPI_user_Method',
     'ConduitAPI_user_whoami_Method' => 'ConduitAPI_user_Method',
     'ConduitCallTestCase' => 'PhabricatorTestCase',
     'ConduitException' => 'Exception',
     'ConduitSSHWorkflow' => 'PhabricatorSSHWorkflow',
     'ConpherenceConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'ConpherenceController' => 'PhabricatorController',
     'ConpherenceDAO' => 'PhabricatorLiskDAO',
     'ConpherenceEditor' => 'PhabricatorApplicationTransactionEditor',
     'ConpherenceFileWidgetView' => 'AphrontView',
     'ConpherenceFormDragAndDropUploadControl' => 'AphrontFormControl',
     'ConpherenceImageData' => 'ConpherenceConstants',
     'ConpherenceListController' => 'ConpherenceController',
     'ConpherenceMenuItemView' => 'AphrontTagView',
     'ConpherenceNewController' => 'ConpherenceController',
     'ConpherenceParticipant' => 'ConpherenceDAO',
     'ConpherenceParticipantQuery' => 'PhabricatorOffsetPagedQuery',
     'ConpherenceParticipationStatus' => 'ConpherenceConstants',
     'ConpherencePeopleMenuEventListener' => 'PhutilEventListener',
     'ConpherencePontificateControl' => 'AphrontFormControl',
     'ConpherenceReplyHandler' => 'PhabricatorMailReplyHandler',
     'ConpherenceThread' =>
     array(
       0 => 'ConpherenceDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'ConpherenceThreadQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'ConpherenceTransaction' => 'PhabricatorApplicationTransaction',
     'ConpherenceTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'ConpherenceTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'ConpherenceTransactionType' => 'ConpherenceConstants',
     'ConpherenceTransactionView' => 'AphrontView',
     'ConpherenceUpdateController' => 'ConpherenceController',
     'ConpherenceViewController' => 'ConpherenceController',
     'ConpherenceWidgetController' => 'ConpherenceController',
     'DarkConsoleController' => 'PhabricatorController',
     'DarkConsoleDataController' => 'PhabricatorController',
     'DarkConsoleErrorLogPlugin' => 'DarkConsolePlugin',
     'DarkConsoleEventPlugin' => 'DarkConsolePlugin',
     'DarkConsoleEventPluginAPI' => 'PhutilEventListener',
     'DarkConsoleRequestPlugin' => 'DarkConsolePlugin',
     'DarkConsoleServicesPlugin' => 'DarkConsolePlugin',
     'DarkConsoleXHProfPlugin' => 'DarkConsolePlugin',
     'DefaultDatabaseConfigurationProvider' => 'DatabaseConfigurationProvider',
     'DifferentialActionHasNoEffectException' => 'DifferentialException',
     'DifferentialAddCommentView' => 'AphrontView',
     'DifferentialAffectedPath' => 'DifferentialDAO',
     'DifferentialApplyPatchFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialArcanistProjectFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialAuditorsFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialAuthorFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialAuxiliaryField' => 'DifferentialDAO',
     'DifferentialBlameRevisionFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialBranchFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialCCWelcomeMail' => 'DifferentialReviewRequestMail',
     'DifferentialCCsFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialChangeset' => 'DifferentialDAO',
     'DifferentialChangesetDetailView' => 'AphrontView',
     'DifferentialChangesetHTMLRenderer' => 'DifferentialChangesetRenderer',
     'DifferentialChangesetListView' => 'AphrontView',
     'DifferentialChangesetOneUpRenderer' => 'DifferentialChangesetHTMLRenderer',
     'DifferentialChangesetOneUpTestRenderer' => 'DifferentialChangesetTestRenderer',
     'DifferentialChangesetParserTestCase' => 'PhabricatorTestCase',
     'DifferentialChangesetTestRenderer' => 'DifferentialChangesetRenderer',
     'DifferentialChangesetTwoUpRenderer' => 'DifferentialChangesetHTMLRenderer',
     'DifferentialChangesetTwoUpTestRenderer' => 'DifferentialChangesetTestRenderer',
     'DifferentialChangesetViewController' => 'DifferentialController',
     'DifferentialComment' =>
     array(
       0 => 'DifferentialDAO',
       1 => 'PhabricatorMarkupInterface',
     ),
     'DifferentialCommentEditor' => 'PhabricatorEditor',
     'DifferentialCommentMail' => 'DifferentialMail',
     'DifferentialCommentPreviewController' => 'DifferentialController',
     'DifferentialCommentSaveController' => 'DifferentialController',
     'DifferentialCommitsFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialConflictsFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialController' => 'PhabricatorController',
     'DifferentialDAO' => 'PhabricatorLiskDAO',
     'DifferentialDateCreatedFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialDateModifiedFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialDefaultFieldSelector' => 'DifferentialFieldSelector',
     'DifferentialDependenciesFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialDependsOnFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialDiff' => 'DifferentialDAO',
     'DifferentialDiffContentMail' => 'DifferentialMail',
     'DifferentialDiffCreateController' => 'DifferentialController',
     'DifferentialDiffProperty' => 'DifferentialDAO',
     'DifferentialDiffTableOfContentsView' => 'AphrontView',
     'DifferentialDiffTestCase' => 'ArcanistPhutilTestCase',
     'DifferentialDiffViewController' => 'DifferentialController',
     'DifferentialException' => 'Exception',
     'DifferentialExceptionMail' => 'DifferentialMail',
     'DifferentialExportPatchFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialFieldDataNotAvailableException' => 'Exception',
     'DifferentialFieldParseException' => 'Exception',
     'DifferentialFieldSpecificationIncompleteException' => 'Exception',
     'DifferentialFieldValidationException' => 'Exception',
     'DifferentialFreeformFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialGitSVNIDFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialHostFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialHunk' => 'DifferentialDAO',
     'DifferentialHunkParserTestCase' => 'PhabricatorTestCase',
     'DifferentialHunkTestCase' => 'ArcanistPhutilTestCase',
     'DifferentialInlineComment' =>
     array(
       0 => 'DifferentialDAO',
       1 => 'PhabricatorInlineCommentInterface',
     ),
     'DifferentialInlineCommentEditController' => 'PhabricatorInlineCommentController',
     'DifferentialInlineCommentEditView' => 'AphrontView',
     'DifferentialInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
     'DifferentialInlineCommentView' => 'AphrontView',
     'DifferentialLinesFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialLintFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialLocalCommitsView' => 'AphrontView',
     'DifferentialMail' => 'PhabricatorMail',
     'DifferentialManiphestTasksFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialNewDiffMail' => 'DifferentialReviewRequestMail',
     'DifferentialParseRenderTestCase' => 'PhabricatorTestCase',
     'DifferentialPathFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialPeopleMenuEventListener' => 'PhutilEventListener',
     'DifferentialPrimaryPaneView' => 'AphrontView',
+    'DifferentialReleephRequestFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialRemarkupRule' => 'PhabricatorRemarkupRuleObject',
     'DifferentialReplyHandler' => 'PhabricatorMailReplyHandler',
     'DifferentialResultsTableView' => 'AphrontView',
     'DifferentialRevertPlanFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialReviewRequestMail' => 'DifferentialMail',
     'DifferentialReviewedByFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialReviewerStatsTestCase' => 'PhabricatorTestCase',
     'DifferentialReviewersFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialRevision' =>
     array(
       0 => 'DifferentialDAO',
       1 => 'PhabricatorTokenReceiverInterface',
       2 => 'PhabricatorPolicyInterface',
     ),
     'DifferentialRevisionCommentListView' => 'AphrontView',
     'DifferentialRevisionCommentView' => 'AphrontView',
     'DifferentialRevisionDetailView' => 'AphrontView',
     'DifferentialRevisionEditController' => 'DifferentialController',
     'DifferentialRevisionEditor' => 'PhabricatorEditor',
     'DifferentialRevisionIDFieldParserTestCase' => 'PhabricatorTestCase',
     'DifferentialRevisionIDFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialRevisionListController' => 'DifferentialController',
     'DifferentialRevisionListView' => 'AphrontView',
     'DifferentialRevisionStatsController' => 'DifferentialController',
     'DifferentialRevisionStatsView' => 'AphrontView',
     'DifferentialRevisionStatusFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
     'DifferentialRevisionViewController' => 'DifferentialController',
     'DifferentialSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'DifferentialSubscribeController' => 'DifferentialController',
     'DifferentialSummaryFieldSpecification' => 'DifferentialFreeformFieldSpecification',
     'DifferentialTestPlanFieldSpecification' => 'DifferentialFieldSpecification',
     'DifferentialTitleFieldSpecification' => 'DifferentialFreeformFieldSpecification',
     'DifferentialUnitFieldSpecification' => 'DifferentialFieldSpecification',
     'DiffusionBranchTableController' => 'DiffusionController',
     'DiffusionBranchTableView' => 'DiffusionView',
     'DiffusionBrowseController' => 'DiffusionController',
     'DiffusionBrowseFileController' => 'DiffusionController',
     'DiffusionBrowseTableView' => 'DiffusionView',
     'DiffusionChangeController' => 'DiffusionController',
     'DiffusionCommentListView' => 'AphrontView',
     'DiffusionCommentView' => 'AphrontView',
     'DiffusionCommitBranchesController' => 'DiffusionController',
     'DiffusionCommitChangeTableView' => 'DiffusionView',
     'DiffusionCommitController' => 'DiffusionController',
     'DiffusionCommitEditController' => 'DiffusionController',
     'DiffusionCommitParentsQuery' => 'DiffusionQuery',
     'DiffusionCommitQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'DiffusionCommitTagsController' => 'DiffusionController',
     'DiffusionCommitTagsQuery' => 'DiffusionQuery',
     'DiffusionContainsQuery' => 'DiffusionQuery',
     'DiffusionController' => 'PhabricatorController',
     'DiffusionDiffController' => 'DiffusionController',
     'DiffusionDiffQuery' => 'DiffusionQuery',
     'DiffusionEmptyResultView' => 'DiffusionView',
     'DiffusionExistsQuery' => 'DiffusionQuery',
     'DiffusionExternalController' => 'DiffusionController',
     'DiffusionFileContentQuery' => 'DiffusionQuery',
     'DiffusionGitBranchQuery' => 'DiffusionBranchQuery',
     'DiffusionGitBranchQueryTestCase' => 'PhabricatorTestCase',
     'DiffusionGitBrowseQuery' => 'DiffusionBrowseQuery',
     'DiffusionGitCommitParentsQuery' => 'DiffusionCommitParentsQuery',
     'DiffusionGitCommitTagsQuery' => 'DiffusionCommitTagsQuery',
     'DiffusionGitContainsQuery' => 'DiffusionContainsQuery',
     'DiffusionGitDiffQuery' => 'DiffusionDiffQuery',
     'DiffusionGitExistsQuery' => 'DiffusionExistsQuery',
     'DiffusionGitFileContentQuery' => 'DiffusionFileContentQuery',
     'DiffusionGitHistoryQuery' => 'DiffusionHistoryQuery',
     'DiffusionGitLastModifiedQuery' => 'DiffusionLastModifiedQuery',
     'DiffusionGitMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
     'DiffusionGitRawDiffQuery' => 'DiffusionRawDiffQuery',
     'DiffusionGitRequest' => 'DiffusionRequest',
     'DiffusionGitTagListQuery' => 'DiffusionTagListQuery',
     'DiffusionHistoryController' => 'DiffusionController',
     'DiffusionHistoryQuery' => 'DiffusionQuery',
     'DiffusionHistoryTableView' => 'DiffusionView',
     'DiffusionHomeController' => 'DiffusionController',
     'DiffusionInlineCommentController' => 'PhabricatorInlineCommentController',
     'DiffusionInlineCommentPreviewController' => 'PhabricatorInlineCommentPreviewController',
     'DiffusionLastModifiedController' => 'DiffusionController',
     'DiffusionLastModifiedQuery' => 'DiffusionQuery',
     'DiffusionLintController' => 'DiffusionController',
     'DiffusionLintDetailsController' => 'DiffusionController',
     'DiffusionMercurialBranchQuery' => 'DiffusionBranchQuery',
     'DiffusionMercurialBrowseQuery' => 'DiffusionBrowseQuery',
     'DiffusionMercurialCommitParentsQuery' => 'DiffusionCommitParentsQuery',
     'DiffusionMercurialCommitTagsQuery' => 'DiffusionCommitTagsQuery',
     'DiffusionMercurialContainsQuery' => 'DiffusionContainsQuery',
     'DiffusionMercurialDiffQuery' => 'DiffusionDiffQuery',
     'DiffusionMercurialExistsQuery' => 'DiffusionExistsQuery',
     'DiffusionMercurialFileContentQuery' => 'DiffusionFileContentQuery',
     'DiffusionMercurialHistoryQuery' => 'DiffusionHistoryQuery',
     'DiffusionMercurialLastModifiedQuery' => 'DiffusionLastModifiedQuery',
     'DiffusionMercurialMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
     'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery',
     'DiffusionMercurialRequest' => 'DiffusionRequest',
     'DiffusionMercurialTagListQuery' => 'DiffusionTagListQuery',
     'DiffusionMergedCommitsQuery' => 'DiffusionQuery',
     'DiffusionPathCompleteController' => 'DiffusionController',
     'DiffusionPathQueryTestCase' => 'PhabricatorTestCase',
     'DiffusionPathValidateController' => 'DiffusionController',
     'DiffusionPeopleMenuEventListener' => 'PhutilEventListener',
     'DiffusionRawDiffQuery' => 'DiffusionQuery',
     'DiffusionRemarkupRule' => 'PhabricatorRemarkupRuleObject',
     'DiffusionRepositoryController' => 'DiffusionController',
     'DiffusionSetupException' => 'AphrontUsageException',
     'DiffusionSvnBrowseQuery' => 'DiffusionBrowseQuery',
     'DiffusionSvnCommitParentsQuery' => 'DiffusionCommitParentsQuery',
     'DiffusionSvnCommitTagsQuery' => 'DiffusionCommitTagsQuery',
     'DiffusionSvnContainsQuery' => 'DiffusionContainsQuery',
     'DiffusionSvnDiffQuery' => 'DiffusionDiffQuery',
     'DiffusionSvnExistsQuery' => 'DiffusionExistsQuery',
     'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
     'DiffusionSvnHistoryQuery' => 'DiffusionHistoryQuery',
     'DiffusionSvnLastModifiedQuery' => 'DiffusionLastModifiedQuery',
     'DiffusionSvnMergedCommitsQuery' => 'DiffusionMergedCommitsQuery',
     'DiffusionSvnRawDiffQuery' => 'DiffusionRawDiffQuery',
     'DiffusionSvnRequest' => 'DiffusionRequest',
     'DiffusionSvnTagListQuery' => 'DiffusionTagListQuery',
     'DiffusionSymbolController' => 'DiffusionController',
     'DiffusionSymbolQuery' => 'PhabricatorOffsetPagedQuery',
     'DiffusionTagListController' => 'DiffusionController',
     'DiffusionTagListQuery' => 'DiffusionQuery',
     'DiffusionTagListView' => 'DiffusionView',
     'DiffusionURITestCase' => 'ArcanistPhutilTestCase',
     'DiffusionView' => 'AphrontView',
     'DivinerArticleAtomizer' => 'DivinerAtomizer',
     'DivinerAtomCache' => 'DivinerDiskCache',
     'DivinerAtomizeWorkflow' => 'DivinerWorkflow',
     'DivinerDefaultRenderer' => 'DivinerRenderer',
     'DivinerFileAtomizer' => 'DivinerAtomizer',
     'DivinerGenerateWorkflow' => 'DivinerWorkflow',
     'DivinerListController' => 'PhabricatorController',
     'DivinerPublishCache' => 'DivinerDiskCache',
     'DivinerRemarkupRuleSymbol' => 'PhutilRemarkupRule',
     'DivinerStaticPublisher' => 'DivinerPublisher',
     'DivinerWorkflow' => 'PhutilArgumentWorkflow',
     'DrydockAllocatorWorker' => 'PhabricatorWorker',
     'DrydockApacheWebrootInterface' => 'DrydockWebrootInterface',
     'DrydockCommandInterface' => 'DrydockInterface',
     'DrydockController' => 'PhabricatorController',
     'DrydockDAO' => 'PhabricatorLiskDAO',
     'DrydockLease' => 'DrydockDAO',
     'DrydockLeaseListController' => 'DrydockController',
     'DrydockLeaseQuery' => 'PhabricatorOffsetPagedQuery',
     'DrydockLeaseReleaseController' => 'DrydockController',
     'DrydockLeaseStatus' => 'DrydockConstants',
     'DrydockLeaseViewController' => 'DrydockController',
     'DrydockLocalCommandInterface' => 'DrydockCommandInterface',
     'DrydockLocalHostBlueprint' => 'DrydockBlueprint',
     'DrydockLog' => 'DrydockDAO',
     'DrydockLogController' => 'DrydockController',
     'DrydockLogQuery' => 'PhabricatorOffsetPagedQuery',
     'DrydockManagementCloseWorkflow' => 'DrydockManagementWorkflow',
     'DrydockManagementLeaseWorkflow' => 'DrydockManagementWorkflow',
     'DrydockManagementReleaseWorkflow' => 'DrydockManagementWorkflow',
     'DrydockManagementWaitForLeaseWorkflow' => 'DrydockManagementWorkflow',
     'DrydockManagementWorkflow' => 'PhutilArgumentWorkflow',
     'DrydockResource' => 'DrydockDAO',
     'DrydockResourceCloseController' => 'DrydockController',
     'DrydockResourceListController' => 'DrydockController',
     'DrydockResourceQuery' => 'PhabricatorOffsetPagedQuery',
     'DrydockResourceStatus' => 'DrydockConstants',
     'DrydockResourceViewController' => 'DrydockController',
     'DrydockSSHCommandInterface' => 'DrydockCommandInterface',
     'DrydockWebrootInterface' => 'DrydockInterface',
     'DrydockWorkingCopyBlueprint' => 'DrydockBlueprint',
     'FeedPublisherWorker' => 'PhabricatorWorker',
     'HarbormasterDAO' => 'PhabricatorLiskDAO',
     'HarbormasterObject' => 'HarbormasterDAO',
     'HarbormasterRunnerWorker' => 'PhabricatorWorker',
     'HarbormasterScratchTable' => 'HarbormasterDAO',
     'HeraldAction' => 'HeraldDAO',
     'HeraldApplyTranscript' => 'HeraldDAO',
     'HeraldCommitAdapter' => 'HeraldObjectAdapter',
     'HeraldCondition' => 'HeraldDAO',
     'HeraldController' => 'PhabricatorController',
     'HeraldDAO' => 'PhabricatorLiskDAO',
     'HeraldDeleteController' => 'HeraldController',
     'HeraldDifferentialRevisionAdapter' => 'HeraldObjectAdapter',
     'HeraldDryRunAdapter' => 'HeraldObjectAdapter',
     'HeraldEditLogQuery' => 'PhabricatorOffsetPagedQuery',
     'HeraldHomeController' => 'HeraldController',
     'HeraldInvalidConditionException' => 'Exception',
     'HeraldInvalidFieldException' => 'Exception',
     'HeraldNewController' => 'HeraldController',
     'HeraldRecursiveConditionsException' => 'Exception',
     'HeraldRule' => 'HeraldDAO',
     'HeraldRuleController' => 'HeraldController',
     'HeraldRuleEdit' => 'HeraldDAO',
     'HeraldRuleEditHistoryController' => 'HeraldController',
     'HeraldRuleEditHistoryView' => 'AphrontView',
     'HeraldRuleListView' => 'AphrontView',
     'HeraldRuleQuery' => 'PhabricatorOffsetPagedQuery',
     'HeraldTestConsoleController' => 'HeraldController',
     'HeraldTranscript' => 'HeraldDAO',
     'HeraldTranscriptController' => 'HeraldController',
     'HeraldTranscriptListController' => 'HeraldController',
     'JavelinReactorExample' => 'PhabricatorUIExample',
     'JavelinUIExample' => 'PhabricatorUIExample',
     'JavelinViewExample' => 'PhabricatorUIExample',
     'JavelinViewExampleServerView' => 'AphrontView',
     'LiskChunkTestCase' => 'PhabricatorTestCase',
     'LiskDAOTestCase' => 'PhabricatorTestCase',
     'LiskEphemeralObjectException' => 'Exception',
     'LiskFixtureTestCase' => 'PhabricatorTestCase',
     'LiskIsolationTestCase' => 'PhabricatorTestCase',
     'LiskIsolationTestDAO' => 'LiskDAO',
     'LiskIsolationTestDAOException' => 'Exception',
     'LiskMigrationIterator' => 'PhutilBufferedIterator',
     'ManiphestAction' => 'ManiphestConstants',
     'ManiphestAuxiliaryFieldDefaultSpecification' => 'ManiphestAuxiliaryFieldSpecification',
     'ManiphestAuxiliaryFieldSpecification' => 'PhabricatorMarkupInterface',
     'ManiphestAuxiliaryFieldTypeException' => 'Exception',
     'ManiphestAuxiliaryFieldValidationException' => 'Exception',
     'ManiphestBatchEditController' => 'ManiphestController',
     'ManiphestController' => 'PhabricatorController',
     'ManiphestDAO' => 'PhabricatorLiskDAO',
     'ManiphestDefaultTaskExtensions' => 'ManiphestTaskExtensions',
     'ManiphestEdgeEventListener' => 'PhutilEventListener',
     'ManiphestExportController' => 'ManiphestController',
     'ManiphestPeopleMenuEventListener' => 'PhutilEventListener',
     'ManiphestRemarkupRule' => 'PhabricatorRemarkupRuleObject',
     'ManiphestReplyHandler' => 'PhabricatorMailReplyHandler',
     'ManiphestReportController' => 'ManiphestController',
     'ManiphestSavedQuery' => 'ManiphestDAO',
     'ManiphestSavedQueryDeleteController' => 'ManiphestController',
     'ManiphestSavedQueryEditController' => 'ManiphestController',
     'ManiphestSavedQueryListController' => 'ManiphestController',
     'ManiphestSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'ManiphestSubpriorityController' => 'ManiphestController',
     'ManiphestTask' =>
     array(
       0 => 'ManiphestDAO',
       1 => 'PhabricatorMarkupInterface',
       2 => 'PhabricatorPolicyInterface',
       3 => 'PhabricatorTokenReceiverInterface',
     ),
     'ManiphestTaskAuxiliaryStorage' => 'ManiphestDAO',
     'ManiphestTaskDescriptionChangeController' => 'ManiphestController',
     'ManiphestTaskDescriptionPreviewController' => 'ManiphestController',
     'ManiphestTaskDetailController' => 'ManiphestController',
     'ManiphestTaskEditController' => 'ManiphestController',
     'ManiphestTaskListController' => 'ManiphestController',
     'ManiphestTaskListView' => 'ManiphestView',
     'ManiphestTaskOwner' => 'ManiphestConstants',
     'ManiphestTaskPriority' => 'ManiphestConstants',
     'ManiphestTaskProject' => 'ManiphestDAO',
     'ManiphestTaskProjectsView' => 'ManiphestView',
     'ManiphestTaskQuery' => 'PhabricatorQuery',
     'ManiphestTaskStatus' => 'ManiphestConstants',
     'ManiphestTaskSubscriber' => 'ManiphestDAO',
     'ManiphestTaskSummaryView' => 'ManiphestView',
     'ManiphestTransaction' =>
     array(
       0 => 'ManiphestDAO',
       1 => 'PhabricatorMarkupInterface',
     ),
     'ManiphestTransactionDetailView' => 'ManiphestView',
     'ManiphestTransactionEditor' => 'PhabricatorEditor',
     'ManiphestTransactionListView' => 'ManiphestView',
     'ManiphestTransactionPreviewController' => 'ManiphestController',
     'ManiphestTransactionSaveController' => 'ManiphestController',
     'ManiphestTransactionType' => 'ManiphestConstants',
     'ManiphestView' => 'AphrontView',
     'MetaMTANotificationType' => 'MetaMTAConstants',
     'OwnersPackageReplyHandler' => 'PhabricatorMailReplyHandler',
     'PackageCreateMail' => 'PackageMail',
     'PackageDeleteMail' => 'PackageMail',
     'PackageMail' => 'PhabricatorMail',
     'PackageModifyMail' => 'PackageMail',
     'PasteEmbedView' => 'AphrontView',
     'Phabricator404Controller' => 'PhabricatorController',
     'PhabricatorAWSConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorAccessLogConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorActionListExample' => 'PhabricatorUIExample',
     'PhabricatorActionListView' => 'AphrontView',
     'PhabricatorActionView' => 'AphrontView',
     'PhabricatorAllCapsTranslation' => 'PhabricatorTranslation',
     'PhabricatorAnchorView' => 'AphrontView',
     'PhabricatorAphrontBarExample' => 'PhabricatorUIExample',
     'PhabricatorApplicationApplications' => 'PhabricatorApplication',
     'PhabricatorApplicationAudit' => 'PhabricatorApplication',
     'PhabricatorApplicationAuth' => 'PhabricatorApplication',
     'PhabricatorApplicationCalendar' => 'PhabricatorApplication',
     'PhabricatorApplicationChatLog' => 'PhabricatorApplication',
     'PhabricatorApplicationConduit' => 'PhabricatorApplication',
     'PhabricatorApplicationConfig' => 'PhabricatorApplication',
     'PhabricatorApplicationConfigOptions' => 'Phobject',
     'PhabricatorApplicationConpherence' => 'PhabricatorApplication',
     'PhabricatorApplicationCountdown' => 'PhabricatorApplication',
     'PhabricatorApplicationDaemons' => 'PhabricatorApplication',
     'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController',
     'PhabricatorApplicationDifferential' => 'PhabricatorApplication',
     'PhabricatorApplicationDiffusion' => 'PhabricatorApplication',
     'PhabricatorApplicationDiviner' => 'PhabricatorApplication',
     'PhabricatorApplicationDrydock' => 'PhabricatorApplication',
     'PhabricatorApplicationFact' => 'PhabricatorApplication',
     'PhabricatorApplicationFeed' => 'PhabricatorApplication',
     'PhabricatorApplicationFiles' => 'PhabricatorApplication',
     'PhabricatorApplicationFlags' => 'PhabricatorApplication',
     'PhabricatorApplicationHerald' => 'PhabricatorApplication',
     'PhabricatorApplicationLaunchView' => 'AphrontView',
     'PhabricatorApplicationMacro' => 'PhabricatorApplication',
     'PhabricatorApplicationMailingLists' => 'PhabricatorApplication',
     'PhabricatorApplicationManiphest' => 'PhabricatorApplication',
     'PhabricatorApplicationMetaMTA' => 'PhabricatorApplication',
     'PhabricatorApplicationOwners' => 'PhabricatorApplication',
     'PhabricatorApplicationPHID' => 'PhabricatorApplication',
     'PhabricatorApplicationPHPAST' => 'PhabricatorApplication',
     'PhabricatorApplicationPaste' => 'PhabricatorApplication',
     'PhabricatorApplicationPeople' => 'PhabricatorApplication',
     'PhabricatorApplicationPhame' => 'PhabricatorApplication',
     'PhabricatorApplicationPholio' => 'PhabricatorApplication',
     'PhabricatorApplicationPhriction' => 'PhabricatorApplication',
     'PhabricatorApplicationPonder' => 'PhabricatorApplication',
     'PhabricatorApplicationProject' => 'PhabricatorApplication',
+    'PhabricatorApplicationReleeph' => 'PhabricatorApplication',
+    'PhabricatorApplicationReleephConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorApplicationRepositories' => 'PhabricatorApplication',
     'PhabricatorApplicationSettings' => 'PhabricatorApplication',
     'PhabricatorApplicationSlowvote' => 'PhabricatorApplication',
     'PhabricatorApplicationStatusView' => 'AphrontView',
     'PhabricatorApplicationSubscriptions' => 'PhabricatorApplication',
     'PhabricatorApplicationTokens' => 'PhabricatorApplication',
     'PhabricatorApplicationTransaction' =>
     array(
       0 => 'PhabricatorLiskDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorApplicationTransactionComment' =>
     array(
       0 => 'PhabricatorLiskDAO',
       1 => 'PhabricatorMarkupInterface',
       2 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorApplicationTransactionCommentEditController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionCommentEditor' => 'PhabricatorEditor',
     'PhabricatorApplicationTransactionCommentHistoryController' => 'PhabricatorApplicationTransactionController',
     'PhabricatorApplicationTransactionCommentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorApplicationTransactionCommentView' => 'AphrontView',
     'PhabricatorApplicationTransactionController' => 'PhabricatorController',
     'PhabricatorApplicationTransactionEditor' => 'PhabricatorEditor',
     'PhabricatorApplicationTransactionFeedStory' => 'PhabricatorFeedStory',
     'PhabricatorApplicationTransactionNoEffectException' => 'Exception',
     'PhabricatorApplicationTransactionNoEffectResponse' => 'AphrontProxyResponse',
     'PhabricatorApplicationTransactionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorApplicationTransactionResponse' => 'AphrontProxyResponse',
     'PhabricatorApplicationTransactionTextDiffDetailView' => 'AphrontView',
     'PhabricatorApplicationTransactionView' => 'AphrontView',
     'PhabricatorApplicationTransactions' => 'PhabricatorApplication',
     'PhabricatorApplicationUIExamples' => 'PhabricatorApplication',
     'PhabricatorApplicationUninstallController' => 'PhabricatorApplicationsController',
     'PhabricatorApplicationsController' => 'PhabricatorController',
     'PhabricatorApplicationsListController' => 'PhabricatorApplicationsController',
     'PhabricatorAuditAddCommentController' => 'PhabricatorAuditController',
     'PhabricatorAuditComment' =>
     array(
       0 => 'PhabricatorAuditDAO',
       1 => 'PhabricatorMarkupInterface',
     ),
     'PhabricatorAuditCommentEditor' => 'PhabricatorEditor',
     'PhabricatorAuditCommitListView' => 'AphrontView',
     'PhabricatorAuditController' => 'PhabricatorController',
     'PhabricatorAuditDAO' => 'PhabricatorLiskDAO',
     'PhabricatorAuditInlineComment' =>
     array(
       0 => 'PhabricatorAuditDAO',
       1 => 'PhabricatorInlineCommentInterface',
     ),
     'PhabricatorAuditListController' => 'PhabricatorAuditController',
     'PhabricatorAuditListView' => 'AphrontView',
     'PhabricatorAuditPreviewController' => 'PhabricatorAuditController',
     'PhabricatorAuditReplyHandler' => 'PhabricatorMailReplyHandler',
     'PhabricatorAuthController' => 'PhabricatorController',
     'PhabricatorAuthenticationConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorBarePageExample' => 'PhabricatorUIExample',
     'PhabricatorBarePageView' => 'AphrontPageView',
     'PhabricatorBaseEnglishTranslation' => 'PhabricatorTranslation',
     'PhabricatorBot' => 'PhabricatorDaemon',
     'PhabricatorBotBaseStreamingProtocolAdapter' => 'PhabricatorBaseProtocolAdapter',
     'PhabricatorBotChannel' => 'PhabricatorBotTarget',
     'PhabricatorBotDebugLogHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotDifferentialNotificationHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotFeedNotificationHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotFlowdockProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter',
     'PhabricatorBotLogHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotMacroHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotObjectNameHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotSymbolHandler' => 'PhabricatorBotHandler',
     'PhabricatorBotUser' => 'PhabricatorBotTarget',
     'PhabricatorBotWhatsNewHandler' => 'PhabricatorBotHandler',
     'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList',
     'PhabricatorButtonsExample' => 'PhabricatorUIExample',
     'PhabricatorCacheDAO' => 'PhabricatorLiskDAO',
     'PhabricatorCalendarBrowseController' => 'PhabricatorCalendarController',
     'PhabricatorCalendarController' => 'PhabricatorController',
     'PhabricatorCalendarDAO' => 'PhabricatorLiskDAO',
     'PhabricatorCalendarDeleteStatusController' => 'PhabricatorCalendarController',
     'PhabricatorCalendarEditStatusController' => 'PhabricatorCalendarController',
     'PhabricatorCalendarHoliday' => 'PhabricatorCalendarDAO',
     'PhabricatorCalendarHolidayTestCase' => 'PhabricatorTestCase',
     'PhabricatorCalendarViewStatusController' => 'PhabricatorCalendarController',
     'PhabricatorCampfireProtocolAdapter' => 'PhabricatorBotBaseStreamingProtocolAdapter',
     'PhabricatorChangesetResponse' => 'AphrontProxyResponse',
     'PhabricatorChatLogChannel' =>
     array(
       0 => 'PhabricatorChatLogDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorChatLogChannelListController' => 'PhabricatorChatLogController',
     'PhabricatorChatLogChannelLogController' => 'PhabricatorChatLogController',
     'PhabricatorChatLogChannelQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorChatLogController' => 'PhabricatorController',
     'PhabricatorChatLogDAO' => 'PhabricatorLiskDAO',
     'PhabricatorChatLogEvent' =>
     array(
       0 => 'PhabricatorChatLogDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorChatLogEventType' => 'PhabricatorChatLogConstants',
     'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorConduitAPIController' => 'PhabricatorConduitController',
     'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO',
     'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO',
     'PhabricatorConduitConsoleController' => 'PhabricatorConduitController',
     'PhabricatorConduitController' => 'PhabricatorController',
     'PhabricatorConduitDAO' => 'PhabricatorLiskDAO',
     'PhabricatorConduitListController' => 'PhabricatorConduitController',
     'PhabricatorConduitLogController' => 'PhabricatorConduitController',
     'PhabricatorConduitMethodCallLog' => 'PhabricatorConduitDAO',
     'PhabricatorConduitTokenController' => 'PhabricatorConduitController',
     'PhabricatorConfigAllController' => 'PhabricatorConfigController',
     'PhabricatorConfigController' => 'PhabricatorController',
     'PhabricatorConfigDatabaseSource' => 'PhabricatorConfigProxySource',
     'PhabricatorConfigDefaultSource' => 'PhabricatorConfigProxySource',
     'PhabricatorConfigDictionarySource' => 'PhabricatorConfigSource',
     'PhabricatorConfigEditController' => 'PhabricatorConfigController',
     'PhabricatorConfigEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorConfigEntry' => 'PhabricatorConfigEntryDAO',
     'PhabricatorConfigEntryDAO' => 'PhabricatorLiskDAO',
     'PhabricatorConfigFileSource' => 'PhabricatorConfigProxySource',
     'PhabricatorConfigGroupController' => 'PhabricatorConfigController',
     'PhabricatorConfigIgnoreController' => 'PhabricatorApplicationsController',
     'PhabricatorConfigIssueListController' => 'PhabricatorConfigController',
     'PhabricatorConfigIssueViewController' => 'PhabricatorConfigController',
     'PhabricatorConfigListController' => 'PhabricatorConfigController',
     'PhabricatorConfigLocalSource' => 'PhabricatorConfigProxySource',
     'PhabricatorConfigManagementDeleteWorkflow' => 'PhabricatorConfigManagementWorkflow',
     'PhabricatorConfigManagementGetWorkflow' => 'PhabricatorConfigManagementWorkflow',
     'PhabricatorConfigManagementListWorkflow' => 'PhabricatorConfigManagementWorkflow',
     'PhabricatorConfigManagementSetWorkflow' => 'PhabricatorConfigManagementWorkflow',
     'PhabricatorConfigManagementWorkflow' => 'PhutilArgumentWorkflow',
     'PhabricatorConfigOption' =>
     array(
       0 => 'Phobject',
       1 => 'PhabricatorMarkupInterface',
     ),
     'PhabricatorConfigProxySource' => 'PhabricatorConfigSource',
     'PhabricatorConfigResponse' => 'AphrontHTMLResponse',
     'PhabricatorConfigStackSource' => 'PhabricatorConfigSource',
     'PhabricatorConfigTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorConfigTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorConfigValidationException' => 'Exception',
     'PhabricatorContentSourceView' => 'AphrontView',
     'PhabricatorController' => 'AphrontController',
     'PhabricatorCoreConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorCountdownController' => 'PhabricatorController',
     'PhabricatorCountdownDAO' => 'PhabricatorLiskDAO',
     'PhabricatorCountdownDeleteController' => 'PhabricatorCountdownController',
     'PhabricatorCountdownEditController' => 'PhabricatorCountdownController',
     'PhabricatorCountdownListController' => 'PhabricatorCountdownController',
     'PhabricatorCountdownRemarkupRule' => 'PhutilRemarkupRule',
     'PhabricatorCountdownViewController' => 'PhabricatorCountdownController',
     'PhabricatorCountedToggleButtonsExample' => 'PhabricatorUIExample',
     'PhabricatorCrumbView' => 'AphrontView',
     'PhabricatorCrumbsView' => 'AphrontView',
     'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery',
     'PhabricatorDaemon' => 'PhutilDaemon',
     'PhabricatorDaemonCombinedLogController' => 'PhabricatorDaemonController',
     'PhabricatorDaemonConsoleController' => 'PhabricatorDaemonController',
     'PhabricatorDaemonController' => 'PhabricatorController',
     'PhabricatorDaemonDAO' => 'PhabricatorLiskDAO',
     'PhabricatorDaemonLog' => 'PhabricatorDaemonDAO',
     'PhabricatorDaemonLogEvent' => 'PhabricatorDaemonDAO',
     'PhabricatorDaemonLogEventsView' => 'AphrontView',
     'PhabricatorDaemonLogListController' => 'PhabricatorDaemonController',
     'PhabricatorDaemonLogListView' => 'AphrontView',
     'PhabricatorDaemonLogViewController' => 'PhabricatorDaemonController',
     'PhabricatorDebugController' => 'PhabricatorController',
     'PhabricatorDefaultFileStorageEngineSelector' => 'PhabricatorFileStorageEngineSelector',
     'PhabricatorDefaultSearchEngineSelector' => 'PhabricatorSearchEngineSelector',
     'PhabricatorDeveloperConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorDifferentialConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorDiffusionConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorDirectoryController' => 'PhabricatorController',
     'PhabricatorDirectoryMainController' => 'PhabricatorDirectoryController',
     'PhabricatorDisabledUserController' => 'PhabricatorAuthController',
     'PhabricatorDisqusConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorDraft' => 'PhabricatorDraftDAO',
     'PhabricatorDraftDAO' => 'PhabricatorLiskDAO',
     'PhabricatorEdgeConfig' => 'PhabricatorEdgeConstants',
     'PhabricatorEdgeCycleException' => 'Exception',
     'PhabricatorEdgeEditor' => 'PhabricatorEditor',
     'PhabricatorEdgeGraph' => 'AbstractDirectedGraph',
     'PhabricatorEdgeQuery' => 'PhabricatorQuery',
     'PhabricatorEdgeTestCase' => 'PhabricatorTestCase',
     'PhabricatorEditor' => 'Phobject',
     'PhabricatorEmailLoginController' => 'PhabricatorAuthController',
     'PhabricatorEmailTokenController' => 'PhabricatorAuthController',
     'PhabricatorEmailVerificationController' => 'PhabricatorPeopleController',
     'PhabricatorEmptyQueryException' => 'Exception',
     'PhabricatorEnglishTranslation' => 'PhabricatorBaseEnglishTranslation',
     'PhabricatorEnvTestCase' => 'PhabricatorTestCase',
     'PhabricatorErrorExample' => 'PhabricatorUIExample',
     'PhabricatorEvent' => 'PhutilEvent',
     'PhabricatorEventType' => 'PhutilEventType',
     'PhabricatorExampleEventListener' => 'PhutilEventListener',
     'PhabricatorExtendingPhabricatorConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorFacebookConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorFactAggregate' => 'PhabricatorFactDAO',
     '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' => 'PhutilArgumentWorkflow',
     'PhabricatorFactRaw' => 'PhabricatorFactDAO',
     'PhabricatorFactSimpleSpec' => 'PhabricatorFactSpec',
     'PhabricatorFactUpdateIterator' => 'PhutilBufferedIterator',
     'PhabricatorFeedConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorFeedController' => 'PhabricatorController',
     'PhabricatorFeedDAO' => 'PhabricatorLiskDAO',
     'PhabricatorFeedMainController' => 'PhabricatorFeedController',
     'PhabricatorFeedPublicStreamController' => 'PhabricatorFeedController',
     'PhabricatorFeedQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorFeedStory' => 'PhabricatorPolicyInterface',
     'PhabricatorFeedStoryAggregate' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryAudit' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryCommit' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryData' => 'PhabricatorFeedDAO',
     'PhabricatorFeedStoryDifferential' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryDifferentialAggregate' => 'PhabricatorFeedStoryAggregate',
     'PhabricatorFeedStoryManiphest' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryManiphestAggregate' => 'PhabricatorFeedStoryAggregate',
     'PhabricatorFeedStoryNotification' => 'PhabricatorFeedDAO',
     'PhabricatorFeedStoryPhriction' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryProject' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryReference' => 'PhabricatorFeedDAO',
     'PhabricatorFeedStoryStatus' => 'PhabricatorFeedStory',
     'PhabricatorFeedStoryTypeConstants' => 'PhabricatorFeedConstants',
     'PhabricatorFeedStoryView' => 'PhabricatorFeedView',
     'PhabricatorFeedView' => 'AphrontView',
     'PhabricatorFile' =>
     array(
       0 => 'PhabricatorFileDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorFileController' => 'PhabricatorController',
     'PhabricatorFileDAO' => 'PhabricatorLiskDAO',
     'PhabricatorFileDataController' => 'PhabricatorFileController',
     'PhabricatorFileDeleteController' => 'PhabricatorFileController',
     'PhabricatorFileDropUploadController' => 'PhabricatorFileController',
     'PhabricatorFileImageMacro' =>
     array(
       0 => 'PhabricatorFileDAO',
       1 => 'PhabricatorSubscribableInterface',
       2 => 'PhabricatorApplicationTransactionInterface',
     ),
     'PhabricatorFileInfoController' => 'PhabricatorFileController',
     'PhabricatorFileLinkListView' => 'AphrontView',
     'PhabricatorFileLinkView' => 'AphrontView',
     'PhabricatorFileListController' => 'PhabricatorFileController',
     'PhabricatorFileQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorFileShortcutController' => 'PhabricatorFileController',
     'PhabricatorFileStorageBlob' => 'PhabricatorFileDAO',
     'PhabricatorFileStorageConfigurationException' => 'Exception',
     'PhabricatorFileTestCase' => 'PhabricatorTestCase',
     'PhabricatorFileTransformController' => 'PhabricatorFileController',
     'PhabricatorFileUploadController' => 'PhabricatorFileController',
     'PhabricatorFileUploadException' => 'Exception',
     'PhabricatorFilesConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorFilesManagementEnginesWorkflow' => 'PhabricatorFilesManagementWorkflow',
     'PhabricatorFilesManagementMetadataWorkflow' => 'PhabricatorFilesManagementWorkflow',
     'PhabricatorFilesManagementMigrateWorkflow' => 'PhabricatorFilesManagementWorkflow',
     'PhabricatorFilesManagementWorkflow' => 'PhutilArgumentWorkflow',
     'PhabricatorFlag' => 'PhabricatorFlagDAO',
     'PhabricatorFlagColor' => 'PhabricatorFlagConstants',
     'PhabricatorFlagController' => 'PhabricatorController',
     'PhabricatorFlagDAO' => 'PhabricatorLiskDAO',
     'PhabricatorFlagDeleteController' => 'PhabricatorFlagController',
     'PhabricatorFlagEditController' => 'PhabricatorFlagController',
     'PhabricatorFlagListController' => 'PhabricatorFlagController',
     'PhabricatorFlagListView' => 'AphrontView',
     'PhabricatorFlagsUIEventListener' => 'PhutilEventListener',
     'PhabricatorFormExample' => 'PhabricatorUIExample',
     'PhabricatorGarbageCollectorConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorGarbageCollectorDaemon' => 'PhabricatorDaemon',
     'PhabricatorGestureExample' => 'PhabricatorUIExample',
     'PhabricatorGitHubConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorGlobalLock' => 'PhutilLock',
     'PhabricatorGlobalUploadTargetView' => 'AphrontView',
     'PhabricatorGoogleConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorHashTestCase' => 'PhabricatorTestCase',
     'PhabricatorHeaderView' => 'AphrontView',
     'PhabricatorHelpController' => 'PhabricatorController',
     'PhabricatorHelpKeyboardShortcutController' => 'PhabricatorHelpController',
     'PhabricatorIRCBot' => 'PhabricatorDaemon',
     'PhabricatorIRCProtocolAdapter' => 'PhabricatorBaseProtocolAdapter',
     'PhabricatorIRCProtocolHandler' => 'PhabricatorBotHandler',
     'PhabricatorInfrastructureTestCase' => 'PhabricatorTestCase',
     'PhabricatorInlineCommentController' => 'PhabricatorController',
     'PhabricatorInlineCommentInterface' => 'PhabricatorMarkupInterface',
     'PhabricatorInlineCommentPreviewController' => 'PhabricatorController',
     'PhabricatorInlineSummaryView' => 'AphrontView',
     'PhabricatorJavelinLinter' => 'ArcanistLinter',
     'PhabricatorKeyValueDatabaseCache' => 'PhutilKeyValueCache',
     'PhabricatorLDAPConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorLDAPLoginController' => 'PhabricatorAuthController',
     'PhabricatorLDAPRegistrationController' => 'PhabricatorAuthController',
     'PhabricatorLDAPUnknownUserException' => 'Exception',
     'PhabricatorLDAPUnlinkController' => 'PhabricatorAuthController',
     'PhabricatorLintEngine' => 'PhutilLintEngine',
     'PhabricatorLiskDAO' => 'LiskDAO',
     'PhabricatorLocalDiskFileStorageEngine' => 'PhabricatorFileStorageEngine',
     'PhabricatorLocalTimeTestCase' => 'PhabricatorTestCase',
     'PhabricatorLoginController' => 'PhabricatorAuthController',
     'PhabricatorLoginValidateController' => 'PhabricatorAuthController',
     'PhabricatorLogoutController' => 'PhabricatorAuthController',
     'PhabricatorMacroCommentController' => 'PhabricatorMacroController',
     'PhabricatorMacroConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorMacroController' => 'PhabricatorController',
     'PhabricatorMacroDisableController' => 'PhabricatorMacroController',
     'PhabricatorMacroEditController' => 'PhabricatorMacroController',
     'PhabricatorMacroEditor' => 'PhabricatorApplicationTransactionEditor',
     'PhabricatorMacroListController' => 'PhabricatorMacroController',
     'PhabricatorMacroMemeController' => 'PhabricatorMacroController',
     'PhabricatorMacroMemeDialogController' => 'PhabricatorMacroController',
     'PhabricatorMacroReplyHandler' => 'PhabricatorMailReplyHandler',
     'PhabricatorMacroTransaction' => 'PhabricatorApplicationTransaction',
     'PhabricatorMacroTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PhabricatorMacroTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PhabricatorMacroViewController' => 'PhabricatorMacroController',
     'PhabricatorMailImplementationAmazonSESAdapter' => 'PhabricatorMailImplementationPHPMailerLiteAdapter',
     'PhabricatorMailImplementationPHPMailerAdapter' => 'PhabricatorMailImplementationAdapter',
     'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter',
     'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter',
     'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter',
     'PhabricatorMailingListsController' => 'PhabricatorController',
     'PhabricatorMailingListsEditController' => 'PhabricatorMailingListsController',
     'PhabricatorMailingListsListController' => 'PhabricatorMailingListsController',
     'PhabricatorMainMenuGroupView' => 'AphrontView',
     'PhabricatorMainMenuIconView' => 'AphrontView',
     'PhabricatorMainMenuSearchView' => 'AphrontView',
     'PhabricatorMainMenuView' => 'AphrontView',
     'PhabricatorManiphestConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorMarkupCache' => 'PhabricatorCacheDAO',
     'PhabricatorMenuItemView' => 'AphrontTagView',
     'PhabricatorMenuView' => 'AphrontTagView',
     'PhabricatorMenuViewTestCase' => 'PhabricatorTestCase',
     'PhabricatorMetaMTAConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorMetaMTAController' => 'PhabricatorController',
     'PhabricatorMetaMTADAO' => 'PhabricatorLiskDAO',
     'PhabricatorMetaMTAEmailBodyParserTestCase' => 'PhabricatorTestCase',
     'PhabricatorMetaMTAListController' => 'PhabricatorMetaMTAController',
     'PhabricatorMetaMTAMail' => 'PhabricatorMetaMTADAO',
     'PhabricatorMetaMTAMailBodyTestCase' => 'PhabricatorTestCase',
     'PhabricatorMetaMTAMailTestCase' => 'PhabricatorTestCase',
     'PhabricatorMetaMTAMailingList' => 'PhabricatorMetaMTADAO',
     'PhabricatorMetaMTAReceiveController' => 'PhabricatorMetaMTAController',
     'PhabricatorMetaMTAReceivedListController' => 'PhabricatorMetaMTAController',
     'PhabricatorMetaMTAReceivedMail' => 'PhabricatorMetaMTADAO',
     'PhabricatorMetaMTASendController' => 'PhabricatorMetaMTAController',
     'PhabricatorMetaMTASendGridReceiveController' => 'PhabricatorMetaMTAController',
     'PhabricatorMetaMTAViewController' => 'PhabricatorMetaMTAController',
     'PhabricatorMetaMTAWorker' => 'PhabricatorWorker',
     'PhabricatorMustVerifyEmailController' => 'PhabricatorAuthController',
     'PhabricatorMySQLConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorMySQLFileStorageEngine' => 'PhabricatorFileStorageEngine',
     'PhabricatorNoteExample' => 'PhabricatorUIExample',
     'PhabricatorNotificationClearController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorNotificationController' => 'PhabricatorController',
     'PhabricatorNotificationIndividualController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationListController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationPanelController' => 'PhabricatorNotificationController',
     'PhabricatorNotificationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorNotificationStatusController' => 'PhabricatorNotificationController',
     'PhabricatorOAuthClientAuthorization' => 'PhabricatorOAuthServerDAO',
     'PhabricatorOAuthClientAuthorizationBaseController' => 'PhabricatorOAuthServerController',
     'PhabricatorOAuthClientAuthorizationDeleteController' => 'PhabricatorOAuthClientAuthorizationBaseController',
     'PhabricatorOAuthClientAuthorizationEditController' => 'PhabricatorOAuthClientAuthorizationBaseController',
     'PhabricatorOAuthClientAuthorizationListController' => 'PhabricatorOAuthClientAuthorizationBaseController',
     'PhabricatorOAuthClientAuthorizationQuery' => 'PhabricatorOffsetPagedQuery',
     'PhabricatorOAuthClientBaseController' => 'PhabricatorOAuthServerController',
     'PhabricatorOAuthClientDeleteController' => 'PhabricatorOAuthClientBaseController',
     'PhabricatorOAuthClientEditController' => 'PhabricatorOAuthClientBaseController',
     'PhabricatorOAuthClientListController' => 'PhabricatorOAuthClientBaseController',
     'PhabricatorOAuthClientViewController' => 'PhabricatorOAuthClientBaseController',
     'PhabricatorOAuthDefaultRegistrationController' => 'PhabricatorOAuthRegistrationController',
     'PhabricatorOAuthDiagnosticsController' => 'PhabricatorAuthController',
     'PhabricatorOAuthFailureView' => 'AphrontView',
     'PhabricatorOAuthLoginController' => 'PhabricatorAuthController',
     'PhabricatorOAuthProviderDisqus' => 'PhabricatorOAuthProvider',
     'PhabricatorOAuthProviderException' => 'Exception',
     'PhabricatorOAuthProviderFacebook' => 'PhabricatorOAuthProvider',
     'PhabricatorOAuthProviderGitHub' => 'PhabricatorOAuthProvider',
     'PhabricatorOAuthProviderGoogle' => 'PhabricatorOAuthProvider',
     'PhabricatorOAuthProviderPhabricator' => 'PhabricatorOAuthProvider',
     'PhabricatorOAuthRegistrationController' => 'PhabricatorAuthController',
     'PhabricatorOAuthResponse' => 'AphrontResponse',
     'PhabricatorOAuthServerAccessToken' => 'PhabricatorOAuthServerDAO',
     'PhabricatorOAuthServerAuthController' => 'PhabricatorAuthController',
     'PhabricatorOAuthServerAuthorizationCode' => 'PhabricatorOAuthServerDAO',
     'PhabricatorOAuthServerClient' => 'PhabricatorOAuthServerDAO',
     'PhabricatorOAuthServerClientQuery' => 'PhabricatorOffsetPagedQuery',
     'PhabricatorOAuthServerController' => 'PhabricatorController',
     'PhabricatorOAuthServerDAO' => 'PhabricatorLiskDAO',
     'PhabricatorOAuthServerTestCase' => 'PhabricatorTestCase',
     'PhabricatorOAuthServerTestController' => 'PhabricatorOAuthServerController',
     'PhabricatorOAuthServerTokenController' => 'PhabricatorAuthController',
     'PhabricatorOAuthUnlinkController' => 'PhabricatorAuthController',
     'PhabricatorObjectHandleStatus' => 'PhabricatorObjectHandleConstants',
     'PhabricatorObjectItemListExample' => 'PhabricatorUIExample',
     'PhabricatorObjectItemListView' => 'AphrontView',
     'PhabricatorObjectItemView' => 'AphrontView',
     'PhabricatorObjectListView' => 'AphrontView',
     'PhabricatorOffsetPagedQuery' => 'PhabricatorQuery',
     'PhabricatorOwnersConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorOwnersController' => 'PhabricatorController',
     'PhabricatorOwnersDAO' => 'PhabricatorLiskDAO',
     'PhabricatorOwnersDeleteController' => 'PhabricatorOwnersController',
     'PhabricatorOwnersDetailController' => 'PhabricatorOwnersController',
     'PhabricatorOwnersEditController' => 'PhabricatorOwnersController',
     'PhabricatorOwnersListController' => 'PhabricatorOwnersController',
     'PhabricatorOwnersOwner' => 'PhabricatorOwnersDAO',
     'PhabricatorOwnersPackage' =>
     array(
       0 => 'PhabricatorOwnersDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorOwnersPackageQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorOwnersPackageTestCase' => 'PhabricatorTestCase',
     'PhabricatorOwnersPath' => 'PhabricatorOwnersDAO',
     'PhabricatorPHDConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPHIDConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPHIDController' => 'PhabricatorController',
     'PhabricatorPHIDLookupController' => 'PhabricatorPHIDController',
     'PhabricatorPHPMailerConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPaste' =>
     array(
       0 => 'PhabricatorPasteDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorPasteController' => 'PhabricatorController',
     'PhabricatorPasteDAO' => 'PhabricatorLiskDAO',
     'PhabricatorPasteEditController' => 'PhabricatorPasteController',
     'PhabricatorPasteListController' => 'PhabricatorPasteController',
     'PhabricatorPasteQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorPasteRemarkupRule' => 'PhabricatorRemarkupRuleObject',
     'PhabricatorPasteViewController' => 'PhabricatorPasteController',
     'PhabricatorPeopleController' => 'PhabricatorController',
     'PhabricatorPeopleEditController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleLdapController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleListController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleLogsController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleProfileController' => 'PhabricatorPeopleController',
     'PhabricatorPeopleQuery' => 'PhabricatorOffsetPagedQuery',
     'PhabricatorPhabricatorOAuthConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPhameConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPholioConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPhrictionConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPinboardItemView' => 'AphrontView',
     'PhabricatorPinboardView' => 'AphrontView',
     'PhabricatorPolicies' => 'PhabricatorPolicyConstants',
     'PhabricatorPolicyAwareQuery' => 'PhabricatorOffsetPagedQuery',
     'PhabricatorPolicyAwareTestQuery' => 'PhabricatorPolicyAwareQuery',
     'PhabricatorPolicyCapability' => 'PhabricatorPolicyConstants',
     'PhabricatorPolicyConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorPolicyException' => 'Exception',
     'PhabricatorPolicyQuery' => 'PhabricatorQuery',
     'PhabricatorPolicyTestCase' => 'PhabricatorTestCase',
     'PhabricatorPolicyTestObject' => 'PhabricatorPolicyInterface',
     'PhabricatorPolicyType' => 'PhabricatorPolicyConstants',
     'PhabricatorProfileHeaderView' => 'AphrontView',
     'PhabricatorProject' =>
     array(
       0 => 'PhabricatorProjectDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorProjectController' => 'PhabricatorController',
     'PhabricatorProjectCreateController' => 'PhabricatorProjectController',
     'PhabricatorProjectDAO' => 'PhabricatorLiskDAO',
     'PhabricatorProjectEditor' => 'PhabricatorEditor',
     'PhabricatorProjectEditorTestCase' => 'PhabricatorTestCase',
     'PhabricatorProjectListController' => 'PhabricatorProjectController',
     'PhabricatorProjectMembersEditController' => 'PhabricatorProjectController',
     'PhabricatorProjectNameCollisionException' => 'Exception',
     'PhabricatorProjectProfile' => 'PhabricatorProjectDAO',
     'PhabricatorProjectProfileController' => 'PhabricatorProjectController',
     'PhabricatorProjectProfileEditController' => 'PhabricatorProjectController',
     'PhabricatorProjectQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorProjectTransaction' => 'PhabricatorProjectDAO',
     'PhabricatorProjectTransactionType' => 'PhabricatorProjectConstants',
     'PhabricatorProjectUpdateController' => 'PhabricatorProjectController',
     'PhabricatorPropertyListExample' => 'PhabricatorUIExample',
     'PhabricatorPropertyListView' => 'AphrontView',
     'PhabricatorRecaptchaConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorRedirectController' => 'PhabricatorController',
     'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
     'PhabricatorRemarkupControl' => 'AphrontFormTextAreaControl',
     'PhabricatorRemarkupRuleEmbedFile' => 'PhutilRemarkupRule',
     'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
     'PhabricatorRemarkupRuleMeme' => 'PhutilRemarkupRule',
     'PhabricatorRemarkupRuleMention' => 'PhutilRemarkupRule',
     'PhabricatorRemarkupRuleObject' => 'PhutilRemarkupRule',
     'PhabricatorRemarkupRuleYoutube' => 'PhutilRemarkupRule',
     'PhabricatorRepository' =>
     array(
       0 => 'PhabricatorRepositoryDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorRepositoryArcanistProject' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositoryArcanistProjectDeleteController' => 'PhabricatorRepositoryController',
     'PhabricatorRepositoryArcanistProjectEditController' => 'PhabricatorRepositoryController',
     'PhabricatorRepositoryAuditRequest' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositoryBranch' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositoryCommit' =>
     array(
       0 => 'PhabricatorRepositoryDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorRepositoryCommitChangeParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
     'PhabricatorRepositoryCommitData' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositoryCommitHeraldWorker' => 'PhabricatorRepositoryCommitParserWorker',
     'PhabricatorRepositoryCommitMessageParserWorker' => 'PhabricatorRepositoryCommitParserWorker',
     'PhabricatorRepositoryCommitOwnersWorker' => 'PhabricatorRepositoryCommitParserWorker',
     'PhabricatorRepositoryCommitParserWorker' => 'PhabricatorWorker',
     'PhabricatorRepositoryCommitSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PhabricatorRepositoryConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorRepositoryController' => 'PhabricatorController',
     'PhabricatorRepositoryCreateController' => 'PhabricatorRepositoryController',
     'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
     'PhabricatorRepositoryDeleteController' => 'PhabricatorRepositoryController',
     'PhabricatorRepositoryEditController' => 'PhabricatorRepositoryController',
     'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
     'PhabricatorRepositoryGitCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
     'PhabricatorRepositoryListController' => 'PhabricatorRepositoryController',
     'PhabricatorRepositoryManagementDeleteWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementDiscoverWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementListWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementPullWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
     'PhabricatorRepositoryManagementWorkflow' => 'PhutilArgumentWorkflow',
     'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
     'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
     'PhabricatorRepositoryPullLocalDaemon' => 'PhabricatorDaemon',
     'PhabricatorRepositoryPullLocalDaemonTestCase' => 'PhabricatorTestCase',
     'PhabricatorRepositoryQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorRepositoryShortcut' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositorySvnCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
     'PhabricatorRepositorySvnCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
     'PhabricatorRepositorySymbol' => 'PhabricatorRepositoryDAO',
     'PhabricatorRepositoryTestCase' => 'PhabricatorTestCase',
     'PhabricatorS3FileStorageEngine' => 'PhabricatorFileStorageEngine',
     'PhabricatorSSHWorkflow' => 'PhutilArgumentWorkflow',
     'PhabricatorSearchAttachController' => 'PhabricatorSearchBaseController',
     'PhabricatorSearchBaseController' => 'PhabricatorController',
     'PhabricatorSearchConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorSearchController' => 'PhabricatorSearchBaseController',
     'PhabricatorSearchDAO' => 'PhabricatorLiskDAO',
     'PhabricatorSearchDocument' => 'PhabricatorSearchDAO',
     'PhabricatorSearchDocumentField' => 'PhabricatorSearchDAO',
     'PhabricatorSearchDocumentRelationship' => 'PhabricatorSearchDAO',
     'PhabricatorSearchEngineElastic' => 'PhabricatorSearchEngine',
     'PhabricatorSearchEngineMySQL' => 'PhabricatorSearchEngine',
     'PhabricatorSearchManagementIndexWorkflow' => 'PhabricatorSearchManagementWorkflow',
     'PhabricatorSearchManagementWorkflow' => 'PhutilArgumentWorkflow',
     'PhabricatorSearchQuery' => 'PhabricatorSearchDAO',
     'PhabricatorSearchResultView' => 'AphrontView',
     'PhabricatorSearchSelectController' => 'PhabricatorSearchBaseController',
     'PhabricatorSecurityConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorSendGridConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorSettingsAdjustController' => 'PhabricatorController',
     'PhabricatorSettingsMainController' => 'PhabricatorController',
     'PhabricatorSettingsPanelAccount' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelConduit' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelDiffPreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelDisplayPreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelEmailAddresses' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelEmailPreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelHomePreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelLDAP' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelOAuth' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelPassword' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelProfile' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelSSHKeys' => 'PhabricatorSettingsPanel',
     'PhabricatorSettingsPanelSearchPreferences' => 'PhabricatorSettingsPanel',
     'PhabricatorSetupCheckAPC' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckBaseURI' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckDatabase' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckExtensions' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckExtraConfig' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckFacebook' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckGD' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckImagemagick' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckInvalidConfig' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckMail' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckMySQL' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckPHPConfig' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckPath' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckPygment' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckStorage' => 'PhabricatorSetupCheck',
     'PhabricatorSetupCheckTimezone' => 'PhabricatorSetupCheck',
     'PhabricatorSetupIssueExample' => 'PhabricatorUIExample',
     'PhabricatorSetupIssueView' => 'AphrontView',
     'PhabricatorSlowvoteChoice' => 'PhabricatorSlowvoteDAO',
     'PhabricatorSlowvoteComment' => 'PhabricatorSlowvoteDAO',
     'PhabricatorSlowvoteController' => 'PhabricatorController',
     'PhabricatorSlowvoteCreateController' => 'PhabricatorSlowvoteController',
     'PhabricatorSlowvoteDAO' => 'PhabricatorLiskDAO',
     'PhabricatorSlowvoteListController' => 'PhabricatorSlowvoteController',
     'PhabricatorSlowvoteOption' => 'PhabricatorSlowvoteDAO',
     'PhabricatorSlowvotePoll' => 'PhabricatorSlowvoteDAO',
     'PhabricatorSlowvotePollController' => 'PhabricatorSlowvoteController',
     'PhabricatorSlugTestCase' => 'PhabricatorTestCase',
     'PhabricatorSortTableExample' => 'PhabricatorUIExample',
     'PhabricatorSourceCodeView' => 'AphrontView',
     'PhabricatorStandardPageView' => 'PhabricatorBarePageView',
     'PhabricatorStatusController' => 'PhabricatorController',
     'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementDestroyWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementDumpWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementStatusWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementUpgradeWorkflow' => 'PhabricatorStorageManagementWorkflow',
     'PhabricatorStorageManagementWorkflow' => 'PhutilArgumentWorkflow',
     'PhabricatorSubscribersQuery' => 'PhabricatorQuery',
     'PhabricatorSubscriptionsEditController' => 'PhabricatorController',
     'PhabricatorSubscriptionsEditor' => 'PhabricatorEditor',
     'PhabricatorSubscriptionsUIEventListener' => 'PhutilEventListener',
     'PhabricatorSymbolNameLinter' => 'ArcanistXHPASTLintNamingHook',
     'PhabricatorSyntaxHighlightingConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorTagExample' => 'PhabricatorUIExample',
     'PhabricatorTagView' => 'AphrontView',
     'PhabricatorTaskmasterDaemon' => 'PhabricatorDaemon',
     'PhabricatorTestCase' => 'ArcanistPhutilTestCase',
     'PhabricatorTestStorageEngine' => 'PhabricatorFileStorageEngine',
     'PhabricatorTestWorker' => 'PhabricatorWorker',
     'PhabricatorTimelineCursor' => 'PhabricatorTimelineDAO',
     'PhabricatorTimelineDAO' => 'PhabricatorLiskDAO',
     'PhabricatorTimelineEvent' => 'PhabricatorTimelineDAO',
     'PhabricatorTimelineEventData' => 'PhabricatorTimelineDAO',
     'PhabricatorTimelineEventView' => 'AphrontView',
     'PhabricatorTimelineExample' => 'PhabricatorUIExample',
     'PhabricatorTimelineIterator' => 'Iterator',
     'PhabricatorTimelineView' => 'AphrontView',
     'PhabricatorTimer' => 'PhabricatorCountdownDAO',
     'PhabricatorToken' =>
     array(
       0 => 'PhabricatorTokenDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorTokenController' => 'PhabricatorController',
     'PhabricatorTokenCount' => 'PhabricatorTokenDAO',
     'PhabricatorTokenCountQuery' => 'PhabricatorOffsetPagedQuery',
     'PhabricatorTokenDAO' => 'PhabricatorLiskDAO',
     'PhabricatorTokenGiveController' => 'PhabricatorTokenController',
     'PhabricatorTokenGiven' =>
     array(
       0 => 'PhabricatorTokenDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhabricatorTokenGivenController' => 'PhabricatorTokenController',
     'PhabricatorTokenGivenEditor' => 'PhabricatorEditor',
     'PhabricatorTokenGivenFeedStory' => 'PhabricatorFeedStory',
     'PhabricatorTokenGivenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorTokenQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhabricatorTokenUIEventListener' => 'PhutilEventListener',
     'PhabricatorTransactionView' => 'AphrontView',
     'PhabricatorTransformedFile' => 'PhabricatorFileDAO',
     'PhabricatorTranslationsConfigOptions' => 'PhabricatorApplicationConfigOptions',
     'PhabricatorTrivialTestCase' => 'PhabricatorTestCase',
     'PhabricatorTwoColumnExample' => 'PhabricatorUIExample',
     'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
     'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
     'PhabricatorUIExampleRenderController' => 'PhabricatorController',
     'PhabricatorUIListFilterExample' => 'PhabricatorUIExample',
     'PhabricatorUINotificationExample' => 'PhabricatorUIExample',
     'PhabricatorUIPagerExample' => 'PhabricatorUIExample',
     'PhabricatorUITooltipExample' => 'PhabricatorUIExample',
     'PhabricatorUnitsTestCase' => 'PhabricatorTestCase',
     'PhabricatorUser' =>
     array(
       0 => 'PhabricatorUserDAO',
       1 => 'PhutilPerson',
     ),
     'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
     'PhabricatorUserEditor' => 'PhabricatorEditor',
     'PhabricatorUserEmail' => 'PhabricatorUserDAO',
     'PhabricatorUserLDAPInfo' => 'PhabricatorUserDAO',
     'PhabricatorUserLog' => 'PhabricatorUserDAO',
     'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
     'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
     'PhabricatorUserProfile' => 'PhabricatorUserDAO',
     'PhabricatorUserSSHKey' => 'PhabricatorUserDAO',
     'PhabricatorUserSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PhabricatorUserStatus' => 'PhabricatorUserDAO',
     'PhabricatorUserStatusInvalidEpochException' => 'Exception',
     'PhabricatorUserStatusOverlapException' => 'Exception',
     'PhabricatorUserTestCase' => 'PhabricatorTestCase',
     'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask',
     'PhabricatorWorkerArchiveTask' => 'PhabricatorWorkerTask',
     'PhabricatorWorkerDAO' => 'PhabricatorLiskDAO',
     'PhabricatorWorkerLeaseQuery' => 'PhabricatorQuery',
     'PhabricatorWorkerPermanentFailureException' => 'Exception',
     'PhabricatorWorkerTask' => 'PhabricatorWorkerDAO',
     'PhabricatorWorkerTaskData' => 'PhabricatorWorkerDAO',
     'PhabricatorWorkerTaskDetailController' => 'PhabricatorDaemonController',
     'PhabricatorWorkerTaskUpdateController' => 'PhabricatorDaemonController',
     'PhabricatorWorkerTestCase' => 'PhabricatorTestCase',
     'PhabricatorXHPASTViewController' => 'PhabricatorController',
     'PhabricatorXHPASTViewDAO' => 'PhabricatorLiskDAO',
     'PhabricatorXHPASTViewFrameController' => 'PhabricatorXHPASTViewController',
     'PhabricatorXHPASTViewFramesetController' => 'PhabricatorXHPASTViewController',
     'PhabricatorXHPASTViewInputController' => 'PhabricatorXHPASTViewPanelController',
     'PhabricatorXHPASTViewPanelController' => 'PhabricatorXHPASTViewController',
     'PhabricatorXHPASTViewParseTree' => 'PhabricatorXHPASTViewDAO',
     'PhabricatorXHPASTViewRunController' => 'PhabricatorXHPASTViewController',
     'PhabricatorXHPASTViewStreamController' => 'PhabricatorXHPASTViewPanelController',
     'PhabricatorXHPASTViewTreeController' => 'PhabricatorXHPASTViewPanelController',
     'PhabricatorXHProfController' => 'PhabricatorController',
     'PhabricatorXHProfDAO' => 'PhabricatorLiskDAO',
     'PhabricatorXHProfProfileController' => 'PhabricatorXHProfController',
     'PhabricatorXHProfProfileSymbolView' => 'PhabricatorXHProfProfileView',
     'PhabricatorXHProfProfileTopLevelView' => 'PhabricatorXHProfProfileView',
     'PhabricatorXHProfProfileView' => 'AphrontView',
     'PhabricatorXHProfSample' => 'PhabricatorXHProfDAO',
     'PhabricatorXHProfSampleListController' => 'PhabricatorXHProfController',
     'PhabricatorXHProfSampleListView' => 'AphrontView',
     'PhameBasicBlogSkin' => 'PhameBlogSkin',
     'PhameBasicTemplateBlogSkin' => 'PhameBasicBlogSkin',
     'PhameBlog' =>
     array(
       0 => 'PhameDAO',
       1 => 'PhabricatorPolicyInterface',
       2 => 'PhabricatorMarkupInterface',
     ),
     'PhameBlogDeleteController' => 'PhameController',
     'PhameBlogEditController' => 'PhameController',
     'PhameBlogFeedController' => 'PhameController',
     'PhameBlogListController' => 'PhameController',
     'PhameBlogLiveController' => 'PhameController',
     'PhameBlogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhameBlogSkin' => 'PhabricatorController',
     'PhameBlogViewController' => 'PhameController',
     'PhameController' => 'PhabricatorController',
     'PhameDAO' => 'PhabricatorLiskDAO',
     'PhamePost' =>
     array(
       0 => 'PhameDAO',
       1 => 'PhabricatorPolicyInterface',
       2 => 'PhabricatorMarkupInterface',
     ),
     'PhamePostDeleteController' => 'PhameController',
     'PhamePostEditController' => 'PhameController',
     'PhamePostFramedController' => 'PhameController',
     'PhamePostListController' => 'PhameController',
     'PhamePostNewController' => 'PhameController',
     'PhamePostNotLiveController' => 'PhameController',
     'PhamePostPreviewController' => 'PhameController',
     'PhamePostPublishController' => 'PhameController',
     'PhamePostQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhamePostUnpublishController' => 'PhameController',
     'PhamePostView' => 'AphrontView',
     'PhamePostViewController' => 'PhameController',
     'PhameResourceController' => 'CelerityResourceController',
     'PholioController' => 'PhabricatorController',
     'PholioDAO' => 'PhabricatorLiskDAO',
     'PholioImage' =>
     array(
       0 => 'PholioDAO',
       1 => 'PhabricatorMarkupInterface',
     ),
     'PholioInlineCommentEditView' => 'AphrontView',
     'PholioInlineCommentSaveView' => 'AphrontView',
     'PholioInlineCommentView' => 'AphrontView',
     'PholioInlineController' => 'PholioController',
     'PholioInlineDeleteController' => 'PholioController',
     'PholioInlineEditController' => 'PholioController',
     'PholioInlineSaveController' => 'PholioController',
     'PholioInlineViewController' => 'PholioController',
     'PholioMock' =>
     array(
       0 => 'PholioDAO',
       1 => 'PhabricatorMarkupInterface',
       2 => 'PhabricatorPolicyInterface',
       3 => 'PhabricatorSubscribableInterface',
       4 => 'PhabricatorTokenReceiverInterface',
       5 => 'PhabricatorApplicationTransactionInterface',
     ),
     'PholioMockCommentController' => 'PholioController',
     'PholioMockEditController' => 'PholioController',
     'PholioMockEditor' => 'PhabricatorApplicationTransactionEditor',
     'PholioMockEmbedView' => 'AphrontView',
     'PholioMockImagesView' => 'AphrontView',
     'PholioMockListController' => 'PholioController',
     'PholioMockQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PholioMockViewController' => 'PholioController',
     'PholioRemarkupRule' => 'PhabricatorRemarkupRuleObject',
     'PholioReplyHandler' => 'PhabricatorMailReplyHandler',
     'PholioSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PholioTransaction' => 'PhabricatorApplicationTransaction',
     'PholioTransactionComment' => 'PhabricatorApplicationTransactionComment',
     'PholioTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
     'PholioTransactionType' => 'PholioConstants',
     'PholioTransactionView' => 'PhabricatorApplicationTransactionView',
     'PhortuneMonthYearExpiryControl' => 'AphrontFormControl',
     'PhortuneStripeBaseController' => 'PhabricatorController',
     'PhortuneStripePaymentFormView' => 'AphrontView',
     'PhortuneStripeTestPaymentFormController' => 'PhortuneStripeBaseController',
     'PhrictionActionConstants' => 'PhrictionConstants',
     'PhrictionChangeType' => 'PhrictionConstants',
     'PhrictionContent' =>
     array(
       0 => 'PhrictionDAO',
       1 => 'PhabricatorMarkupInterface',
     ),
     'PhrictionController' => 'PhabricatorController',
     'PhrictionDAO' => 'PhabricatorLiskDAO',
     'PhrictionDeleteController' => 'PhrictionController',
     'PhrictionDiffController' => 'PhrictionController',
     'PhrictionDocument' =>
     array(
       0 => 'PhrictionDAO',
       1 => 'PhabricatorPolicyInterface',
     ),
     'PhrictionDocumentController' => 'PhrictionController',
     'PhrictionDocumentEditor' => 'PhabricatorEditor',
     'PhrictionDocumentPreviewController' => 'PhrictionController',
     'PhrictionDocumentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PhrictionDocumentStatus' => 'PhrictionConstants',
     'PhrictionDocumentTestCase' => 'PhabricatorTestCase',
     'PhrictionEditController' => 'PhrictionController',
     'PhrictionHistoryController' => 'PhrictionController',
     'PhrictionListController' => 'PhrictionController',
     'PhrictionMoveController' => 'PhrictionController',
     'PhrictionNewController' => 'PhrictionController',
     'PhrictionRemarkupRule' => 'PhutilRemarkupRule',
     'PhrictionSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PonderAddAnswerView' => 'AphrontView',
     'PonderAddCommentView' => 'AphrontView',
     'PonderAnswer' =>
     array(
       0 => 'PonderDAO',
       1 => 'PhabricatorMarkupInterface',
       2 => 'PonderVotableInterface',
     ),
     'PonderAnswerEditor' => 'PhabricatorEditor',
     'PonderAnswerListView' => 'AphrontView',
     'PonderAnswerPreviewController' => 'PonderController',
     'PonderAnswerQuery' => 'PhabricatorOffsetPagedQuery',
     'PonderAnswerSaveController' => 'PonderController',
     'PonderAnswerViewController' => 'PonderController',
     'PonderAnsweredMail' => 'PonderMail',
     'PonderComment' =>
     array(
       0 => 'PonderDAO',
       1 => 'PhabricatorMarkupInterface',
     ),
     'PonderCommentEditor' => 'PhabricatorEditor',
     'PonderCommentListView' => 'AphrontView',
     'PonderCommentMail' => 'PonderMail',
     'PonderCommentQuery' => 'PhabricatorQuery',
     'PonderCommentSaveController' => 'PonderController',
     'PonderController' => 'PhabricatorController',
     'PonderDAO' => 'PhabricatorLiskDAO',
     'PonderFeedController' => 'PonderController',
     'PonderMail' => 'PhabricatorMail',
     'PonderMentionMail' => 'PonderMail',
     'PonderPostBodyView' => 'AphrontView',
     'PonderQuestion' =>
     array(
       0 => 'PonderDAO',
       1 => 'PhabricatorMarkupInterface',
       2 => 'PonderVotableInterface',
       3 => 'PhabricatorSubscribableInterface',
       4 => 'PhabricatorPolicyInterface',
     ),
     'PonderQuestionAskController' => 'PonderController',
     'PonderQuestionDetailView' => 'AphrontView',
     'PonderQuestionEditor' => 'PhabricatorEditor',
     'PonderQuestionPreviewController' => 'PonderController',
     'PonderQuestionQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
     'PonderQuestionSummaryView' => 'AphrontView',
     'PonderQuestionViewController' => 'PonderController',
     'PonderRemarkupRule' => 'PhabricatorRemarkupRuleObject',
     'PonderReplyHandler' => 'PhabricatorMailReplyHandler',
     'PonderSearchIndexer' => 'PhabricatorSearchDocumentIndexer',
     'PonderUserProfileView' => 'AphrontView',
     'PonderVotableView' => 'AphrontView',
     'PonderVoteEditor' => 'PhabricatorEditor',
     'PonderVoteSaveController' => 'PonderController',
     'QueryFormattingTestCase' => 'PhabricatorTestCase',
+    'ReleephActiveProjectListView' => 'AphrontView',
+    'ReleephAuthorFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephBranch' => 'ReleephDAO',
+    'ReleephBranchAccessController' => 'ReleephController',
+    'ReleephBranchBoxView' => 'AphrontView',
+    'ReleephBranchCommitFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephBranchCreateController' => 'ReleephController',
+    'ReleephBranchEditController' => 'ReleephController',
+    'ReleephBranchEditor' => 'PhabricatorEditor',
+    'ReleephBranchNamePreviewController' => 'PhabricatorController',
+    'ReleephBranchPreviewView' => 'AphrontFormControl',
+    'ReleephBranchViewController' => 'ReleephController',
+    'ReleephCommitFinderException' => 'Exception',
+    'ReleephCommitMessageFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephController' => 'PhabricatorController',
+    'ReleephDAO' => 'PhabricatorLiskDAO',
+    'ReleephDefaultFieldSelector' => 'ReleephFieldSelector',
+    'ReleephDefaultUserView' => 'ReleephUserView',
+    'ReleephDiffChurnFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephDiffMessageFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephDiffSizeFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephEvent' => 'ReleephDAO',
+    'ReleephFieldParseException' => 'Exception',
+    'ReleephFieldSpecificationIncompleteException' => 'Exception',
+    'ReleephInactiveProjectListView' => 'AphrontView',
+    'ReleephIntentFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephLevelFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephObjectHandleLoader' => 'ObjectHandleLoader',
+    'ReleephOriginalCommitFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephProject' => 'ReleephDAO',
+    'ReleephProjectActionController' => 'ReleephController',
+    'ReleephProjectCreateController' => 'ReleephController',
+    'ReleephProjectEditController' => 'ReleephController',
+    'ReleephProjectListController' => 'PhabricatorController',
+    'ReleephProjectView' => 'AphrontView',
+    'ReleephProjectViewController' => 'ReleephController',
+    'ReleephReasonFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephRequest' => 'ReleephDAO',
+    'ReleephRequestActionController' => 'ReleephController',
+    'ReleephRequestCreateController' => 'ReleephController',
+    'ReleephRequestDifferentialCreateController' => 'ReleephController',
+    'ReleephRequestEditController' => 'ReleephController',
+    'ReleephRequestEditor' => 'PhabricatorEditor',
+    'ReleephRequestEvent' => 'ReleephDAO',
+    'ReleephRequestEventListView' => 'AphrontView',
+    'ReleephRequestException' => 'Exception',
+    'ReleephRequestHeaderListView' => 'AphrontView',
+    'ReleephRequestHeaderView' => 'AphrontView',
+    'ReleephRequestIntentsView' => 'AphrontView',
+    'ReleephRequestStatusView' => 'AphrontView',
+    'ReleephRequestTypeaheadControl' => 'AphrontFormControl',
+    'ReleephRequestTypeaheadController' => 'PhabricatorTypeaheadDatasourceController',
+    'ReleephRequestViewController' => 'ReleephController',
+    'ReleephRequestorFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephRevisionFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephRiskFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephSeverityFieldSpecification' => 'ReleephLevelFieldSpecification',
+    'ReleephStatusFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephSummaryFieldSpecification' => 'ReleephFieldSpecification',
+    'ReleephUserView' => 'AphrontView',
   ),
 ));
diff --git a/src/applications/releeph/ReleephObjectHandleLoader.php b/src/applications/releeph/ReleephObjectHandleLoader.php
new file mode 100644
index 000000000..553ead7a5
--- /dev/null
+++ b/src/applications/releeph/ReleephObjectHandleLoader.php
@@ -0,0 +1,92 @@
+<?php
+
+final class ReleephObjectHandleLoader extends ObjectHandleLoader {
+
+  /**
+   * The intention for phid.external-loaders is for each new 4-char PHID type
+   * to point to a different external loader for that type.
+   *
+   * For brevity, we instead just have this one class that can load any type of
+   * Releeph PHID.
+   */
+
+  public function loadHandles(array $phids) {
+    $types = array();
+
+    foreach ($phids as $phid) {
+      $type = phid_get_type($phid);
+      $types[$type][] = $phid;
+    }
+
+    $handles = array();
+
+    foreach ($types as $type => $phids) {
+      switch ($type) {
+        case ReleephPHIDConstants::PHID_TYPE_RERQ:
+          $object = new ReleephRequest();
+
+          $instances = $object->loadAllWhere('phid in (%Ls)', $phids);
+          $instances = mpull($instances, null, 'getPHID');
+
+          foreach ($phids as $phid) {
+            $instance = $instances[$phid];
+            $handle = new PhabricatorObjectHandle();
+            $handle->setPHID($phid);
+            $handle->setType($type);
+            $handle->setURI('/RQ'.$instance->getID());
+
+            $name = 'RQ'.$instance->getID();
+            $handle->setName($name);
+            $handle->setFullName($name.': '.$instance->getSummaryForDisplay());
+            $handle->setComplete(true);
+
+            $handles[$phid] = $handle;
+          }
+          break;
+
+        case ReleephPHIDConstants::PHID_TYPE_REBR:
+          $object = new ReleephBranch();
+
+          $branches = $object->loadAllWhere('phid IN (%Ls)', $phids);
+          $branches = mpull($branches, null, 'getPHID');
+
+          foreach ($phids as $phid) {
+            $branch = $branches[$phid];
+            $handle = new PhabricatorObjectHandle();
+            $handle->setPHID($phid);
+            $handle->setType($type);
+            $handle->setURI($branch->getURI());
+            $handle->setName($branch->getBasename());
+            $handle->setFullName($branch->getName());
+            $handle->setComplete(true);
+            $handles[$phid] = $handle;
+          }
+          break;
+
+        case ReleephPHIDConstants::PHID_TYPE_REPR:
+          $object = new ReleephProject();
+
+          $instances = $object->loadAllWhere('phid IN (%Ls)', $phids);
+          $instances = mpull($instances, null, 'getPHID');
+
+          foreach ($phids as $phid) {
+            $instance = $instances[$phid];
+            $handle = new PhabricatorObjectHandle();
+            $handle->setPHID($phid);
+            $handle->setType($type);
+            $handle->setURI($instance->getURI());
+            $handle->setName($instance->getName()); // no fullName for proejcts
+            $handle->setComplete(true);
+            $handles[$phid] = $handle;
+          }
+          break;
+
+        default:
+          throw new Exception('unknown type '.$type);
+      }
+    }
+
+    return $handles;
+  }
+
+}
diff --git a/src/applications/releeph/ReleephPHIDConstants.php b/src/applications/releeph/ReleephPHIDConstants.php
new file mode 100644
index 000000000..6265da6c8
--- /dev/null
+++ b/src/applications/releeph/ReleephPHIDConstants.php
@@ -0,0 +1,9 @@
+<?php
+
+final class ReleephPHIDConstants {
+
+  // Releeph
+  const PHID_TYPE_REPR = 'REPR';
+  const PHID_TYPE_REBR = 'REBR';
+  const PHID_TYPE_RERQ = 'RERQ';
+}
diff --git a/src/applications/releeph/application/PhabricatorApplicationReleeph.php b/src/applications/releeph/application/PhabricatorApplicationReleeph.php
new file mode 100644
index 000000000..4512ba0d6
--- /dev/null
+++ b/src/applications/releeph/application/PhabricatorApplicationReleeph.php
@@ -0,0 +1,86 @@
+<?php
+
+final class PhabricatorApplicationReleeph extends PhabricatorApplication {
+
+  public function getName() {
+    return 'Releeph';
+  }
+
+  public function getShortDescription() {
+    return 'Release Branches';
+  }
+
+  public function getBaseURI() {
+    return '/releeph/';
+  }
+
+  public function getAutospriteName() {
+    return 'releeph';
+  }
+
+  public function getApplicationGroup() {
+    return self::GROUP_ORGANIZATION;
+  }
+
+  public function isInstalled() {
+    if (PhabricatorEnv::getEnvConfig('releeph.installed')) {
+      return parent::isInstalled();
+    }
+    return false;
+  }
+
+  public function getRoutes() {
+    return array(
+      '/RQ(?P<requestID>[1-9]\d*)' => 'ReleephRequestViewController',
+      '/releeph/' => array(
+        '' => 'ReleephProjectListController',
+        'project/' => array(
+          '' => 'ReleephProjectListController',
+          'inactive/' => 'ReleephProjectListController',
+          'create/' => 'ReleephProjectCreateController',
+          '(?P<projectID>[1-9]\d*)/' => array(
+            '' => 'ReleephProjectViewController',
+            'closedbranches/' => 'ReleephProjectViewController',
+            'edit/' => 'ReleephProjectEditController',
+            'cutbranch/' => 'ReleephBranchCreateController',
+            'action/(?P<action>.+)/' => 'ReleephProjectActionController',
+          ),
+        ),
+        'branch/' => array(
+          'edit/(?P<branchID>[1-9]\d*)/' =>
+            'ReleephBranchEditController',
+          '(?P<action>close|re-open)/(?P<branchID>[1-9]\d*)/' =>
+            'ReleephBranchAccessController',
+          'preview/' => 'ReleephBranchNamePreviewController',
+
+          // Left in, just in case the by-name stuff fails!
+          '(?P<branchID>[^/]+)/' =>
+            'ReleephBranchViewController',
+        ),
+        'request/' => array(
+          '(?P<requestID>[1-9]\d*)/' => 'ReleephRequestViewController',
+          'create/' => 'ReleephRequestCreateController',
+          'differentialcreate/' => array(
+            'D(?P<diffRevID>[1-9]\d*)' =>
+              'ReleephRequestDifferentialCreateController',
+          ),
+          'edit/(?P<requestID>[1-9]\d*)/' =>
+            'ReleephRequestEditController',
+          'action/(?P<action>.+)/(?P<requestID>[1-9]\d*)/' =>
+            'ReleephRequestActionController',
+          'typeahead/' =>
+            'ReleephRequestTypeaheadController',
+        ),
+
+        // Branch navigation made pretty, as it's the most common:
+        '(?P<projectName>[^/]+)/(?P<branchName>[^/]+)/' => array(
+          ''              => 'ReleephBranchViewController',
+          'edit/'         => 'ReleephBranchEditController',
+          'request/'      => 'ReleephRequestCreateController',
+          '(?P<action>close|re-open)/' => 'ReleephBranchAccessController',
+        ),
+      )
+    );
+  }
+
+}
diff --git a/src/applications/releeph/commitfinder/ReleephCommitFinder.php b/src/applications/releeph/commitfinder/ReleephCommitFinder.php
new file mode 100644
index 000000000..321294441
--- /dev/null
+++ b/src/applications/releeph/commitfinder/ReleephCommitFinder.php
@@ -0,0 +1,74 @@
+<?php
+
+final class ReleephCommitFinder {
+
+  private $releephProject;
+
+  public function setReleephProject(ReleephProject $rp) {
+    $this->releephProject = $rp;
+    return $this;
+  }
+
+  public function fromPartial($partial_string) {
+    // Look for diffs
+    $matches = array();
+    if (preg_match('/^D([1-9]\d*)$/', $partial_string, $matches)) {
+      $diff_id = $matches[1];
+      $diff_rev = id(new DifferentialRevision())->load($diff_id);
+      if (!$diff_rev) {
+        throw new ReleephCommitFinderException(
+          "{$partial_string} does not refer to an existing diff.");
+      }
+      $commit_phids = $diff_rev->loadCommitPHIDs();
+
+      if (!$commit_phids) {
+        throw new ReleephCommitFinderException(
+          "{$partial_string} has no commits associated with it yet.");
+      }
+
+      $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere(
+        'phid IN (%Ls) ORDER BY epoch ASC',
+        $commit_phids);
+      return head($commits);
+    }
+
+    // Look for a raw commit number, or r<callsign><commit-number>.
+    $repository = $this->releephProject->loadPhabricatorRepository();
+    $dr_data = null;
+    $matches = array();
+    if (preg_match('/^r(?P<callsign>[A-Z]+)(?P<commit>\w+)$/',
+      $partial_string, $matches)) {
+      $callsign = $matches['callsign'];
+      if ($callsign != $repository->getCallsign()) {
+        throw new ReleephCommitFinderException(sprintf(
+          "%s is in a different repository to this Releeph project (%s).",
+          $partial_string,
+          $repository->getCallsign()));
+      } else {
+        $dr_data = $matches;
+      }
+    } else {
+      $dr_data = array(
+        'callsign' => $repository->getCallsign(),
+        'commit' => $partial_string
+      );
+    }
+
+    try {
+      $dr = DiffusionRequest::newFromDictionary($dr_data);
+    } catch (Exception $ex) {
+      $message = "No commit matches {$partial_string}: ".$ex->getMessage();
+      throw new ReleephCommitFinderException($message);
+    }
+
+    $phabricator_repository_commit = $dr->loadCommit();
+
+    if (!$phabricator_repository_commit) {
+      throw new ReleephCommitFinderException(
+        "The commit {$partial_string} doesn't exist in this repository.");
+    }
+
+    return $phabricator_repository_commit;
+  }
+
+}
diff --git a/src/applications/releeph/commitfinder/ReleephCommitFinderException.php b/src/applications/releeph/commitfinder/ReleephCommitFinderException.php
new file mode 100644
index 000000000..8250de592
--- /dev/null
+++ b/src/applications/releeph/commitfinder/ReleephCommitFinderException.php
@@ -0,0 +1,3 @@
+<?php
+
+final class ReleephCommitFinderException extends Exception {}
diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_Method.php
new file mode 100644
index 000000000..7d5d9aa08
--- /dev/null
+++ b/src/applications/releeph/conduit/ConduitAPI_releeph_Method.php
@@ -0,0 +1,9 @@
+<?php
+
+abstract class ConduitAPI_releeph_Method extends ConduitAPIMethod {
+
+  public function getApplication() {
+    return PhabricatorApplication::getByClass('PhabricatorApplicationReleeph');
+  }
+
+}
diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_getbranches_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_getbranches_Method.php
new file mode 100644
index 000000000..d7a76e842
--- /dev/null
+++ b/src/applications/releeph/conduit/ConduitAPI_releeph_getbranches_Method.php
@@ -0,0 +1,62 @@
+<?php
+
+final class ConduitAPI_releeph_getbranches_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodDescription() {
+    return "Return information about all active Releeph branches.";
+  }
+
+  public function defineParamTypes() {
+    return array(
+    );
+  }
+
+  public function defineReturnType() {
+    return 'nonempty list<dict<string, wild>>';
+  }
+
+  public function defineErrorTypes() {
+    return array(
+    );
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $results = array();
+
+    $projects = id(new ReleephProject())->loadAllWhere('isActive = 1');
+
+    foreach ($projects as $project) {
+      $repository = $project->loadOneRelative(
+        id(new PhabricatorRepository()),
+        'id',
+        'getRepositoryID');
+
+      $branches = $project->loadRelatives(
+        id(new ReleephBranch()),
+        'releephProjectID',
+        'getID',
+        'isActive = 1');
+
+      foreach ($branches as $branch) {
+        $full_branch_name = $branch->getName();
+
+        $cut_point_commit = $branch->loadOneRelative(
+          id(new PhabricatorRepositoryCommit()),
+          'phid',
+          'getCutPointCommitPHID');
+
+        $results[] = array(
+          'project'         => $project->getName(),
+          'repository'      => $repository->getCallsign(),
+          'branch'          => $branch->getBasename(),
+          'fullBranchName'  => $full_branch_name,
+          'symbolicName'    => $branch->getSymbolicName(),
+          'cutPoint'        => $branch->getCutPointCommitIdentifier(),
+        );
+      }
+    }
+
+    return $results;
+  }
+}
diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_projectinfo_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_projectinfo_Method.php
new file mode 100644
index 000000000..950e62953
--- /dev/null
+++ b/src/applications/releeph/conduit/ConduitAPI_releeph_projectinfo_Method.php
@@ -0,0 +1,96 @@
+<?php
+
+final class ConduitAPI_releeph_projectinfo_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodDescription() {
+    return
+      "Fetch information about all Releeph projects ".
+      "for a given Arcanist project.";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'arcProjectName' => 'optional string',
+    );
+  }
+
+  public function defineReturnType() {
+    return 'dict<string, wild>';
+  }
+
+  public function defineErrorTypes() {
+    return array(
+      "ERR_UNKNOWN_ARC" =>
+        "The given Arcanist project name doesn't exist in the ".
+        "installation of Phabricator you are accessing.",
+    );
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $arc_project_name = $request->getValue('arcProjectName');
+    if ($arc_project_name) {
+      $arc_project = id(new PhabricatorRepositoryArcanistProject())
+        ->loadOneWhere('name = %s', $arc_project_name);
+      if (!$arc_project) {
+        throw id(new ConduitException("ERR_UNKNOWN_ARC"))
+          ->setErrorDescription(
+            "Unknown Arcanist project '{$arc_project_name}': ".
+            "are you using the correct Conduit URI?");
+      }
+
+      $releeph_projects = id(new ReleephProject())
+        ->loadAllWhere('arcanistProjectID = %d', $arc_project->getID());
+    } else {
+      $releeph_projects = id(new ReleephProject())->loadAll();
+    }
+
+    $releeph_projects = mfilter($releeph_projects, 'getIsActive');
+
+    $result = array();
+    foreach ($releeph_projects as $releeph_project) {
+      $selector = $releeph_project->getReleephFieldSelector();
+      $fields = $selector->getFieldSpecifications();
+
+      $fields_info = array();
+      foreach ($fields as $field) {
+        $field->setReleephProject($releeph_project);
+        if ($field->isEditable()) {
+          $key = $field->getKeyForConduit();
+          $fields_info[$key] = array(
+            'class'   => get_class($field),
+            'name'    => $field->getName(),
+            'key'     => $key,
+            'arcHelp' => $field->renderHelpForArcanist(),
+          );
+        }
+      }
+
+      $releeph_branches = mfilter(
+        id(new ReleephBranch())
+          ->loadAllWhere('releephProjectID = %d', $releeph_project->getID()),
+        'getIsActive');
+
+      $releeph_branches_struct = array();
+      foreach ($releeph_branches as $branch) {
+        $releeph_branches_struct[] = array(
+          'branchName'  => $branch->getName(),
+          'projectName' => $releeph_project->getName(),
+          'projectPHID' => $releeph_project->getPHID(),
+          'branchPHID'  => $branch->getPHID(),
+        );
+      }
+
+      $result[] = array(
+        'projectName' => $releeph_project->getName(),
+        'projectPHID' => $releeph_project->getPHID(),
+        'branches'    => $releeph_branches_struct,
+        'fields'      => $fields_info,
+      );
+    }
+
+    return $result;
+  }
+
+
+}
diff --git a/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php b/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php
new file mode 100644
index 000000000..68b2a3010
--- /dev/null
+++ b/src/applications/releeph/conduit/ConduitAPI_releeph_request_Method.php
@@ -0,0 +1,130 @@
+<?php
+
+final class ConduitAPI_releeph_request_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodDescription() {
+    return "Request a commit or diff to be picked to a branch.";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'branchPHID'  => 'required string',
+      'things'      => 'required string',
+      'fields'      => 'dict<string, string>',
+    );
+  }
+
+  public function defineReturnType() {
+    return 'dict<string, wild>';
+  }
+
+  public function defineErrorTypes() {
+    return array(
+      "ERR_BRANCH"      => 'Unknown Releeph branch.',
+      "ERR_FIELD_PARSE" => 'Unable to parse a Releeph field.',
+    );
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $branch_phid = $request->getValue('branchPHID');
+    $releeph_branch = id(new ReleephBranch())
+      ->loadOneWhere('phid = %s', $branch_phid);
+
+    if (!$releeph_branch) {
+      throw id(new ConduitException("ERR_BRANCH"))->setErrorDescription(
+        "No ReleephBranch found with PHID {$branch_phid}!");
+    }
+
+    $releeph_project = $releeph_branch->loadReleephProject();
+
+    // Find the requested commit identifiers
+    $requested_commits = array();
+    $things = $request->getValue('things');
+    $finder = id(new ReleephCommitFinder())
+      ->setReleephProject($releeph_project);
+    foreach ($things as $thing) {
+      try {
+        $requested_commits[$thing] = $finder->fromPartial($thing);
+      } catch (ReleephCommitFinderException $ex) {
+        throw id(new ConduitException('ERR_NO_MATCHES'))
+          ->setErrorDescription($ex->getMessage());
+      }
+    }
+
+    // Find any existing requests that clash on the commit id, for this branch
+    $existing_releeph_requests = id(new ReleephRequest())->loadAllWhere(
+      'requestCommitPHID IN (%Ls) AND branchID = %d',
+      mpull($requested_commits, 'getPHID'),
+      $releeph_branch->getID());
+    $existing_releeph_requests = mpull(
+      $existing_releeph_requests,
+      null,
+      'getRequestCommitPHID');
+
+    $selector = $releeph_project->getReleephFieldSelector();
+    $fields = $selector->getFieldSpecifications();
+    foreach ($fields as $field) {
+      $field
+        ->setReleephProject($releeph_project)
+        ->setReleephBranch($releeph_branch);
+    }
+
+    $results = array();
+    foreach ($requested_commits as $thing => $commit) {
+      $phid = $commit->getPHID();
+      $handles = id(new PhabricatorObjectHandleData(array($phid)))
+        ->setViewer($request->getUser())
+        ->loadHandles();
+      $name = id($handles[$phid])->getName();
+
+      $releeph_request = null;
+
+      $existing_releeph_request = idx($existing_releeph_requests, $phid);
+      if ($existing_releeph_request) {
+        $releeph_request = $existing_releeph_request;
+      } else {
+        $releeph_request = new ReleephRequest();
+        foreach ($fields as $field) {
+          if (!$field->isEditable()) {
+            continue;
+          }
+          $field->setReleephRequest($releeph_request);
+          try {
+            $field->setValueFromConduitAPIRequest($request);
+          } catch (ReleephFieldParseException $ex) {
+            throw id(new ConduitException('ERR_FIELD_PARSE'))
+              ->setErrorDescription($ex->getMessage());
+          }
+        }
+        id(new ReleephRequestEditor($releeph_request))
+          ->setActor($request->getUser())
+          ->create($commit, $releeph_branch);
+      }
+
+      $releeph_branch->populateReleephRequestHandles(
+        $request->getUser(),
+        array($releeph_request));
+      $rq_handles = $releeph_request->getHandles();
+      $requestor_phid = $releeph_request->getRequestUserPHID();
+      $requestor = $rq_handles[$requestor_phid]->getName();
+
+      $url = PhabricatorEnv::getProductionURI('/RQ'.$releeph_request->getID());
+
+      $results[$thing] = array(
+        'thing'         => $thing,
+        'branch'        => $releeph_branch->getDisplayNameWithDetail(),
+        'commitName'    => $name,
+        'commitID'      => $commit->getCommitIdentifier(),
+        'url'           => $url,
+        'requestID'     => $releeph_request->getID(),
+        'requestor'     => $requestor,
+        'requestTime'   => $releeph_request->getDateCreated(),
+        'existing'      => $existing_releeph_request !== null,
+      );
+    }
+
+    return $results;
+  }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_canpush_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_canpush_Method.php
new file mode 100644
index 000000000..d37bf8529
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_canpush_Method.php
@@ -0,0 +1,39 @@
+<?php
+
+final class ConduitAPI_releephwork_canpush_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodStatus() {
+    return self::METHOD_STATUS_UNSTABLE;
+  }
+
+  public function getMethodDescription() {
+    return "Return whether the conduit user is allowed to push.";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'projectPHID' => 'required string',
+    );
+  }
+
+  public function defineReturnType() {
+    return 'bool';
+  }
+
+  public function defineErrorTypes() {
+    return array();
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $releeph_project = id(new ReleephProject())
+      ->loadOneWhere('phid = %s', $request->getValue('projectPHID'));
+
+    if (!$releeph_project->getPushers()) {
+      return true;
+    } else {
+      $user = $request->getUser();
+      return $releeph_project->isPusher($user);
+    }
+  }
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getauthorinfo_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getauthorinfo_Method.php
new file mode 100644
index 000000000..62b594c78
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getauthorinfo_Method.php
@@ -0,0 +1,43 @@
+<?php
+
+final class ConduitAPI_releephwork_getauthorinfo_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodStatus() {
+    return self::METHOD_STATUS_UNSTABLE;
+  }
+
+  public function getMethodDescription() {
+    return "Return a string to use as the VCS author.";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'userPHID'  => 'required string',
+      'vcsType'   => 'required string',
+    );
+  }
+
+  public function defineReturnType() {
+    return 'nonempty string';
+  }
+
+  public function defineErrorTypes() {
+    return array();
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $user = id(new PhabricatorUser())
+      ->loadOneWhere('phid = %s', $request->getValue('userPHID'));
+
+    $email = $user->loadPrimaryEmailAddress();
+    if (is_numeric($email)) {
+      $email = $user->getUserName().'@fb.com';
+    }
+
+    return sprintf(
+      '%s <%s>',
+      $user->getRealName(),
+      $email);
+  }
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranch_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranch_Method.php
new file mode 100644
index 000000000..9b9f57e40
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranch_Method.php
@@ -0,0 +1,52 @@
+<?php
+
+final class ConduitAPI_releephwork_getbranch_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodStatus() {
+    return self::METHOD_STATUS_UNSTABLE;
+  }
+
+  public function getMethodDescription() {
+    return "Return information to help checkout / cut a Releeph branch.";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'branchPHID'  => 'required string',
+    );
+  }
+
+  public function defineReturnType() {
+    return 'dict<string, wild>';
+  }
+
+  public function defineErrorTypes() {
+    return array();
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $branch = id(new ReleephBranch())
+      ->loadOneWhere('phid = %s', $request->getValue('branchPHID'));
+
+    $cut_phid = $branch->getCutPointCommitPHID();
+    $phids = array($cut_phid);
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      ->setViewer($request->getUser())
+      ->loadHandles();
+
+    $project = $branch->loadReleephProject();
+    $repo = $project->loadPhabricatorRepository();
+
+    return array(
+      'branchName'      => $branch->getName(),
+      'branchPHID'      => $branch->getPHID(),
+      'vcsType'         => $repo->getVersionControlSystem(),
+      'cutCommitID'     => $branch->getCutPointCommitIdentifier(),
+      'cutCommitName'   => $handles[$cut_phid]->getName(),
+      'creatorPHID'     => $branch->getCreatedByUserPHID(),
+      'trunk'           => $project->getTrunkBranch(),
+    );
+  }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranchcommitmessage_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranchcommitmessage_Method.php
new file mode 100644
index 000000000..5549591fc
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getbranchcommitmessage_Method.php
@@ -0,0 +1,94 @@
+<?php
+
+final class ConduitAPI_releephwork_getbranchcommitmessage_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodStatus() {
+    return self::METHOD_STATUS_UNSTABLE;
+  }
+
+  public function getMethodDescription() {
+    return "Get a commit message for committing a Releeph branch.";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'branchPHID'  => 'required string',
+    );
+  }
+
+  public function defineReturnType() {
+    return 'nonempty string';
+  }
+
+  public function defineErrorTypes() {
+    return array();
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $branch = id(new ReleephBranch())
+      ->loadOneWhere('phid = %s', $request->getValue('branchPHID'));
+
+    $project = $branch->loadReleephProject();
+
+    $creator_phid = $branch->getCreatedByUserPHID();
+    $cut_phid = $branch->getCutPointCommitPHID();
+
+    $phids = array(
+      $branch->getPHID(),
+      $project->getPHID(),
+      $creator_phid,
+      $cut_phid,
+    );
+
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      ->setViewer($request->getUser())
+      ->loadHandles();
+
+    $h_branch = $handles[$branch->getPHID()];
+    $h_project = $handles[$project->getPHID()];
+
+    // Not as customizable as a ReleephRequest's commit message.  It doesn't
+    // really need to be.
+    $commit_message = array();
+    $commit_message[] = $h_branch->getFullName();
+    $commit_message[] = $h_branch->getURI();
+
+    $commit_message[] = "Cut Point: ".$handles[$cut_phid]->getName();
+
+    $cut_point_pr_commit = id(new PhabricatorRepositoryCommit())
+      ->loadOneWhere('phid = %s', $cut_phid);
+    $cut_point_commit_date = strftime(
+      '%Y-%m-%d %H:%M:%S%z',
+      $cut_point_pr_commit->getEpoch());
+    $commit_message[] = "Cut Point Date: {$cut_point_commit_date}";
+
+    $commit_message[] = "Created By: ".$handles[$creator_phid]->getName();
+
+    $project_uri = $project->getURI();
+    $commit_message[] = "Project: ".$h_project->getName()." ".$project_uri;
+
+    /**
+     * Required for 090-limit_new_branch_creations.sh in
+     * admin/scripts/git/hosting/hooks/update.d (in the E repo):
+     *
+     *   http://fburl.com/2372545
+     *
+     * The commit message must have a line saying:
+     *
+     *   @new-branch: <branch-name>
+     *
+     */
+    $repo = $project->loadPhabricatorRepository();
+    switch ($repo->getVersionControlSystem()) {
+      case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
+        $commit_message[] = sprintf(
+          '@new-branch: %s',
+          $branch->getName());
+        break;
+    }
+
+    return implode("\n\n", $commit_message);
+  }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php
new file mode 100644
index 000000000..324136957
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getcommitmessage_Method.php
@@ -0,0 +1,90 @@
+<?php
+
+final class ConduitAPI_releephwork_getcommitmessage_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodStatus() {
+    return self::METHOD_STATUS_UNSTABLE;
+  }
+
+  public function getMethodDescription() {
+    return
+      "Get commit message components for building ".
+      "a ReleephRequest commit message.";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'requestPHID' => 'required string',
+      'action'      => 'required enum<"pick", "revert">',
+    );
+  }
+
+  public function defineReturnType() {
+    return 'dict<string, string>';
+  }
+
+  public function defineErrorTypes() {
+    return array();
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $releeph_request = id(new ReleephRequest())
+      ->loadOneWhere('phid = %s', $request->getValue('requestPHID'));
+
+    $action = $request->getValue('action');
+
+    $title = $releeph_request->getSummaryForDisplay();
+
+    $commit_message = array();
+
+    $project = $releeph_request->loadReleephProject();
+    $branch = $releeph_request->loadReleephBranch();
+
+    $selector = $project->getReleephFieldSelector();
+    $fields = $selector->getFieldSpecifications();
+    $fields = $selector->sortFieldsForCommitMessage($fields);
+
+    foreach ($fields as $field) {
+      $field
+        ->setUser($request->getUser())
+        ->setReleephProject($project)
+        ->setReleephBranch($branch)
+        ->setReleephRequest($releeph_request);
+
+      $label = null;
+      $value = null;
+
+      switch ($action) {
+        case 'pick':
+          if ($field->shouldAppearOnCommitMessage()) {
+            $label = $field->renderLabelForCommitMessage();
+            $value = $field->renderValueForCommitMessage();
+          }
+          break;
+
+        case 'revert':
+          if ($field->shouldAppearOnRevertMessage()) {
+            $label = $field->renderLabelForRevertMessage();
+            $value = $field->renderValueForRevertMessage();
+          }
+          break;
+      }
+
+      if ($label && $value) {
+        if (strpos($value, "\n") !== false ||
+            substr($value, 0, 2) === '  ') {
+          $commit_message[] = "{$label}:\n{$value}";
+        } else {
+          $commit_message[] = "{$label}: {$value}";
+        }
+      }
+    }
+
+    return array(
+      'title' => $title,
+      'body'  => implode("\n\n", $commit_message),
+    );
+  }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getorigcommitmessage_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getorigcommitmessage_Method.php
new file mode 100644
index 000000000..4c6efe55e
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_getorigcommitmessage_Method.php
@@ -0,0 +1,35 @@
+<?php
+
+final class ConduitAPI_releephwork_getorigcommitmessage_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodStatus() {
+    return self::METHOD_STATUS_UNSTABLE;
+  }
+
+  public function getMethodDescription() {
+    return "Return the original commit message for the given commit.";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'commitPHID' => 'required string',
+    );
+  }
+
+  public function defineReturnType() {
+    return 'nonempty string';
+  }
+
+  public function defineErrorTypes() {
+    return array();
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $commit = id(new PhabricatorRepositoryCommit())
+      ->loadOneWhere('phid = %s', $request->getValue('commitPHID'));
+    $commit_data = $commit->loadCommitData();
+    $commit_message = $commit_data->getCommitMessage();
+    return trim($commit_message);
+  }
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php
new file mode 100644
index 000000000..c17dbbdcb
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_nextrequest_Method.php
@@ -0,0 +1,208 @@
+<?php
+
+final class ConduitAPI_releephwork_nextrequest_Method
+  extends ConduitAPI_releeph_Method {
+
+  private $project;
+  private $branch;
+
+  public function getMethodStatus() {
+    return self::METHOD_STATUS_UNSTABLE;
+  }
+
+  public function getMethodDescription() {
+    return
+      "Return info required to cut a branch, ".
+      "and pick and revert ReleephRequests";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'branchPHID'  => 'required int',
+      'seen'        => 'required list<string, bool>',
+    );
+  }
+
+  public function defineReturnType() {
+    return '';
+  }
+
+  public function defineErrorTypes() {
+    return array(
+      'ERR-NOT-PUSHER' =>
+        'You are not listed as a pusher for thie Releeph project!',
+    );
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $seen = $request->getValue('seen');
+
+    $branch = id(new ReleephBranch())
+      ->loadOneWhere('phid = %s', $request->getValue('branchPHID'));
+
+    $project = $branch->loadReleephProject();
+
+    $needs_pick = array();
+    $needs_revert = array();
+
+    $releeph_requests = $branch->loadReleephRequests($request->getUser());
+
+    foreach ($releeph_requests as $candidate) {
+      $phid = $candidate->getPHID();
+      if (idx($seen, $phid)) {
+        continue;
+      }
+
+      $should = $candidate->shouldBeInBranch();
+      $in = $candidate->getInBranch();
+      if ($should && !$in) {
+        $needs_pick[] = $candidate;
+      }
+      if (!$should && $in) {
+        $needs_revert[] = $candidate;
+      }
+    }
+
+    /**
+     * Sort both needs_pick and needs_revert in ascending commit order, as
+     * discovered by Phabricator (using the `id` column to perform that
+     * ordering).
+     *
+     * This is easy for $needs_pick as the ordinal is stored.  It is hard for
+     * reverts, as we have to look that information up.
+     */
+    $needs_pick = msort($needs_pick, 'getRequestCommitOrdinal');
+    $needs_revert = $this->sortReverts($needs_revert);
+
+    /**
+     * Do reverts first in reverse order, then the picks in original-commit
+     * order.
+     *
+     * This seems like the correct thing to do, but there may be a better
+     * algorithm for the releephwork.nextrequest Conduit call that orders
+     * things better.
+     *
+     * We could also button-mash our way through everything that failed (at the
+     * end of the run) to try failed things again.
+     */
+    $releeph_request = null;
+    $action = null;
+    if ($needs_revert) {
+      $releeph_request = last($needs_revert);
+      $action = 'revert';
+      $commit_id = $releeph_request->getCommitIdentifier();
+      $commit_phid = $releeph_request->getCommitPHID();
+    } elseif ($needs_pick) {
+      $releeph_request = head($needs_pick);
+      $action = 'pick';
+      $commit_id = $releeph_request->getRequestCommitIdentifier();
+      $commit_phid = $releeph_request->getRequestCommitPHID();
+    } else {
+      // Return early if there's nothing to do!
+      return array();
+    }
+
+    // Build the response
+    $phids = array();
+    $phids[] = $commit_phid;
+
+    $diff_phid = null;
+    $diff_rev_id = null;
+    $diff_rev = $releeph_request->loadDifferentialRevision();
+    if ($diff_rev) {
+      $diff_phid = $diff_rev->getPHID();
+      $phids[] = $diff_phid;
+      $diff_rev_id = $diff_rev->getID();
+    }
+
+    $phids[] = $releeph_request->getPHID();
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      ->setViewer($request->getUser())
+      ->loadHandles();
+
+    $diff_name = null;
+    if ($diff_rev) {
+      $diff_name = $handles[$diff_phid]->getName();
+    }
+
+    // Calculate the new-author information (if any)
+    $new_author = null;
+    $new_author_phid = null;
+    switch ($project->getDetail('commitWithAuthor')) {
+      case ReleephProject::COMMIT_AUTHOR_NONE:
+        break;
+
+      case ReleephProject::COMMIT_AUTHOR_FROM_DIFF:
+        if ($diff_rev) {
+          $new_author_phid = $diff_rev->getAuthorPHID();
+        } else {
+          $pr_commit = $releeph_request->loadPhabricatorRepositoryCommit();
+          if ($pr_commit) {
+            $new_author_phid = $pr_commit->getAuthorPHID();
+          }
+        }
+        break;
+
+      case ReleephProject::COMMIT_AUTHOR_REQUESTOR:
+        $new_author_phid = $releeph_request->getRequestUserPHID();
+        break;
+    }
+
+    return array(
+      'requestID'         => $releeph_request->getID(),
+      'requestPHID'       => $releeph_request->getPHID(),
+      'requestName'       => $handles[$releeph_request->getPHID()]->getName(),
+      'requestorPHID'     => $releeph_request->getRequestUserPHID(),
+      'action'            => $action,
+      'diffRevID'         => $diff_rev_id,
+      'diffName'          => $diff_name,
+      'commitIdentifier'  => $commit_id,
+      'commitPHID'        => $commit_phid,
+      'commitName'        => $handles[$commit_phid]->getName(),
+      'needsRevert'       => mpull($needs_revert, 'getID'),
+      'needsPick'         => mpull($needs_pick, 'getID'),
+      'newAuthorPHID'     => $new_author_phid,
+    );
+  }
+
+  /**
+   * Sort an array of ReleephRequests, that have been picked into a branch, in
+   * the order in which they were picked to the branch.
+   */
+  private function sortReverts(array $releeph_requests) {
+    if (!$releeph_requests) {
+      return array();
+    }
+
+    // ReleephRequests, keyed by <branch-commit-id>
+    $releeph_requests = mpull($releeph_requests, null, 'getCommitIdentifier');
+
+    $commits = id(new PhabricatorRepositoryCommit())
+      ->loadAllWhere(
+        'commitIdentifier IN (%Ls)',
+        mpull($releeph_requests, 'getCommitIdentifier'));
+
+    // A map of <branch-commit-id> => <branch-commit-ordinal>
+    $surrogate = mpull($commits, 'getID', 'getCommitIdentifier');
+
+    $unparsed = array();
+    $result = array();
+
+    foreach ($releeph_requests as $commit_id => $releeph_request) {
+      $ordinal = idx($surrogate, $commit_id);
+      if ($ordinal) {
+        $result[$ordinal] = $releeph_request;
+      } else {
+        $unparsed[] = $releeph_request;
+      }
+    }
+
+    // Sort $result in ascending order
+    ksort($result);
+
+    // Unparsed commits we'll just have to guess, based on time
+    $unparsed = msort($unparsed, 'getDateModified');
+
+    return array_merge($result, $unparsed);
+  }
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php
new file mode 100644
index 000000000..0b8bd3a1a
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_record_Method.php
@@ -0,0 +1,42 @@
+<?php
+
+final class ConduitAPI_releephwork_record_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodStatus() {
+    return self::METHOD_STATUS_UNSTABLE;
+  }
+
+  public function getMethodDescription() {
+    return "Wrapper to ReleephRequestEditor->recordSuccessfulCommit().";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'requestPHID'       => 'required string',
+      'action'            => 'required enum<"pick", "revert">',
+      'commitIdentifier'  => 'required string',
+    );
+  }
+
+  public function defineReturnType() {
+    return 'void';
+  }
+
+  public function defineErrorTypes() {
+    return array();
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $action = $request->getValue('action');
+    $new_commit_id = $request->getValue('commitIdentifier');
+
+    $releeph_request = id(new ReleephRequest())
+      ->loadOneWhere('phid = %s', $request->getValue('requestPHID'));
+
+    id(new ReleephRequestEditor($releeph_request))
+      ->setActor($request->getUser())
+      ->recordSuccessfulCommit($action, $new_commit_id);
+  }
+
+}
diff --git a/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php
new file mode 100644
index 000000000..93fbcee06
--- /dev/null
+++ b/src/applications/releeph/conduit/work/ConduitAPI_releephwork_recordpickstatus_Method.php
@@ -0,0 +1,63 @@
+<?php
+
+final class ConduitAPI_releephwork_recordpickstatus_Method
+  extends ConduitAPI_releeph_Method {
+
+  public function getMethodStatus() {
+    return self::METHOD_STATUS_UNSTABLE;
+  }
+
+  public function getMethodDescription() {
+    return "Wrapper to ReleephRequestEditor->changePickStatus().";
+  }
+
+  public function defineParamTypes() {
+    return array(
+      'requestPHID'       => 'required string',
+      'action'            => 'required enum<"pick", "revert">',
+      'ok'                => 'required bool',
+      'dryRun'            => 'optional bool',
+      'details'           => 'optional dict<string, wild>',
+    );
+  }
+
+  public function defineReturnType() {
+    return '';
+  }
+
+  public function defineErrorTypes() {
+    return array();
+  }
+
+  protected function execute(ConduitAPIRequest $request) {
+    $action = $request->getValue('action');
+    $ok = $request->getValue('ok');
+    $dry_run = $request->getValue('dryRun');
+    $details = $request->getValue('details', array());
+
+    switch ($request->getValue('action')) {
+      case 'pick':
+        $pick_status = $ok
+          ? ReleephRequest::PICK_OK
+          : ReleephRequest::PICK_FAILED;
+        break;
+
+      case 'revert':
+        $pick_status = $ok
+          ? ReleephRequest::REVERT_OK
+          : ReleephRequest::REVERT_FAILED;
+        break;
+
+      default:
+        throw new Exception("Unknown action {$action}!");
+    }
+
+    $releeph_request = id(new ReleephRequest())
+      ->loadOneWhere('phid = %s', $request->getValue('requestPHID'));
+
+    id(new ReleephRequestEditor($releeph_request))
+      ->setActor($request->getUser())
+      ->changePickStatus($pick_status, $dry_run, $details);
+  }
+
+}
diff --git a/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php b/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php
new file mode 100644
index 000000000..75cc32247
--- /dev/null
+++ b/src/applications/releeph/config/PhabricatorApplicationReleephConfigOptions.php
@@ -0,0 +1,64 @@
+<?php
+
+final class PhabricatorApplicationReleephConfigOptions
+  extends PhabricatorApplicationConfigOptions {
+
+  public function getName() {
+    return pht("Releeph");
+  }
+
+  public function getDescription() {
+    return pht("Options for configuring Releeph, the release branch tool.");
+  }
+
+  public function getOptions() {
+    return array(
+      $this->newOption('releeph.installed', 'bool', false)
+        ->setSummary(pht('Enable the Releeph application.'))
+        ->setDescription(
+          pht(
+            "Releeph, a tool for managing release branches, will eventually ".
+            "fit in to the Phabricator suite as a general purpose tool. ".
+            "However Releeph is currently unstable in multiple ways that may ".
+            "not migrate properly for you: the code is still in alpha stage ".
+            "of design, the storage format is likely to change in unexpected ".
+            "ways, and the workflows presented are very specific to a core ".
+            "set of alpha testers at Facebook.  For the time being you are ".
+            "strongly discouraged from relying on Releeph being at all ".
+            "stable.")),
+      $this->newOption(
+        'releeph.field-selector',
+        'class',
+        'ReleephDefaultFieldSelector')
+        ->setBaseClass('ReleephFieldSelector')
+        ->setSummary(pht('Field selector class'))
+        ->setDescription(
+          pht(
+            "Control which fields are available when making a new Releeph ".
+            "request, and which are then shown in the Releeph UI.")),
+      $this->newOption(
+        'releeph.user-view',
+        'class',
+        'ReleephDefaultUserView')
+        ->setBaseClass('ReleephUserView')
+        ->setSummary(pht('Extra markup when rendering usernames'))
+        ->setDescription(
+          pht(
+            "A wrapper to render Phabricator users in Releeph, with custom ".
+            "markup.  For example, Facebook extends this to render additional ".
+            "information about requestors, to each Releeph project's ".
+            "pushers.")),
+      $this->newOption(
+        'releeph.default-branch-template',
+        'string',
+        'releases/%P/%p-%Y%m%d-%v')
+        ->setDescription(
+          pht(
+            "The default branch template for new branches in unconfigured ".
+            "Releeph projects.  This is also configurable on a per-project ".
+            "basis.")),
+    );
+  }
+
+
+}
diff --git a/src/applications/releeph/controller/ReleephController.php b/src/applications/releeph/controller/ReleephController.php
new file mode 100644
index 000000000..22a821453
--- /dev/null
+++ b/src/applications/releeph/controller/ReleephController.php
@@ -0,0 +1,122 @@
+<?php
+
+abstract class ReleephController extends PhabricatorController {
+
+  private $releephProject;
+  private $releephBranch;
+  private $releephRequest;
+
+  /**
+   * ReleephController will take care of loading any Releeph* objects
+   * referenced in the URL.
+   */
+  public function willProcessRequest(array $data) {
+    // Project
+    $project = null;
+    $project_id = idx($data, 'projectID');
+    $project_name = idx($data, 'projectName');
+    if ($project_id) {
+      $project = id(new ReleephProject())->load($project_id);
+      if (!$project) {
+        throw new Exception(
+          "ReleephProject with id '{$project_id}' not found!");
+      }
+    } elseif ($project_name) {
+      $project = id(new ReleephProject())
+        ->loadOneWhere('name = %s', $project_name);
+      if (!$project) {
+        throw new Exception(
+          "ReleephProject with name '{$project_name}' not found!");
+      }
+    }
+
+    // Branch
+    $branch = null;
+    $branch_id = idx($data, 'branchID');
+    $branch_name = idx($data, 'branchName');
+    if ($branch_id) {
+      $branch = id(new ReleephBranch())->load($branch_id);
+      if (!$branch) {
+        throw new Exception("Branch with id '{$branch_id}' not found!");
+      }
+    } elseif ($branch_name) {
+      if (!$project) {
+        throw new Exception(
+          "You cannot refer to a branch by name without also referring ".
+          "to a ReleephProject (branch names are only unique in projects).");
+      }
+      $branch = id(new ReleephBranch())->loadOneWhere(
+        'basename = %s AND releephProjectID = %d',
+        $branch_name,
+        $project->getID());
+      if (!$branch) {
+        throw new Exception(
+          "ReleephBranch with basename '{$branch_name}' not found ".
+          "in project '{$project->getName()}'!");
+      }
+    }
+
+    // Request
+    $request = null;
+    $request_id = idx($data, 'requestID');
+    if ($request_id) {
+      $request = id(new ReleephRequest())->load($request_id);
+      if (!$request) {
+        throw new Exception(
+          "ReleephRequest with id '{$request_id}' not found!");
+      }
+    }
+
+    // Fill in the gaps
+    if ($request && !$branch) {
+      $branch = $request->loadReleephBranch();
+    }
+
+    if ($branch && !$project) {
+      $project = $branch->loadReleephProject();
+    }
+
+    // Set!
+    $this->releephProject = $project;
+    $this->releephBranch = $branch;
+    $this->releephRequest = $request;
+  }
+
+  protected function getReleephProject() {
+    if (!$this->releephProject) {
+      throw new Exception(
+        'This controller did not load a ReleephProject from the URL $data.');
+    }
+    return $this->releephProject;
+  }
+
+  protected function getReleephBranch() {
+    if (!$this->releephBranch) {
+      throw new Exception(
+        'This controller did not load a ReleephBranch from the URL $data.');
+    }
+    return $this->releephBranch;
+  }
+
+  protected function getReleephRequest() {
+    if (!$this->releephRequest) {
+      throw new Exception(
+        'This controller did not load a ReleephRequest from the URL $data.');
+    }
+    return $this->releephRequest;
+  }
+
+  public function buildStandardPageResponse($view, array $data) {
+    $page = $this->buildStandardPageView();
+
+    $page->setApplicationName('Releeph');
+    $page->setBaseURI('/releeph/');
+    $page->setTitle(idx($data, 'title'));
+    $page->setGlyph("\xD3\x82");
+    $page->appendChild($view);
+
+    $response = new AphrontWebpageResponse();
+    return $response->setContent($page->render());
+  }
+
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchAccessController.php b/src/applications/releeph/controller/branch/ReleephBranchAccessController.php
new file mode 100644
index 000000000..bcaf86e96
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchAccessController.php
@@ -0,0 +1,61 @@
+<?php
+
+final class ReleephBranchAccessController extends ReleephController {
+
+  private $action;
+
+  public function willProcessRequest(array $data) {
+    $this->action = $data['action'];
+    parent::willProcessRequest($data);
+  }
+
+  public function processRequest() {
+    $rph_branch = $this->getReleephBranch();
+    $request = $this->getRequest();
+
+    $active_uri = '/releeph/project/'.$rph_branch->getReleephProjectID().'/';
+    $inactive_uri = $active_uri.'inactive/';
+
+    switch ($this->action) {
+      case 'close':
+        $is_active = false;
+        $origin_uri = $active_uri;
+        break;
+
+      case 're-open':
+        $is_active = true;
+        $origin_uri = $inactive_uri;
+        break;
+
+      default:
+        throw new Exception("Unknown action '{$this->action}'!");
+        break;
+    }
+
+    if ($request->isDialogFormPost()) {
+      id(new ReleephBranchEditor())
+        ->setActor($request->getUser())
+        ->setReleephBranch($rph_branch)
+        ->changeBranchAccess($is_active ? 1 : 0);
+      return id(new AphrontRedirectResponse())
+        ->setURI($origin_uri);
+    }
+
+    $button_text = ucfirst($this->action).' Branch';
+    $message = hsprintf(
+      '<p>Really %s the branch <i>%s</i>?</p>',
+      $this->action,
+      $rph_branch->getBasename());
+
+
+    $dialog = new AphrontDialogView();
+    $dialog
+      ->setUser($request->getUser())
+      ->setTitle('Confirm')
+      ->appendChild($message)
+      ->addSubmitButton($button_text)
+      ->addCancelButton($origin_uri);
+
+    return id(new AphrontDialogResponse())->setDialog($dialog);
+  }
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchCreateController.php b/src/applications/releeph/controller/branch/ReleephBranchCreateController.php
new file mode 100644
index 000000000..6031c0388
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchCreateController.php
@@ -0,0 +1,105 @@
+<?php
+
+final class ReleephBranchCreateController extends ReleephController {
+
+  public function processRequest() {
+    $releeph_project = $this->getReleephProject();
+
+    $request = $this->getRequest();
+
+    $cut_point = $request->getStr('cutPoint');
+    $symbolic_name = $request->getStr('symbolicName');
+
+    if (!$cut_point) {
+      $repository = $releeph_project->loadPhabricatorRepository();
+      switch ($repository->getVersionControlSystem()) {
+        case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
+          break;
+
+        case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
+          $cut_point = $releeph_project->getTrunkBranch();
+          break;
+      }
+    }
+
+    $e_cut = true;
+    $errors = array();
+
+    $branch_date_control = id(new AphrontFormDateControl())
+      ->setUser($request->getUser())
+      ->setName('templateDate')
+      ->setLabel('Date')
+      ->setCaption('The date used for filling out the branch template.')
+      ->setInitialTime(AphrontFormDateControl::TIME_START_OF_DAY);
+    $branch_date = $branch_date_control->readValueFromRequest($request);
+
+    if ($request->isFormPost()) {
+      $cut_commit = null;
+      if (!$cut_point) {
+        $e_cut = 'Required';
+        $errors[] = 'You must give a branch cut point';
+      } else {
+        try {
+          $finder = id(new ReleephCommitFinder())
+            ->setReleephProject($releeph_project);
+          $cut_commit = $finder->fromPartial($cut_point);
+        } catch (Exception $e) {
+          $e_cut = 'Invalid';
+          $errors[] = $e->getMessage();
+        }
+      }
+
+      if (!$errors) {
+        $branch = id(new ReleephBranchEditor())
+          ->setReleephProject($releeph_project)
+          ->setActor($request->getUser())
+          ->newBranchFromCommit(
+            $cut_commit,
+            $branch_date,
+            $symbolic_name);
+
+        return id(new AphrontRedirectResponse())
+          ->setURI($branch->getURI());
+      }
+    }
+
+    $error_view = array();
+    if ($errors) {
+      $error_view = new AphrontErrorView();
+      $error_view->setErrors($errors);
+      $error_view->setTitle('Form Errors');
+    }
+
+    $form = id(new AphrontFormView())
+      ->setUser($request->getUser())
+      ->appendChild(
+        id(new AphrontFormTextControl())
+          ->setLabel('Symbolic name')
+          ->setName('symbolicName')
+          ->setValue($symbolic_name)
+          ->setCaption('Mutable alternate name, for easy reference, '.
+              '(e.g. "LATEST")'))
+      ->appendChild(
+        id(new AphrontFormTextControl())
+          ->setLabel('Cut point')
+          ->setName('cutPoint')
+          ->setValue($cut_point)
+          ->setError($e_cut)
+          ->setCaption(
+              'A commit ID for your repo type, or a Diffusion ID like "rE123"'))
+      ->appendChild($branch_date_control)
+      ->appendChild(
+        id(new AphrontFormSubmitControl())
+          ->setValue('Cut Branch')
+          ->addCancelButton($releeph_project->getURI()));
+
+    $panel = id(new AphrontPanelView())
+      ->appendChild($form)
+      ->setHeader('Cut Branch')
+      ->setWidth(AphrontPanelView::WIDTH_FORM);
+
+    return $this->buildStandardPageResponse(
+      array($error_view, $panel),
+      array('title' => 'Cut new branch'));
+  }
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchEditController.php b/src/applications/releeph/controller/branch/ReleephBranchEditController.php
new file mode 100644
index 000000000..5501ee3e0
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchEditController.php
@@ -0,0 +1,136 @@
+<?php
+
+final class ReleephBranchEditController extends ReleephController {
+
+  public function processRequest() {
+    $request = $this->getRequest();
+    $releeph_branch = $this->getReleephBranch();
+    $branch_name = $request->getStr(
+      'branchName',
+      $releeph_branch->getName());
+    $symbolic_name = $request->getStr(
+      'symbolicName',
+      $releeph_branch->getSymbolicName());
+
+    $e_existing_with_same_branch_name = false;
+    $errors = array();
+
+    if ($request->isFormPost()) {
+      $existing_with_same_branch_name =
+        id(new ReleephBranch())
+          ->loadOneWhere(
+              'id != %d AND releephProjectID = %d AND name = %s',
+              $releeph_branch->getID(),
+              $releeph_branch->getReleephProjectID(),
+              $branch_name);
+
+      if ($existing_with_same_branch_name) {
+        $errors[] = sprintf(
+          "The branch name %s is currently taken. Please use another name. ",
+          $branch_name);
+        $e_existing_with_same_branch_name = 'Error';
+      }
+
+      if (!$errors) {
+        $existing_with_same_symbolic_name =
+          id(new ReleephBranch())
+            ->loadOneWhere(
+                'id != %d AND releephProjectID = %d AND symbolicName = %s',
+                $releeph_branch->getID(),
+                $releeph_branch->getReleephProjectID(),
+                $symbolic_name);
+
+        $releeph_branch->openTransaction();
+        $releeph_branch
+          ->setName($branch_name)
+          ->setBasename(last(explode('/', $branch_name)))
+          ->setSymbolicName($symbolic_name);
+
+        if ($existing_with_same_symbolic_name) {
+          $existing_with_same_symbolic_name
+            ->setSymbolicName(null)
+            ->save();
+        }
+
+        $releeph_branch->save();
+        $releeph_branch->saveTransaction();
+
+        return id(new AphrontRedirectResponse())
+          ->setURI('/releeph/project/'.$releeph_branch->getReleephProjectID());
+      }
+    }
+
+    $phids = array();
+
+    $phids[] = $creator_phid = $releeph_branch->getCreatedByUserPHID();
+    $phids[] = $cut_commit_phid = $releeph_branch->getCutPointCommitPHID();
+
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      ->setViewer($request->getUser())
+      ->loadHandles();
+
+    $form = id(new AphrontFormView())
+      ->setUser($request->getUser())
+      ->appendChild(
+        id(new AphrontFormStaticControl())
+        ->setLabel('Branch name')
+        ->setValue($branch_name))
+      ->appendChild(
+        id(new AphrontFormMarkupControl())
+          ->setLabel('Cut point')
+          ->setValue($handles[$cut_commit_phid]->renderLink()))
+      ->appendChild(
+        id(new AphrontFormMarkupControl())
+          ->setLabel('Created by')
+          ->setValue($handles[$creator_phid]->renderLink()))
+      ->appendChild(
+        id(new AphrontFormTextControl)
+          ->setLabel('Symbolic Name')
+          ->setName('symbolicName')
+          ->setValue($symbolic_name)
+          ->setCaption('Mutable alternate name, for easy reference, '.
+              '(e.g. "LATEST")'))
+      ->appendChild(hsprintf(
+        '<br>' .
+        'In dire situations where the branch name is wrong, ' .
+        'you can edit it in the database by changing the field below. ' .
+        'If you do this, it is very important that you change your ' .
+        'branch\'s name in the VCS to reflect the new name in Releeph, ' .
+        'otherwise a catastrophe of previously unheard-of magnitude ' .
+        'will befall your project.'))
+      ->appendChild(
+        id(new AphrontFormTextControl)
+          ->setLabel('New branch name')
+          ->setName('branchName')
+          ->setValue($branch_name)
+          ->setError($e_existing_with_same_branch_name))
+      ->appendChild(
+        id(new AphrontFormSubmitControl())
+          ->addCancelButton($releeph_branch->getURI())
+          ->setValue('Save'));
+
+    $error_view = null;
+    if ($errors) {
+      $error_view = id(new AphrontErrorView())
+        ->setSeverity(AphrontErrorView::SEVERITY_ERROR)
+        ->setErrors($errors)
+        ->setTitle('Errors');
+    }
+
+    $title = hsprintf(
+      'Edit branch %s',
+      $releeph_branch->getDisplayNameWithDetail());
+
+    $panel = id(new AphrontPanelView())
+      ->setHeader($title)
+      ->appendChild($form)
+      ->setWidth(AphrontPanelView::WIDTH_FORM);
+
+    return $this->buildStandardPageResponse(
+      array(
+        $error_view,
+        $panel,
+      ),
+      array('title' => $title));
+  }
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php b/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php
new file mode 100644
index 000000000..5606542bf
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchNamePreviewController.php
@@ -0,0 +1,46 @@
+<?php
+
+final class ReleephBranchNamePreviewController
+  extends PhabricatorController {
+
+  public function processRequest() {
+    $request = $this->getRequest();
+
+    $is_symbolic = $request->getBool('isSymbolic');
+    $template = $request->getStr('template');
+
+    if (!$is_symbolic && !$template) {
+      $template = ReleephBranchTemplate::getDefaultTemplate();
+    }
+
+    $arc_project_id = $request->getInt('arcProjectID');
+    $fake_commit_handle =
+      ReleephBranchTemplate::getFakeCommitHandleFor($arc_project_id);
+
+    list($name, $errors) = id(new ReleephBranchTemplate())
+      ->setCommitHandle($fake_commit_handle)
+      ->setReleephProjectName($request->getStr('projectName'))
+      ->setSymbolic($is_symbolic)
+      ->interpolate($template);
+
+    $markup = '';
+
+    if ($name) {
+      $markup = phutil_tag(
+        'div',
+        array('class' => 'name'),
+        $name);
+    }
+
+    if ($errors) {
+      $markup .= phutil_tag(
+        'div',
+        array('class' => 'error'),
+        head($errors));
+    }
+
+    return id(new AphrontAjaxResponse())
+      ->setContent(array('markup' => $markup));
+  }
+
+}
diff --git a/src/applications/releeph/controller/branch/ReleephBranchViewController.php b/src/applications/releeph/controller/branch/ReleephBranchViewController.php
new file mode 100644
index 000000000..f01f14987
--- /dev/null
+++ b/src/applications/releeph/controller/branch/ReleephBranchViewController.php
@@ -0,0 +1,94 @@
+<?php
+
+final class ReleephBranchViewController extends ReleephController {
+
+  public function processRequest() {
+    $request = $this->getRequest();
+
+    $releeph_branch = $this->getReleephBranch();
+    $releeph_project = $this->getReleephProject();
+    $all_releeph_requests = $releeph_branch->loadReleephRequests(
+      $request->getUser());
+
+    $selector = $releeph_project->getReleephFieldSelector();
+    $fields = $selector->arrangeFieldsForSelectForm(
+      $selector->getFieldSpecifications());
+
+    $form = id(new AphrontFormView())
+      ->setMethod('GET')
+      ->setUser($request->getUser());
+
+    $filtered_releeph_requests = $all_releeph_requests;
+    foreach ($fields as $field) {
+      $all_releeph_requests_without_this_field = $all_releeph_requests;
+      foreach ($fields as $other_field) {
+        if ($other_field != $field) {
+          $other_field->selectReleephRequestsHook(
+            $request,
+            $all_releeph_requests_without_this_field);
+
+        }
+      }
+
+      $field->appendSelectControlsHook(
+        $form,
+        $request,
+        $all_releeph_requests,
+        $all_releeph_requests_without_this_field);
+
+      $field->selectReleephRequestsHook(
+        $request,
+        $filtered_releeph_requests);
+    }
+
+    $form->appendChild(
+      id(new AphrontFormSubmitControl())
+        ->setValue('Filter'));
+
+    $list = id(new ReleephRequestHeaderListView())
+      ->setOriginType('branch')
+      ->setUser($request->getUser())
+      ->setAphrontRequest($this->getRequest())
+      ->setReleephProject($releeph_project)
+      ->setReleephBranch($releeph_branch)
+      ->setReleephRequests($filtered_releeph_requests);
+
+    $filter = id(new AphrontListFilterView())
+      ->appendChild($form);
+
+    $crumbs = $this->buildApplicationCrumbs()
+      ->addCrumb(
+        id(new PhabricatorCrumbView())
+          ->setName($releeph_project->getName())
+          ->setHref($releeph_project->getURI()))
+      ->addCrumb(
+        id(new PhabricatorCrumbView())
+          ->setName($releeph_branch->getDisplayNameWithDetail())
+          ->setHref($releeph_branch->getURI()));
+
+    // Don't show the request button for inactive (closed) branches
+    if ($releeph_branch->isActive()) {
+      $create_uri = $releeph_branch->getURI('request/');
+      $crumbs->addAction(
+        id(new PhabricatorMenuItemView())
+          ->setHref($create_uri)
+          ->setName('Request Pick')
+          ->setIcon('create'));
+    }
+
+    return $this->buildStandardPageResponse(
+      array(
+        $crumbs,
+        $filter,
+        $list
+      ),
+      array(
+        'title' =>
+          $releeph_project->getName().
+          ' - '.
+          $releeph_branch->getDisplayName().
+          ' requests'
+      ));
+  }
+
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectActionController.php b/src/applications/releeph/controller/project/ReleephProjectActionController.php
new file mode 100644
index 000000000..4e91107ea
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectActionController.php
@@ -0,0 +1,63 @@
+<?php
+
+final class ReleephProjectActionController extends ReleephController {
+
+  private $action;
+
+  public function willProcessRequest(array $data) {
+    parent::willProcessRequest($data);
+    $this->action = $data['action'];
+  }
+
+  public function processRequest() {
+    $request = $this->getRequest();
+
+    $action = $this->action;
+    $rph_project = $this->getReleephProject();
+
+    switch ($action) {
+      case 'deactivate':
+        if ($request->isDialogFormPost()) {
+          $rph_project->deactivate($request->getUser())->save();
+          return id(new AphrontRedirectResponse())->setURI('/releeph');
+        }
+
+        $dialog = id(new AphrontDialogView())
+          ->setUser($request->getUser())
+          ->setTitle('Really deactivate Releeph Project?')
+          ->appendChild(hsprintf(
+            '<p>Really deactivate the Releeph project <i>%s</i>?',
+            $rph_project->getName()))
+          ->appendChild(hsprintf(
+            '<p style="margin-top:1em">It will still exist, but '.
+            'will be hidden from the list of active projects.</p>'))
+          ->addSubmitButton('Deactivate Releeph Project')
+          ->addCancelButton($request->getRequestURI());
+
+        return id(new AphrontDialogResponse())->setDialog($dialog);
+
+      case 'activate':
+        $rph_project->setIsActive(1)->save();
+        return id(new AphrontRedirectResponse())->setURI('/releeph');
+
+      case 'delete':
+        if ($request->isDialogFormPost()) {
+          $rph_project->delete();
+          return id(new AphrontRedirectResponse())
+            ->setURI('/releeph/project/inactive');
+        }
+
+        $dialog = id(new AphrontDialogView())
+          ->setUser($request->getUser())
+          ->setTitle('Really delete Releeph Project?')
+          ->appendChild(hsprintf(
+            '<p>Really delete the "%s" Releeph project? '.
+              'This cannot be undone!</p>',
+            $rph_project->getName()))
+          ->addSubmitButton('Delete Releeph Project')
+          ->addCancelButton($request->getRequestURI());
+        return id(new AphrontDialogResponse())->setDialog($dialog);
+
+    }
+  }
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectCreateController.php b/src/applications/releeph/controller/project/ReleephProjectCreateController.php
new file mode 100644
index 000000000..2dbfb72c5
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectCreateController.php
@@ -0,0 +1,149 @@
+<?php
+
+final class ReleephProjectCreateController extends ReleephController {
+
+  public function processRequest() {
+    $request = $this->getRequest();
+    $name = trim($request->getStr('name'));
+    $trunk_branch = trim($request->getStr('trunkBranch'));
+    $arc_pr_id = $request->getInt('arcPrID');
+
+
+    // Only allow arc projects with repositories.  Sort and re-key by ID.
+    $arc_projects = id(new PhabricatorRepositoryArcanistProject())->loadAll();
+    $arc_projects = mpull(
+      msort(
+        mfilter($arc_projects, 'getRepositoryID'),
+        'getName'),
+      null,
+      'getID');
+
+    $e_name = true;
+    $e_trunk_branch = true;
+    $errors = array();
+
+    if ($request->isFormPost()) {
+      if (!$name) {
+        $e_name = 'Required';
+        $errors[] =
+          'Your releeph project should have a simple descriptive name.';
+      }
+
+      if (!$trunk_branch) {
+        $e_trunk_branch = 'Required';
+        $errors[] =
+          'You must specify which branch you will be picking from.';
+      }
+
+      $all_names = mpull(id(new ReleephProject())->loadAll(), 'getName');
+
+      if (in_array($name, $all_names)) {
+        $errors[] = "Releeph project name {$name} is already taken";
+      }
+
+      $arc_project = $arc_projects[$arc_pr_id];
+      $pr_repository = $arc_project->loadRepository();
+
+      if (!$errors) {
+        $releeph_project = id(new ReleephProject())
+          ->setName($name)
+          ->setTrunkBranch($trunk_branch)
+          ->setRepositoryID($pr_repository->getID())
+          ->setRepositoryPHID($pr_repository->getPHID())
+          ->setArcanistProjectID($arc_project->getID())
+          ->setCreatedByUserPHID($request->getUser()->getPHID())
+          ->setIsActive(1)
+          ->save();
+
+        return id(new AphrontRedirectResponse())->setURI('/releeph/');
+      }
+    }
+
+    $error_view = null;
+    if ($errors) {
+      $error_view = new AphrontErrorView();
+      $error_view->setErrors($errors);
+      $error_view->setTitle('Form Errors');
+    }
+
+    // Make our own optgroup select control
+    $arc_project_choices = array();
+    $pr_repositories = mpull(
+      msort(
+        array_filter(
+          // Some arc-projects don't have repositories
+          mpull($arc_projects, 'loadRepository')),
+        'getName'),
+      null,
+      'getID');
+
+    foreach ($pr_repositories as $pr_repo_id => $pr_repository) {
+      $options = array();
+      foreach ($arc_projects as $arc_project) {
+        if ($arc_project->getRepositoryID() == $pr_repo_id) {
+          $options[$arc_project->getID()] = $arc_project->getName();
+        }
+      }
+      $arc_project_choices[$pr_repository->getName()] = $options;
+    }
+
+    $project_name_input = id(new AphrontFormTextControl())
+      ->setLabel('Name')
+      ->setDisableAutocomplete(true)
+      ->setName('name')
+      ->setValue($name)
+      ->setError($e_name)
+      ->setCaption('A name like "Thrift" but not "Thrift releases".');
+
+    $arc_project_input = id(new AphrontFormSelectControl())
+      ->setLabel('Arc Project')
+      ->setName('arcPrID')
+      ->setValue($arc_pr_id)
+      ->setCaption(hsprintf(
+        "If your Arc project isn't listed, associate it with a repository %s",
+        phutil_tag(
+          'a',
+          array(
+            'href' => '/repository/',
+            'target' => '_blank',
+          ),
+          'here')))
+      ->setOptions($arc_project_choices);
+
+    $branch_name_preview = id(new ReleephBranchPreviewView())
+      ->setLabel('Example Branch')
+      ->addControl('projectName', $project_name_input)
+      ->addControl('arcProjectID', $arc_project_input)
+      ->addStatic('template', '')
+      ->addStatic('isSymbolic', false);
+
+    $form = id(new AphrontFormView())
+      ->setUser($request->getUser())
+      ->appendChild($project_name_input)
+      ->appendChild($arc_project_input)
+      ->appendChild(
+        id(new AphrontFormTextControl())
+          ->setLabel('Trunk')
+          ->setName('trunkBranch')
+          ->setValue($trunk_branch)
+          ->setError($e_trunk_branch)
+          ->setCaption('The development branch, '.
+              'from which requests will be picked.'))
+      ->appendChild($branch_name_preview)
+      ->appendChild(
+        id(new AphrontFormSubmitControl())
+          ->addCancelButton('/releeph/project/')
+          ->setValue('Create'));
+
+    $panel = id(new AphrontPanelView())
+      ->setHeader('Create Releeph Project')
+      ->appendChild($form)
+      ->setWidth(AphrontPanelView::WIDTH_FORM);
+
+    return $this->buildStandardPageResponse(
+      array($error_view, $panel),
+      array(
+        'title' => 'Create new Releeph Project'
+      ));
+  }
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectEditController.php b/src/applications/releeph/controller/project/ReleephProjectEditController.php
new file mode 100644
index 000000000..1dcb128e6
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectEditController.php
@@ -0,0 +1,388 @@
+<?php
+
+final class ReleephProjectEditController extends ReleephController {
+
+  public function processRequest() {
+    $request = $this->getRequest();
+
+    $e_name = true;
+    $e_trunk_branch = true;
+    $e_branch_template = false;
+    $errors = array();
+
+    $project_name = $request->getStr('name',
+      $this->getReleephProject()->getName());
+
+    $phabricator_project_id = $request->getInt('projectID',
+      $this->getReleephProject()->getProjectID());
+    $trunk_branch = $request->getStr('trunkBranch',
+      $this->getReleephProject()->getTrunkBranch());
+    $branch_template = $request->getStr('branchTemplate');
+    if ($branch_template === null) {
+      $branch_template =
+        $this->getReleephProject()->getDetail('branchTemplate');
+    }
+    $pick_failure_instructions = $request->getStr('pickFailureInstructions',
+      $this->getReleephProject()->getDetail('pick_failure_instructions'));
+    $commit_author = $request->getStr('commitWithAuthor',
+      $this->getReleephProject()->getDetail('commitWithAuthor'));
+    $test_paths = $request->getStr('testPaths');
+    if ($test_paths !== null) {
+      $test_paths = array_filter(explode("\n", $test_paths));
+    } else {
+      $test_paths = $this->getReleephProject()->getDetail('testPaths', array());
+    }
+
+    $field_selector = $request->getStr('fieldSelector',
+      get_class($this->getReleephProject()->getReleephFieldSelector()));
+
+    $release_counter = $request->getInt(
+      'releaseCounter',
+      $this->getReleephProject()->getCurrentReleaseNumber());
+
+    $arc_project_id = $this->getReleephProject()->getArcanistProjectID();
+
+    if ($request->isFormPost()) {
+      $pusher_phids = $request->getArr('pushers');
+
+      if (!$project_name) {
+        $e_name = 'Required';
+        $errors[] =
+          'Your releeph project should have a simple descriptive name';
+      }
+
+      if (!$trunk_branch) {
+        $e_trunk_branch = 'Required';
+        $errors[] =
+          'You must specify which branch you will be picking from.';
+      }
+
+      if ($release_counter && !is_int($release_counter)) {
+        $errors[] = "Release counter must be a positive integer!";
+      }
+
+      $other_releeph_projects = id(new ReleephProject())
+        ->loadAllWhere('id <> %d', $this->getReleephProject()->getID());
+      $other_releeph_project_names = mpull($other_releeph_projects,
+        'getName', 'getID');
+
+      if (in_array($project_name, $other_releeph_project_names)) {
+        $errors[] = "Releeph project name {$project_name} is already taken";
+      }
+
+      foreach ($test_paths as $test_path) {
+        $result = @preg_match($test_path, '');
+        $is_a_valid_regexp = $result !== false;
+        if (!$is_a_valid_regexp) {
+          $errors[] = 'Please provide a valid regular expression: '.
+            "{$test_path} is not valid";
+        }
+      }
+
+      $project = $this->getReleephProject()
+        ->setProjectID($phabricator_project_id)
+        ->setTrunkBranch($trunk_branch)
+        ->setDetail('pushers', $pusher_phids)
+        ->setDetail('pick_failure_instructions', $pick_failure_instructions)
+        ->setDetail('field_selector', $field_selector)
+        ->setDetail('branchTemplate', $branch_template)
+        ->setDetail('commitWithAuthor', $commit_author)
+        ->setDetail('testPaths', $test_paths);
+
+      if ($release_counter) {
+        $project->setDetail('releaseCounter', $release_counter);
+      }
+
+      $fake_commit_handle =
+        ReleephBranchTemplate::getFakeCommitHandleFor($arc_project_id);
+
+      if ($branch_template) {
+        list($branch_name, $template_errors) = id(new ReleephBranchTemplate())
+          ->setCommitHandle($fake_commit_handle)
+          ->setReleephProjectName($project_name)
+          ->interpolate($branch_template);
+
+        if ($template_errors) {
+          $e_branch_template = 'Invalid!';
+          foreach ($template_errors as $template_error) {
+            $errors[] = "Template error: {$template_error}";
+          }
+        }
+      }
+
+      if (!$errors) {
+        $project->save();
+
+        return id(new AphrontRedirectResponse())
+          ->setURI('/releeph/project/');
+      }
+    }
+
+    $error_view = null;
+    if ($errors) {
+      $error_view = new AphrontErrorView();
+      $error_view->setErrors($errors);
+      $error_view->setTitle('Form Errors');
+    }
+
+    $projects = mpull(
+      id(new PhabricatorProject())->loadAll(),
+      'getName',
+      'getID');
+
+    $projects[0] = '-'; // no project associated, that's ok
+
+    $pusher_phids = $request->getArr(
+      'pushers',
+      $this->getReleephProject()->getDetail('pushers', array()));
+
+    $handles = id(new PhabricatorObjectHandleData($pusher_phids))
+      ->setViewer($request->getUser())
+      ->loadHandles();
+
+    $pusher_tokens = array();
+    foreach ($pusher_phids as $phid) {
+      $pusher_tokens[$phid] = $handles[$phid]->getFullName();
+    }
+
+    $basic_inset = id(new AphrontFormInsetView())
+      ->setTitle('Basics')
+      ->appendChild(
+        id(new AphrontFormTextControl())
+          ->setLabel('Name')
+          ->setName('name')
+          ->setValue($project_name)
+          ->setError($e_name)
+          ->setCaption('A name like "Thrift" but not "Thrift releases".'))
+      ->appendChild(
+        id(new AphrontFormStaticControl())
+          ->setLabel('Repository')
+          ->setValue(
+              $this
+                ->getReleephProject()
+                ->loadPhabricatorRepository()
+                ->getName()))
+      ->appendChild(
+        id(new AphrontFormStaticControl())
+          ->setLabel('Arc Project')
+          ->setValue(
+              $this->getReleephProject()->loadArcanistProject()->getName()))
+      ->appendChild(
+        id(new AphrontFormStaticControl())
+          ->setLabel('Releeph Project PHID')
+          ->setValue(
+              $this->getReleephProject()->getPHID()))
+      ->appendChild(
+        id(new AphrontFormSelectControl())
+          ->setLabel('Phabricator Project')
+          ->setValue($phabricator_project_id)
+          ->setName('projectID')
+          ->setOptions($projects))
+      ->appendChild(
+        id(new AphrontFormTextControl())
+          ->setLabel('Trunk')
+          ->setValue($trunk_branch)
+          ->setName('trunkBranch')
+          ->setError($e_trunk_branch))
+      ->appendChild(
+        id(new AphrontFormTextControl())
+          ->setLabel('Release counter')
+          ->setValue($release_counter)
+          ->setName('releaseCounter')
+          ->setCaption(
+            "Used by the command line branch cutter's %N field"))
+      ->appendChild(
+        id(new AphrontFormTextAreaControl())
+          ->setLabel('Pick Instructions')
+          ->setValue($pick_failure_instructions)
+          ->setName('pickFailureInstructions')
+          ->setCaption(
+            "Instructions for pick failures, which will be used " .
+            "in emails generated by failed picks"))
+      ->appendChild(
+        id(new AphrontFormTextAreaControl())
+          ->setLabel('Tests paths')
+          ->setValue(implode("\n", $test_paths))
+          ->setName('testPaths')
+          ->setCaption(
+            'List of strings that all test files contain in their path '.
+            'in this project. One string per line. '.
+            'Examples: \'__tests__\', \'/javatests/\'...'));
+
+    $pushers_inset = id(new AphrontFormInsetView())
+      ->setTitle('Pushers')
+      ->appendChild(
+        'Pushers are allowed to approve Releeph requests to be committed. '.
+        'to this project\'s branches.  If you leave this blank then anyone '.
+        'is allowed to approve requests.')
+      ->appendChild(
+        id(new AphrontFormTokenizerControl())
+          ->setLabel('Pushers')
+          ->setName('pushers')
+          ->setDatasource('/typeahead/common/users/')
+          ->setValue($pusher_tokens));
+
+    $field_selector_options = array();
+    $field_selector_symbols = id(new PhutilSymbolLoader())
+      ->setType('class')
+      ->setConcreteOnly(true)
+      ->setAncestorClass('ReleephFieldSelector')
+      ->selectAndLoadSymbols();
+    foreach ($field_selector_symbols as $symbol) {
+      $selector_name = $symbol['name'];
+      $field_selector_options[$selector_name] = $selector_name;
+    }
+
+    $field_selector_blurb = hsprintf(
+        "If you you have additional information to render about Releeph ".
+        "requests, or want to re-arrange the UI, implement a ".
+        "<tt>ReleephFieldSelector</tt> and select it here.");
+
+    $fields_inset = id(new AphrontFormInsetView())
+      ->setTitle('Fields')
+      ->appendChild($field_selector_blurb)
+      ->appendChild(
+        id(new AphrontFormSelectControl())
+          ->setLabel('Selector')
+          ->setName('fieldSelector')
+          ->setValue($field_selector)
+          ->setOptions($field_selector_options));
+
+    $commit_author_inset = $this->buildCommitAuthorInset($commit_author);
+
+    // Build the Template inset
+    $markup_engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
+
+    // From DifferentialUnitFieldSpecification...
+    $markup_engine->setConfig('viewer', $request->getUser());
+
+    $help_markup = phutil_tag(
+      'div',
+      array(
+        'class' => 'phabricator-remarkup',
+      ),
+      phutil_safe_html(
+        $markup_engine->markupText(ReleephBranchTemplate::getHelpRemarkup())));
+
+    $branch_template_input = id(new AphrontFormTextControl())
+      ->setName('branchTemplate')
+      ->setValue($branch_template)
+      ->setLabel('Template')
+      ->setError($e_branch_template)
+      ->setCaption(
+        "Leave this blank to use your installation's default.");
+
+    $branch_template_preview = id(new ReleephBranchPreviewView())
+      ->setLabel('Preview')
+      ->addControl('template', $branch_template_input)
+      ->addStatic('arcProjectID', $arc_project_id)
+      ->addStatic('isSymbolic', false)
+      ->addStatic('projectName', $this->getReleephProject()->getName());
+
+    $template_inset = id(new AphrontFormInsetView())
+      ->setTitle('Branch Cutting')
+      ->appendChild(
+        'Provide a pattern for creating new branches.')
+      ->appendChild($branch_template_input)
+      ->appendChild($branch_template_preview)
+      ->appendChild($help_markup);
+
+    // Build the form
+    $form = id(new AphrontFormView())
+      ->setUser($request->getUser())
+      ->appendChild($basic_inset)
+      ->appendChild($pushers_inset)
+      ->appendChild($fields_inset)
+      ->appendChild($commit_author_inset)
+      ->appendChild($template_inset);
+
+    $form
+      ->appendChild(
+        id(new AphrontFormSubmitControl())
+          ->addCancelButton('/releeph/project/')
+          ->setValue('Save'));
+
+    $panel = id(new AphrontPanelView())
+      ->setHeader('Edit Releeph Project')
+      ->appendChild($form)
+      ->setWidth(AphrontPanelView::WIDTH_FORM);
+
+    return $this->buildStandardPageResponse(
+      array($error_view, $panel),
+      array('title' => 'Edit Releeph Project'));
+  }
+
+  private function buildCommitAuthorInset($current) {
+    $vcs_type = $this->getReleephProject()
+      ->loadPhabricatorRepository()
+      ->getVersionControlSystem();
+
+    switch ($vcs_type) {
+      case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
+      case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
+        break;
+
+      case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
+        return;
+        break;
+    }
+
+    $vcs_name = PhabricatorRepositoryType::getNameForRepositoryType($vcs_type);
+
+    $help_markup = hsprintf(<<<EOTEXT
+When your project's release engineers run <tt>arc releeph</tt>, they will be
+listed as the <strong>committer</strong> of the code committed to release
+branches.
+
+%s allows you to specify a separate author when committing code.  Some
+tools use the author of a commit (rather than the committer) when they need to
+notify someone about a build or test failure.
+
+Releeph can use one of the following to set the <strong>author</strong> of the
+commits it makes:
+EOTEXT
+    , $vcs_name);
+
+    $trunk = $this->getReleephProject()->getTrunkBranch();
+
+    $options = array(
+      array(
+        'value'   => ReleephProject::COMMIT_AUTHOR_FROM_DIFF,
+        'label'   => 'Original Author',
+        'caption' =>
+          "The author of the original commit in {$trunk}.",
+      ),
+      array(
+        'value'   => ReleephProject::COMMIT_AUTHOR_REQUESTOR,
+        'label'   => 'Requestor',
+        'caption' =>
+          "The person who requested that this code go into the release.",
+      ),
+      array(
+        'value'   => ReleephProject::COMMIT_AUTHOR_NONE,
+        'label'   => "None",
+        'caption' =>
+          "Only record the default committer information.",
+      ),
+    );
+
+    if (!$current) {
+      $current = ReleephProject::COMMIT_AUTHOR_FROM_DIFF;
+    }
+
+    $control = id(new AphrontFormRadioButtonControl())
+      ->setLabel('Author')
+      ->setName('commitWithAuthor')
+      ->setValue($current);
+
+    foreach ($options as $dict) {
+      $control->addButton($dict['value'], $dict['label'], $dict['caption']);
+    }
+
+    return id(new AphrontFormInsetView())
+      ->setTitle('Authors')
+      ->appendChild($help_markup)
+      ->appendChild($control);
+  }
+
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectListController.php b/src/applications/releeph/controller/project/ReleephProjectListController.php
new file mode 100644
index 000000000..e00709d08
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectListController.php
@@ -0,0 +1,70 @@
+<?php
+
+final class ReleephProjectListController extends PhabricatorController {
+
+  public function processRequest() {
+    $path = $this->getRequest()->getRequestURI()->getPath();
+    $is_active = strpos($path, 'inactive/') === false;
+
+    $releeph_projects = mfilter(
+      id(new ReleephProject())->loadAll(),
+      'getIsActive',
+      !$is_active);
+    $releeph_projects = msort($releeph_projects, 'getName');
+
+    $releeph_projects_set = new LiskDAOSet();
+    foreach ($releeph_projects as $releeph_project) {
+      $releeph_projects_set->addToSet($releeph_project);
+    }
+
+    $panel = new AphrontPanelView();
+
+    if ($is_active) {
+      $view_inactive_link = phutil_tag(
+        'a',
+        array(
+          'href'  => '/releeph/project/inactive/',
+        ),
+        'View inactive projects');
+      $panel
+        ->setHeader(hsprintf(
+          'Active Releeph Projects &middot; %s', $view_inactive_link))
+        ->appendChild(
+          id(new ReleephActiveProjectListView())
+            ->setUser($this->getRequest()->getUser())
+            ->setReleephProjects($releeph_projects));
+    } else {
+      $view_active_link = phutil_tag(
+        'a',
+        array(
+          'href' => '/releeph/project/'
+        ),
+        'View active projects');
+      $panel
+        ->setHeader(hsprintf(
+          'Inactive Releeph Projects &middot; %s', $view_active_link))
+        ->appendChild(
+            id(new ReleephInactiveProjectListView())
+              ->setUser($this->getRequest()->getUser())
+              ->setReleephProjects($releeph_projects));
+    }
+
+    if ($is_active) {
+      $create_new_project_button = phutil_tag(
+        'a',
+        array(
+          'href'  => '/releeph/project/create/',
+          'class' => 'green button',
+        ),
+        'Create New Project');
+      $panel->addButton($create_new_project_button);
+    }
+
+    return $this->buildStandardPageResponse(
+      $panel,
+      array(
+        'title' => 'List Releeph Projects'
+      ));
+  }
+
+}
diff --git a/src/applications/releeph/controller/project/ReleephProjectViewController.php b/src/applications/releeph/controller/project/ReleephProjectViewController.php
new file mode 100644
index 000000000..270682246
--- /dev/null
+++ b/src/applications/releeph/controller/project/ReleephProjectViewController.php
@@ -0,0 +1,45 @@
+<?php
+
+final class ReleephProjectViewController extends ReleephController {
+
+  public function processRequest() {
+    // Load all branches
+    $releeph_project = $this->getReleephProject();
+    $releeph_branches = id(new ReleephBranch())
+      ->loadAllWhere('releephProjectID = %d',
+                     $releeph_project->getID());
+
+    $path = $this->getRequest()->getRequestURI()->getPath();
+    $is_open_branches = strpos($path, 'closedbranches/') === false;
+
+    $view = id(new ReleephProjectView())
+      ->setShowOpenBranches($is_open_branches)
+      ->setUser($this->getRequest()->getUser())
+      ->setReleephProject($releeph_project)
+      ->setBranches($releeph_branches);
+
+    $crumbs = $this->buildApplicationCrumbs()
+      ->addCrumb(
+        id(new PhabricatorCrumbView())
+          ->setName($releeph_project->getName())
+          ->setHref($releeph_project->getURI()));
+
+    if ($releeph_project->getIsActive()) {
+      $crumbs->addAction(
+        id(new PhabricatorMenuItemView())
+          ->setHref($releeph_project->getURI('cutbranch'))
+          ->setName('Cut New Branch')
+          ->setIcon('create'));
+    }
+
+    return $this->buildStandardPageResponse(
+      array(
+        $crumbs,
+        $view,
+      ),
+      array(
+        'title' => $releeph_project->getName().' Releeph Project'
+      ));
+  }
+
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestActionController.php b/src/applications/releeph/controller/request/ReleephRequestActionController.php
new file mode 100644
index 000000000..f7229cda2
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestActionController.php
@@ -0,0 +1,71 @@
+<?php
+
+final class ReleephRequestActionController extends ReleephController {
+
+  private $action;
+
+  public function willProcessRequest(array $data) {
+    parent::willProcessRequest($data);
+    $this->action = $data['action'];
+  }
+
+  public function processRequest() {
+    $request = $this->getRequest();
+
+    $releeph_branch  = $this->getReleephBranch();
+    $releeph_request = $this->getReleephRequest();
+
+    $releeph_branch->populateReleephRequestHandles(
+      $request->getUser(), array($releeph_request));
+
+    $action = $this->action;
+
+    $user = $request->getUser();
+
+    $origin_uri = $releeph_request->loadReleephBranch()->getURI();
+
+    $editor = id(new ReleephRequestEditor($releeph_request))
+      ->setActor($user);
+
+    switch ($action) {
+      case 'want':
+      case 'pass':
+        static $action_map = array(
+          'want' => ReleephRequest::INTENT_WANT,
+          'pass' => ReleephRequest::INTENT_PASS);
+        $intent = $action_map[$action];
+        $editor->changeUserIntent($user, $intent);
+        break;
+
+      case 'mark-manually-picked':
+        $editor->markManuallyActioned('pick');
+        break;
+
+      case 'mark-manually-reverted':
+        $editor->markManuallyActioned('revert');
+        break;
+
+      default:
+        throw new Exception("unknown or unimplemented action {$action}");
+    }
+
+    // If we're adding a new user to userIntents, we'll have to re-populate
+    // request handles to load that user's data.
+    //
+    // This is cheap enough to do every time.
+    $this->getReleephBranch()->populateReleephRequestHandles(
+      $user, array($releeph_request));
+
+    $list = id(new ReleephRequestHeaderListView())
+      ->setReleephProject($this->getReleephProject())
+      ->setReleephBranch($this->getReleephBranch())
+      ->setReleephRequests(array($releeph_request))
+      ->setUser($request->getUser())
+      ->setAphrontRequest($this->getRequest())
+      ->setOriginType('request');
+
+    return id(new AphrontAjaxResponse())->setContent(array(
+      'markup' => head($list->renderInner())
+    ));
+  }
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestCreateController.php b/src/applications/releeph/controller/request/ReleephRequestCreateController.php
new file mode 100644
index 000000000..21415fc54
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestCreateController.php
@@ -0,0 +1,165 @@
+<?php
+
+final class ReleephRequestCreateController extends ReleephController {
+
+  const MAX_SUMMARY_LENGTH = 70;
+
+  public function processRequest() {
+    $request = $this->getRequest();
+
+    // We arrived via /releeph/request/create/?branchID=$id
+    $releeph_branch_id = $request->getInt('branchID');
+    if ($releeph_branch_id) {
+      $releeph_branch = id(new ReleephBranch())->load($releeph_branch_id);
+    } else {
+      // We arrived via /releeph/$project/$branch/request.
+      //
+      // If this throws an Exception, then somethind weird happened.
+      $releeph_branch = $this->getReleephBranch();
+    }
+
+    $releeph_project = $releeph_branch->loadReleephProject();
+    $repo = $releeph_project->loadPhabricatorRepository();
+
+    $request_identifier = $request->getStr('requestIdentifierRaw');
+    $e_request_identifier = true;
+
+    $releeph_request = new ReleephRequest();
+
+    $errors = array();
+
+    $selector = $releeph_project->getReleephFieldSelector();
+    $fields = $selector->getFieldSpecifications();
+    foreach ($fields as $field) {
+      $field
+        ->setReleephProject($releeph_project)
+        ->setReleephBranch($releeph_branch)
+        ->setReleephRequest($releeph_request);
+    }
+
+    if ($request->isFormPost()) {
+      foreach ($fields as $field) {
+        if ($field->isEditable()) {
+          try {
+            $field->setValueFromAphrontRequest($request);
+          } catch (ReleephFieldParseException $ex) {
+            $errors[] = $ex->getMessage();
+          }
+        }
+      }
+
+      $pr_commit = null;
+      $finder = id(new ReleephCommitFinder())
+        ->setReleephProject($releeph_project);
+      try {
+        $pr_commit = $finder->fromPartial($request_identifier);
+      } catch (Exception $e) {
+        $e_request_identifier = 'Invalid';
+        $errors[] =
+          "Request {$request_identifier} is probably not a valid commit";
+        $errors[] = $e->getMessage();
+      }
+
+      $pr_commit_data = null;
+      if (!$errors) {
+        $pr_commit_data = $pr_commit->loadCommitData();
+        if (!$pr_commit_data) {
+          $e_request_identifier = 'Not parsed yet';
+          $errors[] = "The requested commit hasn't been parsed yet.";
+        }
+      }
+
+      if (!$errors) {
+        $existing = id(new ReleephRequest())
+          ->loadOneWhere('requestCommitPHID = %s AND branchID = %d',
+              $pr_commit->getPHID(), $releeph_branch->getID());
+
+        if ($existing) {
+          return id(new AphrontRedirectResponse())
+            ->setURI('/releeph/request/edit/'.$existing->getID().
+                     '?existing=1');
+        }
+
+        id(new ReleephRequestEditor($releeph_request))
+          ->setActor($request->getUser())
+          ->create($pr_commit, $releeph_branch);
+
+        return id(new AphrontRedirectResponse())
+          ->setURI($releeph_branch->getURI());
+      }
+    }
+
+    $error_view = null;
+    if ($errors) {
+      $error_view = new AphrontErrorView();
+      $error_view->setErrors($errors);
+      $error_view->setTitle('Form Errors');
+    }
+
+    // For the typeahead
+    $branch_cut_point = id(new PhabricatorRepositoryCommit())
+      ->loadOneWhere(
+          'phid = %s',
+          $releeph_branch->getCutPointCommitPHID());
+
+    // Build the form
+    $form = id(new AphrontFormView())
+      ->setUser($request->getUser());
+
+    $origin = null;
+    $diff_rev_id = $request->getStr('D');
+    if ($diff_rev_id) {
+      $diff_rev = id(new DifferentialRevision())->load($diff_rev_id);
+      $origin = '/D'.$diff_rev->getID();
+      $title = sprintf(
+        'D%d: %s',
+        $diff_rev_id,
+        $diff_rev->getTitle());
+      $form
+        ->addHiddenInput('requestIdentifierRaw', 'D'.$diff_rev_id)
+        ->appendChild(
+          id(new AphrontFormStaticControl())
+            ->setLabel('Diff')
+            ->setValue($title));
+    } else {
+      $origin = $releeph_branch->getURI();
+      $form->appendChild(
+        id(new ReleephRequestTypeaheadControl())
+          ->setName('requestIdentifierRaw')
+          ->setLabel('Commit ID')
+          ->setRepo($repo)
+          ->setValue($request_identifier)
+          ->setError($e_request_identifier)
+          ->setStartTime($branch_cut_point->getEpoch())
+          ->setCaption(
+            'Start typing to autocomplete on commit title, '.
+            'or give a Phabricator commit identifier like rFOO1234'));
+    }
+
+    // Fields
+    foreach ($fields as $field) {
+      if ($field->isEditable()) {
+        $control = $field->renderEditControl($request);
+        $form->appendChild($control);
+      }
+    }
+
+    $form
+      ->appendChild(
+        id(new AphrontFormSubmitControl())
+          ->addCancelButton($origin)
+          ->setValue('Request'));
+
+    $panel = id(new AphrontPanelView())
+      ->setHeader(
+        'Request for '.
+        $releeph_branch->getDisplayNameWithDetail())
+      ->setWidth(AphrontPanelView::WIDTH_FORM)
+      ->appendChild($form);
+
+    return $this->buildStandardPageResponse(
+      array($error_view, $panel),
+      array('title' => 'Request pick'));
+  }
+
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php b/src/applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php
new file mode 100644
index 000000000..9da50fa84
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestDifferentialCreateController.php
@@ -0,0 +1,99 @@
+<?php
+
+final class ReleephRequestDifferentialCreateController
+  extends ReleephController {
+
+  private $revision;
+
+  public function willProcessRequest($data) {
+    $diff_rev_id = $data['diffRevID'];
+    $diff_rev = id(new DifferentialRevision())->load($diff_rev_id);
+    if (!$diff_rev) {
+      throw new Exception(sprintf('D%d not found!', $diff_rev_id));
+    }
+    $this->revision = $diff_rev;
+  }
+
+  public function processRequest() {
+    $request = $this->getRequest();
+    $user = $request->getUser();
+
+    $arc_project = id(new PhabricatorRepositoryArcanistProject())
+      ->loadOneWhere('phid = %s', $this->revision->getArcanistProjectPHID());
+
+    $projects = id(new ReleephProject())->loadAllWhere(
+      'arcanistProjectID = %d AND isActive = 1',
+      $arc_project->getID());
+    if (!$projects) {
+      throw new ReleephRequestException(sprintf(
+        "D%d belongs to the '%s' Arcanist project, ".
+        "which is not part of any Releeph project!",
+        $this->revision->getID(),
+        $arc_project->getName()));
+    }
+
+    $branches = id(new ReleephBranch())->loadAllWhere(
+      'releephProjectID IN (%Ld) AND isActive = 1',
+      mpull($projects, 'getID'));
+    if (!$branches) {
+      throw new ReleephRequestException(sprintf(
+        "D%d could be in the Releeph project(s) %s, ".
+        "but this project / none of these projects have open branches.",
+        $this->revision->getID(),
+        implode(', ', mpull($projects, 'getName'))));
+    }
+
+    if (count($branches) === 1) {
+      return id(new AphrontRedirectResponse())
+        ->setURI($this->buildReleephRequestURI(head($branches)));
+    }
+
+    $projects = msort(
+      mpull($projects, null, 'getID'),
+      'getName');
+
+    $branch_groups = mgroup($branches, 'getReleephProjectID');
+
+    require_celerity_resource('releeph-request-differential-create-dialog');
+    $dialog = id(new AphrontDialogView())
+      ->setUser($user)
+      ->setTitle('Choose Releeph Branch')
+      ->setClass('releeph-request-differential-create-dialog')
+      ->addCancelButton('/D'.$request->getStr('D'));
+
+    $dialog->appendChild(
+      "This differential revision changes code that is associated ".
+      "with multiple Releeph branches.  ".
+      "Please select the branch where you would like this code to be picked.");
+
+    foreach ($branch_groups as $project_id => $branches) {
+      $project = idx($projects, $project_id);
+      $dialog->appendChild(
+        phutil_tag(
+          'h1',
+          array(),
+          $project->getName()));
+      $branches = msort($branches, 'getBasename');
+      foreach ($branches as $branch) {
+        $uri = $this->buildReleephRequestURI($branch);
+        $dialog->appendChild(
+          phutil_tag(
+            'a',
+            array(
+              'href' => $uri,
+            ),
+            $branch->getDisplayNameWithDetail()));
+      }
+    }
+
+    return id(new AphrontDialogResponse)
+      ->setDialog($dialog);
+  }
+
+  private function buildReleephRequestURI(ReleephBranch $branch) {
+    return id(new PhutilURI('/releeph/request/create/'))
+      ->setQueryParam('branchID', $branch->getID())
+      ->setQueryParam('D', $this->revision->getID());
+  }
+
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestEditController.php b/src/applications/releeph/controller/request/ReleephRequestEditController.php
new file mode 100644
index 000000000..eefe3bf60
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestEditController.php
@@ -0,0 +1,132 @@
+<?php
+
+final class ReleephRequestEditController extends ReleephController {
+
+  public function processRequest() {
+    $request = $this->getRequest();
+
+    $releeph_branch  = $this->getReleephBranch();
+    $releeph_request = $this->getReleephRequest();
+
+    $releeph_branch->populateReleephRequestHandles(
+      $request->getUser(), array($releeph_request));
+
+    $phids = array();
+    $phids[] = $releeph_request->getRequestCommitPHID();
+    $phids[] = $releeph_request->getRequestUserPHID();
+    $phids[] = $releeph_request->getCommittedByUserPHID();
+
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      ->setViewer($request->getUser())
+      ->loadHandles();
+
+    $age_string = phabricator_format_relative_time(
+      time() - $releeph_request->getDateCreated());
+
+    // Warn the user if we see this
+    $notice_view = null;
+    if ($request->getInt('existing')) {
+      $notice_messages = array(
+        'You are editing an existing pick request!',
+        hsprintf(
+          "Requested %s ago by %s",
+          $age_string,
+          $handles[$releeph_request->getRequestUserPHID()]->renderLink())
+      );
+      $notice_view = id(new AphrontErrorView())
+        ->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
+        ->setErrors($notice_messages);
+    }
+
+    // <aidehua> epriestley: Is it common to pass around a referer URL to
+    // return from whence one came? [...]
+    // <epriestley> If you only have two places, maybe consider some parameter
+    // rather than the full URL.
+    switch ($request->getStr('origin')) {
+      case 'request':
+        $origin_uri = '/RQ'.$releeph_request->getID();
+        break;
+
+      case 'branch':
+      default:
+        $origin_uri = $releeph_request->loadReleephBranch()->getURI();
+        break;
+    }
+
+    $errors = array();
+
+    $selector = $this->getReleephProject()->getReleephFieldSelector();
+    $fields = $selector->getFieldSpecifications();
+    foreach ($fields as $field) {
+      $field
+        ->setReleephProject($this->getReleephProject())
+        ->setReleephBranch($this->getReleephBranch())
+        ->setReleephRequest($this->getReleephRequest());
+    }
+
+    if ($request->isFormPost()) {
+      foreach ($fields as $field) {
+        if ($field->isEditable()) {
+          try {
+            $field->setValueFromAphrontRequest($request);
+          } catch (ReleephFieldParseException $ex) {
+            $errors[] = $ex->getMessage();
+          }
+        }
+      }
+
+      if (!$errors) {
+        $releeph_request->save();
+        return id(new AphrontRedirectResponse())->setURI($origin_uri);
+      }
+    }
+
+    /**
+     * Build the rest of the page
+     */
+    $error_view = null;
+    if ($errors) {
+      $error_view = new AphrontErrorView();
+      $error_view->setErrors($errors);
+      $error_view->setTitle('Form Errors');
+    }
+
+    $form = id(new AphrontFormView())
+      ->setUser($request->getUser())
+      ->appendChild(
+        id(new AphrontFormMarkupControl())
+          ->setLabel('Original Commit')
+          ->setValue(
+            $handles[$releeph_request->getRequestCommitPHID()]->renderLink()))
+      ->appendChild(
+        id(new AphrontFormMarkupControl())
+          ->setLabel('Requestor')
+          ->setValue(hsprintf(
+            '%s %s ago',
+            $handles[$releeph_request->getRequestUserPHID()]->renderLink(),
+            $age_string)));
+
+    // Fields
+    foreach ($fields as $field) {
+      if ($field->isEditable()) {
+        $control = $field->renderEditControl($request);
+        $form->appendChild($control);
+      }
+    }
+
+    $form
+      ->appendChild(
+        id(new AphrontFormSubmitControl())
+          ->addCancelButton($origin_uri, 'Cancel')
+          ->setValue('Save'));
+
+    $panel = id(new AphrontPanelView())
+      ->setHeader('Edit Pick Request')
+      ->setWidth(AphrontPanelView::WIDTH_FORM)
+      ->appendChild($form);
+
+    return $this->buildStandardPageResponse(
+      array($notice_view, $error_view, $panel),
+      array('title', 'Edit Pick Request'));
+  }
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestTypeaheadController.php b/src/applications/releeph/controller/request/ReleephRequestTypeaheadController.php
new file mode 100644
index 000000000..c86060c4b
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestTypeaheadController.php
@@ -0,0 +1,92 @@
+<?php
+
+final class ReleephRequestTypeaheadController
+  extends PhabricatorTypeaheadDatasourceController {
+
+  public function processRequest() {
+    $request = $this->getRequest();
+
+    $query    = $request->getStr('q');
+    $repo_id  = $request->getInt('repo');
+    $since    = $request->getInt('since');
+    $limit    = $request->getInt('limit');
+
+    $now = time();
+    $data = array();
+
+    // Dummy instances used for getting connections, table names, etc.
+    $pr_commit = new PhabricatorRepositoryCommit();
+    $pr_commit_data = new PhabricatorRepositoryCommitData();
+
+    $conn = $pr_commit->establishConnection('r');
+
+    $rows = queryfx_all(
+      $conn,
+      'SELECT
+        rc.phid as commitPHID,
+        rc.authorPHID,
+        rcd.authorName,
+        SUBSTRING(rcd.commitMessage, 1, 100) AS shortMessage,
+        rc.commitIdentifier,
+        rc.epoch
+        FROM %T rc
+        INNER JOIN %T rcd ON rcd.commitID = rc.id
+        WHERE repositoryID = %d
+        AND rc.epoch >= %d
+        AND (
+          rcd.commitMessage LIKE %~
+          OR
+          rc.commitIdentifier LIKE %~
+        )
+        ORDER BY rc.epoch DESC
+        LIMIT %d',
+      $pr_commit->getTableName(),
+      $pr_commit_data->getTableName(),
+      $repo_id,
+      $since,
+      $query,
+      $query,
+      $limit);
+
+    foreach ($rows as $row) {
+      $full_commit_id = $row['commitIdentifier'];
+      $short_commit_id = substr($full_commit_id, 0, 12);
+      $first_line = $this->getFirstLine($row['shortMessage']);
+      $data[] = array(
+        $full_commit_id,
+        $short_commit_id,
+        $row['authorName'],
+        phabricator_format_relative_time($now - $row['epoch']),
+        $first_line,
+      );
+    }
+
+    return id(new AphrontAjaxResponse())
+      ->setContent($data);
+  }
+
+  /**
+   * Split either at the first new line, or a bunch of dashes.
+   *
+   * Really just a legacy from old Releeph Daemon commit messages where I used
+   * to say:
+   *
+   *   Commit of FOO for BAR
+   *   ------------
+   *   This does X Y Z
+   *
+   */
+  private function getFirstLine($commit_message_fragment) {
+    static $separators = array('-------', "\n");
+    $string = ltrim($commit_message_fragment);
+    $first_line = $string;
+    foreach ($separators as $separator) {
+      if ($pos = strpos($string, $separator)) {
+        $first_line = substr($string, 0, $pos);
+        break;
+      }
+    }
+    return $first_line;
+  }
+
+}
diff --git a/src/applications/releeph/controller/request/ReleephRequestViewController.php b/src/applications/releeph/controller/request/ReleephRequestViewController.php
new file mode 100644
index 000000000..f0cd2661f
--- /dev/null
+++ b/src/applications/releeph/controller/request/ReleephRequestViewController.php
@@ -0,0 +1,99 @@
+<?php
+
+final class ReleephRequestViewController extends ReleephController {
+
+  public function processRequest() {
+    $request = $this->getRequest();
+
+    $uri_path = $request->getRequestURI()->getPath();
+    $legacy_prefix = '/releeph/request/';
+    if (strncmp($uri_path, $legacy_prefix, strlen($legacy_prefix)) === 0) {
+      return id(new AphrontRedirectResponse())
+        ->setURI('/RQ'.$this->getReleephRequest()->getID());
+    }
+
+    $releeph_request = $this->getReleephRequest();
+    $releeph_branch  = $this->getReleephBranch();
+    $releeph_project = $this->getReleephProject();
+
+    $releeph_branch->populateReleephRequestHandles(
+      $request->getUser(), array($releeph_request));
+
+    $rq_view =
+      id(new ReleephRequestHeaderListView())
+        ->setReleephProject($releeph_project)
+        ->setReleephBranch($releeph_branch)
+        ->setReleephRequests(array($releeph_request))
+        ->setUser($request->getUser())
+        ->setAphrontRequest($this->getRequest())
+        ->setReloadOnStateChange(true)
+        ->setOriginType('request');
+
+    $events = $releeph_request->loadEvents();
+    $phids = array_mergev(mpull($events, 'extractPHIDs'));
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      ->setViewer($request->getUser())
+      ->loadHandles();
+
+    $rq_event_list_view =
+      id(new ReleephRequestEventListView())
+        ->setUser($request->getUser())
+        ->setEvents($events)
+        ->setHandles($handles);
+
+    // Handle comment submit
+    $origin_uri = '/RQ'.$releeph_request->getID();
+    if ($request->isFormPost()) {
+      id(new ReleephRequestEditor($releeph_request))
+        ->setActor($request->getUser())
+        ->addComment($request->getStr('comment'));
+      return id(new AphrontRedirectResponse())->setURI($origin_uri);
+    }
+
+    $form = id(new AphrontFormView())
+      ->setUser($request->getUser())
+      ->appendChild(
+        id(new AphrontFormTextAreaControl())
+          ->setName('comment'))
+      ->appendChild(
+        id(new AphrontFormSubmitControl())
+          ->addCancelButton($origin_uri, 'Cancel')
+          ->setValue("Submit"));
+
+    $rq_comment_form = id(new AphrontPanelView())
+      ->setHeader('Add a comment')
+      ->setWidth(AphrontPanelView::WIDTH_FULL)
+      ->appendChild($form);
+
+    $title = hsprintf("RQ%d: %s",
+      $releeph_request->getID(),
+      $releeph_request->getSummaryForDisplay());
+
+    $crumbs = $this->buildApplicationCrumbs()
+      ->addCrumb(
+        id(new PhabricatorCrumbView())
+          ->setName($releeph_project->getName())
+          ->setHref($releeph_project->getURI()))
+      ->addCrumb(
+        id(new PhabricatorCrumbView())
+          ->setName($releeph_branch->getDisplayNameWithDetail())
+          ->setHref($releeph_branch->getURI()))
+      ->addCrumb(
+        id(new PhabricatorCrumbView())
+          ->setName('RQ'.$releeph_request->getID())
+          ->setHref('/RQ'.$releeph_request->getID()));
+
+    return $this->buildStandardPageResponse(
+      array(
+        $crumbs,
+        array(
+          $rq_view,
+          $rq_event_list_view,
+          $rq_comment_form
+        )
+      ),
+      array(
+        'title' => $title
+      ));
+  }
+}
diff --git a/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php b/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php
new file mode 100644
index 000000000..840241747
--- /dev/null
+++ b/src/applications/releeph/differential/DifferentialReleephRequestFieldSpecification.php
@@ -0,0 +1,348 @@
+<?php
+
+/**
+ * This DifferentialFieldSpecification exists for two reason:
+ *
+ * 1: To parse "Releeph: picks RQ<nn>" headers in commits created by
+ * arc-releeph so that RQs committed by arc-releeph have real
+ * PhabricatorRepositoryCommits associated with them (instaed of just the SHA
+ * of the commit, as seen by the pusher).
+ *
+ * 2: If requestors want to commit directly to their release branch, they can
+ * use this header to (i) indicate on a differential revision that this
+ * differential revision is for the release branch, and (ii) when they land
+ * their diff on to the release branch manually, the ReleephRequest is
+ * automatically updated (instead of having to use the "Mark Manually Picked"
+ * button.)
+ *
+ */
+final class DifferentialReleephRequestFieldSpecification
+  extends DifferentialFieldSpecification {
+
+  const ACTION_PICKS    = 'picks';
+  const ACTION_REVERTS  = 'reverts';
+
+  private $releephAction;
+  private $releephPHIDs = array();
+
+  public function getStorageKey() {
+    return 'releeph:actions';
+  }
+
+  public function getValueForStorage() {
+    return json_encode(array(
+      'releephAction' => $this->releephAction,
+      'releephPHIDs'  => $this->releephPHIDs,
+    ));
+  }
+
+  public function setValueFromStorage($json) {
+    if ($json) {
+      $dict = json_decode($json, true);
+      $this->releephAction = idx($dict, 'releephAction');
+      $this->releephPHIDs = idx($dict, 'releephPHIDs');
+    }
+    return $this;
+  }
+
+  public function shouldAppearOnRevisionView() {
+    return true;
+  }
+
+  public function renderLabelForRevisionView() {
+    return 'Releeph';
+  }
+
+  public function getRequiredHandlePHIDs() {
+    return mpull($this->loadReleephRequests(), 'getPHID');
+  }
+
+  public function renderValueForRevisionView() {
+    static $tense = array(
+      self::ACTION_PICKS => array(
+        'future'  => 'Will pick',
+        'past'    => 'Picked',
+      ),
+      self::ACTION_REVERTS => array(
+        'future'  => 'Will revert',
+        'past'    => 'Reverted',
+      ),
+    );
+
+    $releeph_requests = $this->loadReleephRequests();
+    if (!$releeph_requests) {
+      return null;
+    }
+
+    $status = $this->getRevision()->getStatus();
+    if ($status == ArcanistDifferentialRevisionStatus::CLOSED) {
+      $verb = $tense[$this->releephAction]['past'];
+    } else {
+      $verb = $tense[$this->releephAction]['future'];
+    }
+
+    $parts = hsprintf('%s...', $verb);
+    foreach ($releeph_requests as $releeph_request) {
+      $parts->appendHTML(phutil_tag('br'));
+      $parts->appendHTML(
+        $this->getHandle($releeph_request->getPHID())->renderLink());
+    }
+
+    return $parts;
+  }
+
+  public function shouldAppearOnCommitMessage() {
+    return true;
+  }
+
+  public function getCommitMessageKey() {
+    return 'releephActions';
+  }
+
+  public function setValueFromParsedCommitMessage($dict) {
+    $this->releephAction = $dict['releephAction'];
+    $this->releephPHIDs = $dict['releephPHIDs'];
+    return $this;
+  }
+
+  public function renderValueForCommitMessage($is_edit) {
+    $releeph_requests = $this->loadReleephRequests();
+    if (!$releeph_requests) {
+      return null;
+    }
+
+    $parts = array($this->releephAction);
+    foreach ($releeph_requests as $releeph_request) {
+      $parts[] = 'RQ'.$releeph_request->getID();
+    }
+
+    return implode(' ', $parts);
+  }
+
+  /**
+   * Releeph fields should look like:
+   *
+   *   Releeph: picks RQ1 RQ2, RQ3
+   *   Releeph: reverts RQ1
+   */
+  public function parseValueFromCommitMessage($value) {
+    /**
+     * Releeph commit messages look like this (but with more blank lines,
+     * omitted here):
+     *
+     *   Make CaptainHaddock more reasonable
+     *   Releeph: picks RQ1
+     *   Requested By: edward
+     *   Approved By: edward (requestor)
+     *   Request Reason: x
+     *   Summary: Make the Haddock implementation more reasonable.
+     *   Test Plan: none
+     *   Reviewers: user1
+     *
+     * Some of these fields are recognized by Differential (e.g. "Requested
+     * By").  They are folded up into the "Releeph" field, parsed by this
+     * class.  As such $value includes more than just the first-line:
+     *
+     *   "picks RQ1\n\nRequested By: edward\n\nApproved By: edward (requestor)"
+     *
+     * To hack around this, just consider the first line of $value when
+     * determining what Releeph actions the parsed commit is performing.
+     */
+    $first_line = head(array_filter(explode("\n", $value)));
+
+    $tokens = preg_split('/\s*,?\s+/', $first_line);
+    $raw_action = array_shift($tokens);
+    $action = strtolower($raw_action);
+
+    if (!$action) {
+      return null;
+    }
+
+    switch ($action) {
+      case self::ACTION_REVERTS:
+      case self::ACTION_PICKS:
+        break;
+
+      default:
+        throw new DifferentialFieldParseException(
+          "Commit message contains unknown Releeph action '{$raw_action}'!");
+        break;
+    }
+
+    $releeph_requests = array();
+    foreach ($tokens as $token) {
+      $match = array();
+      if (!preg_match('/^(?:RQ)?(\d+)$/i', $token, $match)) {
+        $label = $this->renderLabelForCommitMessage();
+        throw new DifferentialFieldParseException(
+          "Commit message contains unparseable ".
+          "Releeph request token '{$token}'!");
+      }
+
+      $id = (int) $match[1];
+      $releeph_request = id(new ReleephRequest())->load($id);
+
+      if (!$releeph_request) {
+        throw new DifferentialFieldParseException(
+          "Commit message references non existent releeph request: {$value}!");
+      }
+
+      $releeph_requests[] = $releeph_request;
+    }
+
+    if (count($releeph_requests) > 1) {
+      $rqs_seen = array();
+      $groups = array();
+      foreach ($releeph_requests as $releeph_request) {
+        $releeph_branch = $releeph_request->loadReleephBranch();
+        $branch_name = $releeph_branch->getName();
+        $rq_id = 'RQ'.$releeph_request->getID();
+
+        if (idx($rqs_seen, $rq_id)) {
+          throw new DifferentialFieldParseException(
+            "Commit message refers to {$rq_id} multiple times!");
+        }
+        $rqs_seen[$rq_id] = true;
+
+        if (!isset($groups[$branch_name])) {
+          $groups[$branch_name] = array();
+        }
+        $groups[$branch_name][] = $rq_id;
+      }
+
+      if (count($groups) > 1) {
+        $lists = array();
+        foreach ($groups as $branch_name => $rq_ids) {
+          $lists[] = implode(', ', $rq_ids).' in '.$branch_name;
+        }
+        throw new DifferentialFieldParseException(
+          "Commit message references multiple Releeph requests, ".
+          "but the requests are in different branches: ".
+          implode('; ', $lists));
+      }
+    }
+
+    $phids = mpull($releeph_requests, 'getPHID');
+
+    $data = array(
+      'releephAction' => $action,
+      'releephPHIDs'  => $phids,
+    );
+    return $data;
+  }
+
+  public function renderLabelForCommitMessage() {
+    return 'Releeph';
+  }
+
+  public function shouldAppearOnCommitMessageTemplate() {
+    return false;
+  }
+
+  public function didParseCommit(PhabricatorRepository $repo,
+                                 PhabricatorRepositoryCommit $commit,
+                                 PhabricatorRepositoryCommitData $data) {
+
+    $releeph_requests = $this->loadReleephRequests();
+
+    if (!$releeph_requests) {
+      return;
+    }
+
+    $releeph_branch = head($releeph_requests)->loadReleephBranch();
+    if (!$this->isCommitOnBranch($repo, $commit, $releeph_branch)) {
+      return;
+    }
+
+    foreach ($releeph_requests as $releeph_request) {
+      if ($this->releephAction === self::ACTION_PICKS) {
+        $action = 'pick';
+      } else {
+        $action = 'revert';
+      }
+
+      $actor_phid = coalesce(
+        $data->getCommitDetail('committerPHID'),
+        $data->getCommitDetail('authorPHID'));
+
+      $actor = id(new PhabricatorUser())
+        ->loadOneWhere('phid = %s', $actor_phid);
+
+      id(new ReleephRequestEditor($releeph_request))
+        ->setActor($actor)
+        ->discoverCommit($action, $commit, $data);
+    }
+  }
+
+  private function loadReleephRequests() {
+    if (!$this->releephPHIDs) {
+      return array();
+    } else {
+      return id(new ReleephRequest())
+        ->loadAllWhere('phid IN (%Ls)', $this->releephPHIDs);
+    }
+  }
+
+  private function isCommitOnBranch(PhabricatorRepository $repo,
+                                    PhabricatorRepositoryCommit $commit,
+                                    ReleephBranch $releeph_branch) {
+
+    switch ($repo->getVersionControlSystem()) {
+      case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
+        list($output) = $repo->execxLocalCommand(
+          'branch --all --no-color --contains %s',
+          $commit->getCommitIdentifier());
+
+        $remote_prefix = 'remotes/origin/';
+        $branches = array();
+        foreach (array_filter(explode("\n", $output)) as $line) {
+          $tokens = explode(' ', $line);
+          $ref = last($tokens);
+          if (strncmp($ref, $remote_prefix, strlen($remote_prefix)) === 0) {
+            $branch = substr($ref, strlen($remote_prefix));
+            $branches[$branch] = $branch;
+          }
+        }
+
+        return idx($branches, $releeph_branch->getName());
+        break;
+
+      case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
+        $change_query = DiffusionPathChangeQuery::newFromDiffusionRequest(
+          DiffusionRequest::newFromDictionary(array(
+            'repository'  => $repo,
+            'commit'      => $commit->getCommitIdentifier(),
+          )));
+        $path_changes = $change_query->loadChanges();
+        $commit_paths = mpull($path_changes, 'getPath');
+
+        $branch_path = $releeph_branch->getName();
+
+        $in_branch = array();
+        $ex_branch = array();
+        foreach ($commit_paths as $path) {
+          if (strncmp($path, $branch_path, strlen($branch_path)) === 0) {
+            $in_branch[] = $path;
+          } else {
+            $ex_branch[] = $path;
+          }
+        }
+
+        if ($in_branch && $ex_branch) {
+          $error = sprintf(
+            "CONFUSION: commit %s in %s contains %d path change(s) that were ".
+            "part of a Releeph branch, but also has %d path change(s) not ".
+            "part of a Releeph branch!",
+            $commit->getCommitIdentifier(),
+            $repo->getCallsign(),
+            count($in_branch),
+            count($ex_branch));
+          phlog($error);
+        }
+
+        return !empty($in_branch);
+        break;
+    }
+  }
+
+}
diff --git a/src/applications/releeph/differential/ReleephDifferentialRevisionDetailRenderer.php b/src/applications/releeph/differential/ReleephDifferentialRevisionDetailRenderer.php
new file mode 100644
index 000000000..fbff6983f
--- /dev/null
+++ b/src/applications/releeph/differential/ReleephDifferentialRevisionDetailRenderer.php
@@ -0,0 +1,39 @@
+<?php
+
+final class ReleephDifferentialRevisionDetailRenderer {
+
+  public static function generateActionLink(DifferentialRevision $revision,
+                                            DifferentialDiff $diff) {
+
+    $arc_project = $diff->loadArcanistProject(); // 93us
+    if (!$arc_project) {
+      return;
+    }
+
+    $releeph_projects = id(new ReleephProject())->loadAllWhere(
+      'arcanistProjectID = %d AND isActive = 1',
+      $arc_project->getID());
+
+    if (!$releeph_projects) {
+      return;
+    }
+
+    $releeph_branches = id(new ReleephBranch())->loadAllWhere(
+      'releephProjectID IN (%Ld) AND isActive = 1',
+      mpull($releeph_projects, 'getID'));
+
+    if (!$releeph_branches) {
+      return;
+    }
+
+    $uri = new PhutilURI(
+      '/releeph/request/differentialcreate/D'.$revision->getID());
+    return array(
+      'name'  => 'Releeph Request',
+      'sigil' => 'workflow',
+      'href'  => $uri,
+      'icon'  => 'fork',
+    );
+  }
+
+}
diff --git a/src/applications/releeph/editor/ReleephBranchEditor.php b/src/applications/releeph/editor/ReleephBranchEditor.php
new file mode 100644
index 000000000..d3f679502
--- /dev/null
+++ b/src/applications/releeph/editor/ReleephBranchEditor.php
@@ -0,0 +1,106 @@
+<?php
+
+final class ReleephBranchEditor extends PhabricatorEditor {
+
+  private $releephProject;
+  private $releephBranch;
+
+  public function setReleephProject(ReleephProject $rp) {
+    $this->releephProject = $rp;
+    return $this;
+  }
+
+  public function setReleephBranch(ReleephBranch $branch) {
+    $this->releephBranch = $branch;
+    return $this;
+  }
+
+  public function newBranchFromCommit(PhabricatorRepositoryCommit $cut_point,
+                                      $branch_date,
+                                      $symbolic_name = null) {
+
+    $template = $this->releephProject->getDetail('branchTemplate');
+    if (!$template) {
+      $template = ReleephBranchTemplate::getRequiredDefaultTemplate();
+    }
+
+    $cut_point_handle = head(
+      id(new PhabricatorObjectHandleData(array($cut_point->getPHID())))
+        // We'll assume that whoever found the $cut_point has passed privacy
+        // checks.
+        ->setViewer($this->requireActor())
+        ->loadHandles());
+
+    list($name, $errors) = id(new ReleephBranchTemplate())
+      ->setCommitHandle($cut_point_handle)
+      ->setBranchDate($branch_date)
+      ->setReleephProjectName($this->releephProject->getName())
+      ->interpolate($template);
+
+    $basename = last(explode('/', $name));
+
+    $table = id(new ReleephBranch());
+    $transaction = $table->openTransaction();
+    $branch = id(new ReleephBranch())
+      ->setName($name)
+      ->setBasename($basename)
+      ->setReleephProjectID($this->releephProject->getID())
+      ->setCreatedByUserPHID($this->requireActor()->getPHID())
+      ->setCutPointCommitIdentifier($cut_point->getCommitIdentifier())
+      ->setCutPointCommitPHID($cut_point->getPHID())
+      ->setIsActive(1)
+      ->setDetail('branchDate', $branch_date)
+      ->save();
+
+    /**
+     * Steal the symbolic name from any other branch that has it (in this
+     * project).
+     */
+    if ($symbolic_name) {
+      $others = id(new ReleephBranch())->loadAllWhere(
+        'releephProjectID = %d',
+        $this->releephProject->getID());
+      foreach ($others as $other) {
+        if ($other->getSymbolicName() == $symbolic_name) {
+          $other
+            ->setSymbolicName(null)
+            ->save();
+        }
+      }
+      $branch
+        ->setSymbolicName($symbolic_name)
+        ->save();
+    }
+
+    id(new ReleephEvent())
+      ->setType(ReleephEvent::TYPE_BRANCH_CREATE)
+      ->setActorPHID($this->requireActor()->getPHID())
+      ->setReleephProjectID($this->releephProject->getID())
+      ->setReleephBranchID($branch->getID())
+      ->save();
+
+    $table->saveTransaction();
+    return $branch;
+  }
+
+  // aka "close" and "reopen"
+  public function changeBranchAccess($is_active) {
+    $branch = $this->releephBranch;
+    $branch->openTransaction();
+
+    $branch
+      ->setIsActive((int)$is_active)
+      ->save();
+
+    id(new ReleephEvent())
+      ->setType(ReleephEvent::TYPE_BRANCH_ACCESS)
+      ->setActorPHID($this->requireActor()->getPHID())
+      ->setReleephProjectID($branch->getReleephProjectID())
+      ->setReleephBranchID($branch->getID())
+      ->setDetail('isActive', $is_active)
+      ->save();
+
+    $branch->saveTransaction();
+  }
+
+}
diff --git a/src/applications/releeph/editor/ReleephRequestEditor.php b/src/applications/releeph/editor/ReleephRequestEditor.php
new file mode 100644
index 000000000..8cb0945e2
--- /dev/null
+++ b/src/applications/releeph/editor/ReleephRequestEditor.php
@@ -0,0 +1,408 @@
+<?php
+
+/**
+ * Provide methods for the common ways of creating and mutating a
+ * ReleephRequest, sending email when something interesting happens.
+ *
+ * This class generates ReleephRequestEvents, and each type of event
+ * (ReleephRequestEvent::TYPE_*) corresponds to one of the editor methods.
+ *
+ * The editor methods (except for create() use newEvent() and commit() to save
+ * some code duplication.
+ */
+final class ReleephRequestEditor extends PhabricatorEditor {
+
+  private $releephRequest;
+  private $event;
+  private $silentUpdate;
+
+  public function __construct(ReleephRequest $rq) {
+    $this->releephRequest = $rq;
+  }
+
+  public function setSilentUpdate($silent) {
+    $this->silentUpdate = $silent;
+    return $this;
+  }
+
+
+/* -(  ReleephRequest edit methods  )---------------------------------------- */
+
+  /**
+   * Request a PhabricatorRepositoryCommit to be committed to the given
+   * ReleephBranch.
+   */
+  public function create(PhabricatorRepositoryCommit $commit,
+                         ReleephBranch $branch) {
+
+    // We can't use newEvent() / commit() abstractions, so do what those
+    // helpers do manually.
+    $requestor = $this->requireActor();
+
+    $rq = $this->releephRequest;
+    $rq->openTransaction();
+
+    $rq
+      ->setBranchID($branch->getID())
+      ->setRequestCommitIdentifier($commit->getCommitIdentifier())
+      ->setRequestCommitPHID($commit->getPHID())
+      ->setRequestCommitOrdinal($commit->getID())
+      ->setInBranch(0)
+      ->setRequestUserPHID($requestor->getPHID())
+      ->setUserIntent($requestor, ReleephRequest::INTENT_WANT)
+      ->save();
+
+    $event = id(new ReleephRequestEvent())
+      ->setType(ReleephRequestEvent::TYPE_CREATE)
+      ->setActorPHID($requestor->getPHID())
+      ->setStatusBefore(null)
+      ->setStatusAfter($rq->getStatus())
+      ->setReleephRequestID($rq->getID())
+      ->setDetail('commitPHID', $commit->getPHID())
+      ->save();
+
+    $rq->saveTransaction();
+
+    // Mail
+    if (!$this->silentUpdate) {
+      $project = $this->releephRequest->loadReleephProject();
+      $mail = id(new ReleephRequestMail())
+        ->setReleephRequest($this->releephRequest)
+        ->setReleephProject($project)
+        ->setEvents(array($event))
+        ->setSenderAndRecipientPHID($requestor->getPHID())
+        ->addTos(ReleephRequestMail::ENT_ALL_PUSHERS)
+        ->addCCs(ReleephRequestMail::ENT_REQUESTOR)
+        ->send();
+    }
+  }
+
+  /**
+   * Record whether the PhabricatorUser wants or passes on this request.
+   */
+  public function changeUserIntent(PhabricatorUser $user, $intent) {
+    $project = $this->releephRequest->loadReleephProject();
+    $is_pusher = $project->isPusher($user);
+
+    $event = $this->newEvent()
+      ->setType(ReleephRequestEvent::TYPE_USER_INTENT)
+      ->setDetail('userPHID', $user->getPHID())
+      ->setDetail('wasPusher', $is_pusher)
+      ->setDetail('newIntent', $intent);
+
+    $this->releephRequest
+      ->setUserIntent($user, $intent);
+
+    $this->commit();
+
+    // Mail if this is 'interesting'
+    if (!$this->silentUpdate &&
+        $event->getStatusBefore() != $event->getStatusAfter()) {
+
+      $project = $this->releephRequest->loadReleephProject();
+      $mail = id(new ReleephRequestMail())
+        ->setReleephRequest($this->releephRequest)
+        ->setReleephProject($project)
+        ->setEvents(array($event))
+        ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+        ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+        ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+        ->send();
+    }
+  }
+
+  /**
+   * Record the results of someone trying to pick or revert a request in their
+   * local repository, to give advance warning that something doesn't pick or
+   * revert cleanly.
+   */
+  public function changePickStatus($pick_status, $dry_run, $details) {
+    $event = $this->newEvent()
+      ->setType(ReleephRequestEvent::TYPE_PICK_STATUS)
+      ->setDetail('newPickStatus', $pick_status)
+      ->setDetail('commitDetails', $details);
+    $this->releephRequest->setPickStatus($pick_status);
+    $this->commit();
+
+    // Failures should generate an email
+    if (!$this->silentUpdate &&
+        !$dry_run &&
+        ($pick_status == ReleephRequest::PICK_FAILED ||
+         $pick_status == ReleephRequest::REVERT_FAILED)) {
+
+      $project = $this->releephRequest->loadReleephProject();
+      $mail = id(new ReleephRequestMail())
+        ->setReleephRequest($this->releephRequest)
+        ->setReleephProject($project)
+        ->setEvents(array($event))
+        ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+        ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+        ->addCCs(ReleephRequestMail::ENT_ACTORS)
+        ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+        ->send();
+    }
+  }
+
+  /**
+   * Record that a request was committed locally, and is about to be pushed to
+   * the remote repository.
+   *
+   * This lets us mark a ReleephRequest as being in a branch in real time so
+   * that no one else tries to pick it.
+   *
+   * When the daemons discover this commit in the repository with
+   * DifferentialReleephRequestFieldSpecification, we'll be able to recrod the
+   * commit's PHID as well.  That process is slow though, and
+   * we don't want to wait a whole minute before marking something as cleanly
+   * picked or reverted.
+   */
+  public function recordSuccessfulCommit($action, $new_commit_id) {
+    $table = $this->releephRequest;
+    $table->openTransaction();
+
+    $actor = $this->requireActor();
+
+    $event = id(new ReleephRequestEvent())
+      ->setReleephRequestID($this->releephRequest->getID())
+      ->setActorPHID($actor->getPHID())
+      ->setType(ReleephRequestEvent::TYPE_COMMIT)
+      ->setDetail('action', $action)
+      ->setDetail('newCommitIdentifier', $new_commit_id)
+      ->save();
+
+    switch ($action) {
+      case 'pick':
+        $this->releephRequest
+          ->setInBranch(1)
+          ->setPickStatus(ReleephRequest::PICK_OK)
+          ->setCommitIdentifier($new_commit_id)
+          ->setCommitPHID(null)
+          ->setCommittedByUserPHID($actor->getPHID())
+          ->save();
+        break;
+
+      case 'revert':
+        $this->releephRequest
+          ->setInBranch(0)
+          ->setPickStatus(ReleephRequest::REVERT_OK)
+          ->setCommitIdentifier(null)
+          ->setCommitPHID(null)
+          ->setCommittedByUserPHID(null)
+          ->save();
+        break;
+
+      default:
+        $table->killTransaction();
+        throw new Exception("Unknown action {$action}!");
+        break;
+    }
+
+    $table->saveTransaction();
+
+    // Don't spam people about local commits -- we'll do that with
+    // discoverCommit() instead!
+  }
+
+  /**
+   * Mark this request as picked or reverted based on discovering it in the
+   * branch.  We have a PhabricatorRepositoryCommit, so we're able to
+   * setCommitPHID on the ReleephRequest (unlike recordSuccessfulCommit()).
+   */
+  public function discoverCommit(
+    $action,
+    PhabricatorRepositoryCommit $commit,
+    PhabricatorRepositoryCommitData $data) {
+
+    $table = $this->releephRequest;
+    $table->openTransaction();
+    $table->beginWriteLocking();
+
+    $past_events = id(new ReleephRequestEvent())->loadAllWhere(
+      'releephRequestID = %d AND type = %s',
+      $this->releephRequest->getID(),
+      ReleephRequestEvent::TYPE_DISCOVERY);
+
+    foreach ($past_events as $past_event) {
+      if ($past_event->getDetail('newCommitIdentifier')
+            == $commit->getCommitIdentifier()) {
+
+        // Avoid re-discovery if reparsing!
+        $table->endWriteLocking();
+        $table->killTransaction();
+        return;
+      }
+    }
+
+    $actor = $this->requireActor();
+
+    $event = id(new ReleephRequestEvent())
+      ->setReleephRequestID($this->releephRequest->getID())
+      ->setActorPHID($actor->getPHID())
+      ->setType(ReleephRequestEvent::TYPE_DISCOVERY)
+      ->setDateCreated($commit->getEpoch())
+      ->setDetail('action', $action)
+      ->setDetail('newCommitIdentifier', $commit->getCommitIdentifier())
+      ->setDetail('newCommitPHID', $commit->getPHID())
+      ->setDetail('authorPHID', $data->getCommitDetail('authorPHID'))
+      ->setDetail('committerPHID', $data->getCommitDetail('committerPHID'))
+      ->save();
+
+    switch ($action) {
+      case 'pick':
+        $this->releephRequest
+          ->setInBranch(1)
+          ->setPickStatus(ReleephRequest::PICK_OK)
+          ->setCommitIdentifier($commit->getCommitIdentifier())
+          ->setCommitPHID($commit->getPHID())
+          ->setCommittedByUserPHID($actor->getPHID())
+          ->save();
+        break;
+
+      case 'revert':
+        $this->releephRequest
+          ->setInBranch(0)
+          ->setPickStatus(ReleephRequest::REVERT_OK)
+          ->setCommitIdentifier(null)
+          ->setCommitPHID(null)
+          ->setCommittedByUserPHID(null)
+          ->save();
+        break;
+
+      default:
+        $table->killTransaction();
+        throw new Exception("Unknown action {$action}!");
+        break;
+    }
+
+    $table->endWriteLocking();
+    $table->saveTransaction();
+
+    // Mail
+    if (!$this->silentUpdate) {
+      $project = $this->releephRequest->loadReleephProject();
+      $mail = id(new ReleephRequestMail())
+        ->setReleephRequest($this->releephRequest)
+        ->setReleephProject($project)
+        ->setEvents(array($event))
+        ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+        ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+        ->addCCs(ReleephRequestMail::ENT_ACTORS)
+        ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+        ->send();
+    }
+  }
+
+  public function addComment($comment) {
+    $event = $this->newEvent()
+      ->setType(ReleephRequestEvent::TYPE_COMMENT)
+      ->setDetail('comment', $comment);
+    $this->commit();
+
+    // Mail
+    if (!$this->silentUpdate) {
+      $project = $this->releephRequest->loadReleephProject();
+      $mail = id(new ReleephRequestMail())
+        ->setReleephRequest($this->releephRequest)
+        ->setReleephProject($project)
+        ->setEvents(array($event))
+        ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+        ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+        ->addCCs(ReleephRequestMail::ENT_ACTORS)
+        ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+        ->send();
+    }
+  }
+
+  public function markManuallyActioned($action) {
+    $event = $this->newEvent()
+      ->setType(ReleephRequestEvent::TYPE_MANUAL_ACTION)
+      ->setDetail('action', $action);
+
+    $actor = $this->requireActor();
+    $project = $this->releephRequest->loadReleephProject();
+    $requestor_phid = $this->releephRequest->getRequestUserPHID();
+    if (!$project->isPusher($actor) &&
+        $actor->getPHID() !== $requestor_phid) {
+
+      throw new Exception(
+        "Only pushers or requestors can mark requests as ".
+        "manually picked or reverted!");
+    }
+
+    switch ($action) {
+      case 'pick':
+        $in_branch = true;
+        $intent = ReleephRequest::INTENT_WANT;
+        break;
+
+      case 'revert':
+        $in_branch = false;
+        $intent = ReleephRequest::INTENT_PASS;
+        break;
+
+      default:
+        throw new Exception("Unknown action {$action}!");
+        break;
+    }
+
+    $this->releephRequest
+      ->setInBranch((int)$in_branch)
+      ->setUserIntent($this->getActor(), $intent);
+
+    $this->commit();
+
+    // Mail
+    if (!$this->silentUpdate) {
+      $project = $this->releephRequest->loadReleephProject();
+      $mail = id(new ReleephRequestMail())
+        ->setReleephRequest($this->releephRequest)
+        ->setReleephProject($project)
+        ->setEvents(array($event))
+        ->setSenderAndRecipientPHID($this->requireActor()->getPHID())
+        ->addTos(ReleephRequestMail::ENT_REQUESTOR)
+        ->addCCs(ReleephRequestMail::ENT_INTERESTED_PUSHERS)
+        ->send();
+    }
+  }
+
+/* -(  Implementation  )----------------------------------------------------- */
+
+  /**
+   * Create and return a new ReleephRequestEvent bound to the editor's
+   * ReleephRequest, inside a transaction.
+   *
+   * When you call commit(), the event and this editor's ReleephRequest (along
+   * with any changes you made to the ReleephRequest) are saved and the
+   * transaction committed.
+   */
+  private function newEvent() {
+    $actor = $this->requireActor();
+
+    if ($this->event) {
+      throw new Exception("You have already called newEvent()!");
+    }
+    $rq = $this->releephRequest;
+    $rq->openTransaction();
+
+    $this->event = id(new ReleephRequestEvent())
+      ->setReleephRequestID($rq->getID())
+      ->setActorPHID($actor->getPHID())
+      ->setStatusBefore($rq->getStatus());
+
+    return $this->event;
+  }
+
+  private function commit() {
+    if (!$this->event) {
+      throw new Exception("You must call newEvent first!");
+    }
+    $rq = $this->releephRequest;
+    $this->event
+      ->setStatusAfter($rq->getStatus())
+      ->save();
+    $rq->save();
+    $rq->saveTransaction();
+    $this->event = null;
+  }
+
+}
diff --git a/src/applications/releeph/editor/mail/ReleephRequestMail.php b/src/applications/releeph/editor/mail/ReleephRequestMail.php
new file mode 100644
index 000000000..a06f6f334
--- /dev/null
+++ b/src/applications/releeph/editor/mail/ReleephRequestMail.php
@@ -0,0 +1,213 @@
+<?php
+
+/**
+ * Build an email that renders a group of events with and appends some standard
+ * Releeph things (a URI for this request, and this branch).
+ *
+ * Also includes some helper stuff for adding groups of people to the To: and
+ * Cc: headers.
+ */
+final class ReleephRequestMail {
+
+  const ENT_REQUESTOR           = 'requestor';
+  const ENT_DIFF                = 'diff';
+  const ENT_ALL_PUSHERS         = 'pushers';
+  const ENT_ACTORS              = 'actors';
+  const ENT_INTERESTED_PUSHERS  = 'interested-pushers';
+
+  private $sender;
+  private $tos = array();
+  private $ccs = array();
+  private $events;
+  private $releephRequest;
+  private $releephProject;
+
+  public function setReleephRequest(ReleephRequest $rq) {
+    $this->releephRequest = $rq;
+    return $this;
+  }
+
+  public function setReleephProject(ReleephProject $rp) {
+    $this->releephProject = $rp;
+    return $this;
+  }
+
+  public function setEvents(array $events) {
+    assert_instances_of($events, 'ReleephRequestEvent');
+    $this->events = $events;
+    return $this;
+  }
+
+  public function setSenderAndRecipientPHID($sender_phid) {
+    $this->sender = $sender_phid;
+    $this->tos[] = $sender_phid;
+    return $this;
+  }
+
+  public function addTos($entity) {
+    $this->tos = array_merge(
+      $this->tos,
+      $this->getEntityPHIDs($entity));
+    return $this;
+  }
+
+  public function addCcs($entity) {
+    $this->ccs = array_merge(
+      $this->tos,
+      $this->getEntityPHIDs($entity));
+    return $this;
+  }
+
+  public function send() {
+    $this->buildMail()->save();
+  }
+
+  public function buildMail() {
+    return id(new PhabricatorMetaMTAMail())
+      ->setSubject($this->renderSubject())
+      ->setBody($this->buildBody()->render())
+      ->setFrom($this->sender)
+      ->addTos($this->tos)
+      ->addCCs($this->ccs);
+  }
+
+  private function getEntityPHIDs($entity) {
+    $phids = array();
+    switch ($entity) {
+      // The requestor
+      case self::ENT_REQUESTOR:
+        $phids[] = $this->releephRequest->getRequestUserPHID();
+        break;
+
+      // People on the original diff
+      case self::ENT_DIFF:
+        $commit = $this->releephRequest->loadPhabricatorRepositoryCommit();
+        $commit_data = $commit->loadCommitData();
+        if ($commit_data) {
+          $phids[] = $commit_data->getCommitDetail('reviewerPHID');
+          $phids[] = $commit_data->getCommitDetail('authorPHID');
+        }
+        break;
+
+      // All pushers for this project
+      case self::ENT_ALL_PUSHERS:
+        $phids = array_merge(
+          $phids,
+          $this->releephProject->getPushers());
+        break;
+
+      // Pushers who have explicitly wanted or passed on this request
+      case self::ENT_INTERESTED_PUSHERS:
+        $all_pushers = $this->releephProject->getPushers();
+        $intents = $this->releephRequest->getUserIntents();
+        foreach ($all_pushers as $pusher) {
+          if (idx($intents, $pusher)) {
+            $phids[] = $pusher;
+          }
+        }
+        break;
+
+      // Anyone who created our list of events
+      case self::ENT_ACTORS:
+        $phids = array_merge(
+          $phids,
+          mpull($this->events, 'getActorPHID'));
+        break;
+
+      default:
+        throw new Exception(
+          "Unknown entity type {$entity}!");
+        break;
+    }
+
+    return array_filter($phids);
+  }
+
+  private function buildBody() {
+    $body = new PhabricatorMetaMTAMailBody();
+    $rq = $this->releephRequest;
+
+    // Events and comments
+    $phids = array(
+      $rq->getPHID(),
+    );
+    foreach ($this->events as $event) {
+      $phids = array_merge($phids, $event->extractPHIDs());
+    }
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      // By the time we're generating email, we can assume that whichever
+      // entitties are receving the email are authorized to see the loaded
+      // handles!
+      ->setViewer(PhabricatorUser::getOmnipotentUser())
+      ->loadHandles();
+
+    $raw_events = id(new ReleephRequestEventListView())
+      ->setUser(PhabricatorUser::getOmnipotentUser())
+      ->setHandles($handles)
+      ->setEvents($this->events)
+      ->renderForEmail();
+
+    $body->addRawSection($raw_events);
+
+    $project = $rq->loadReleephProject();
+    $branch = $rq->loadReleephBranch();
+
+    /**
+     * If any of the events we are emailing about were TYPE_PICK_STATUS where
+     * the newPickStatus was a pick failure (and/or a revert failure?), include
+     * pick failure instructions.
+     */
+    $pick_failure_events = array();
+    foreach ($this->events as $event) {
+      if ($event->getType() == ReleephRequestEvent::TYPE_PICK_STATUS &&
+          $event->getDetail('newPickStatus') == ReleephRequest::PICK_FAILED) {
+
+        $pick_failure_events[] = $event;
+      }
+    }
+
+    if ($pick_failure_events) {
+      $instructions = $project->getDetail('pick_failure_instructions');
+      if ($instructions) {
+        $body->addTextSection('PICK FAILURE INSTRUCTIONS', $instructions);
+      }
+    }
+
+    // Common stuff at the end
+    $body->addTextSection(
+      'RELEEPH REQUEST',
+      $handles[$rq->getPHID()]->getFullName()."\n".
+      PhabricatorEnv::getProductionURI('/RQ'.$rq->getID()));
+
+    $project_and_branch = sprintf(
+      '%s - %s',
+      $project->getName(),
+      $branch->getDisplayNameWithDetail());
+
+    $body->addTextSection(
+      'RELEEPH BRANCH',
+      $project_and_branch."\n".
+      $branch->getURI());
+
+    // But verbose stuff at the *very* end!
+    foreach ($pick_failure_events as $event) {
+      $failure_details = $event->getDetail('commitDetails');
+      if ($failure_details) {
+        $body->addRawSection('PICK FAILURE DETAILS');
+        foreach ($failure_details as $heading => $data) {
+          $body->addTextSection($heading, $data);
+        }
+      }
+    }
+
+    return $body;
+  }
+
+  private function renderSubject() {
+    $rq = $this->releephRequest;
+    $id = $rq->getID();
+    $summary = $rq->getSummaryForDisplay();
+    return "RQ{$id}: {$summary}";
+  }
+
+}
diff --git a/src/applications/releeph/field/exception/ReleephFieldParseException.php b/src/applications/releeph/field/exception/ReleephFieldParseException.php
new file mode 100644
index 000000000..fcb513df1
--- /dev/null
+++ b/src/applications/releeph/field/exception/ReleephFieldParseException.php
@@ -0,0 +1,12 @@
+<?php
+
+final class ReleephFieldParseException extends Exception {
+
+  public function __construct(ReleephFieldSpecification $field,
+                              $message) {
+
+    $name = $field->getName();
+    parent::__construct("{$name}: {$message}");
+  }
+
+}
diff --git a/src/applications/releeph/field/exception/ReleephFieldSpecificationIncompleteException.php b/src/applications/releeph/field/exception/ReleephFieldSpecificationIncompleteException.php
new file mode 100644
index 000000000..6e67dcf35
--- /dev/null
+++ b/src/applications/releeph/field/exception/ReleephFieldSpecificationIncompleteException.php
@@ -0,0 +1,11 @@
+<?php
+
+final class ReleephFieldSpecificationIncompleteException extends Exception {
+
+  public function __construct(ReleephFieldSpecification $field) {
+    $class = get_class($field);
+    parent::__construct(
+      "Releeph field class {$class} is incompletely implemented.");
+  }
+
+}
diff --git a/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php b/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php
new file mode 100644
index 000000000..26506ef2e
--- /dev/null
+++ b/src/applications/releeph/field/selector/ReleephDefaultFieldSelector.php
@@ -0,0 +1,73 @@
+<?php
+
+final class ReleephDefaultFieldSelector extends ReleephFieldSelector {
+
+  public function getFieldSpecifications() {
+    return array(
+      new ReleephCommitMessageFieldSpecification(),
+      new ReleephSummaryFieldSpecification(),
+      new ReleephReasonFieldSpecification(),
+      new ReleephAuthorFieldSpecification(),
+      new ReleephRevisionFieldSpecification(),
+      new ReleephRequestorFieldSpecification(),
+      new ReleephSeverityFieldSpecification(),
+      new ReleephOriginalCommitFieldSpecification(),
+      new ReleephDiffMessageFieldSpecification(),
+      new ReleephStatusFieldSpecification(),
+      new ReleephIntentFieldSpecification(),
+      new ReleephBranchCommitFieldSpecification(),
+      new ReleephDiffSizeFieldSpecification(),
+      new ReleephDiffChurnFieldSpecification(),
+    );
+  }
+
+  public function arrangeFieldsForHeaderView(array $fields) {
+    return array(
+      // Top group
+      array(
+        'left' => self::selectFields($fields, array(
+          'ReleephAuthorFieldSpecification',
+          'ReleephRevisionFieldSpecification',
+          'ReleephOriginalCommitFieldSpecification',
+          'ReleephDiffSizeFieldSpecification',
+          'ReleephDiffChurnFieldSpecification',
+        )),
+        'right' => self::selectFields($fields, array(
+          'ReleephRequestorFieldSpecification',
+          'ReleephSeverityFieldSpecification',
+          'ReleephStatusFieldSpecification',
+          'ReleephIntentFieldSpecification',
+          'ReleephBranchCommitFieldSpecification',
+        ))
+      ),
+
+      // Bottom group
+      array(
+        'left' => self::selectFields($fields, array(
+          'ReleephDiffMessageFieldSpecification',
+        )),
+        'right' => self::selectFields($fields, array(
+          'ReleephReasonFieldSpecification',
+        ))
+      )
+    );
+  }
+
+  public function arrangeFieldsForSelectForm(array $fields) {
+    self::selectFields($fields, array(
+      'ReleephStatusFieldSpecification',
+      'ReleephSeverityFieldSpecification',
+      'ReleephRequestorFieldSpecification',
+    ));
+  }
+
+  public function sortFieldsForCommitMessage(array $fields) {
+    self::selectFields($fields, array(
+      'ReleephCommitMessageFieldSpecification',
+      'ReleephRequestorFieldSpecification',
+      'ReleephIntentFieldSpecification',
+      'ReleephReasonFieldSpecification',
+    ));
+  }
+
+}
diff --git a/src/applications/releeph/field/selector/ReleephFieldSelector.php b/src/applications/releeph/field/selector/ReleephFieldSelector.php
new file mode 100644
index 000000000..3c7afe90d
--- /dev/null
+++ b/src/applications/releeph/field/selector/ReleephFieldSelector.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Control the rendering of ReleephRequestHeaderView, and the layout of the
+ * ReleephRequest search dialog (in ReleephBranchViewController.)
+ */
+abstract class ReleephFieldSelector {
+
+  final public function __construct() {
+    // <empty>
+  }
+
+  abstract public function getFieldSpecifications();
+
+  abstract public function arrangeFieldsForHeaderView(array $fields);
+
+  abstract public function arrangeFieldsForSelectForm(array $fields);
+
+  public function sortFieldsForCommitMessage(array $fields) {
+    assert_instances_of($fields, 'ReleephFieldSpecification');
+    return $fields;
+  }
+
+  protected static function selectFields(array $fields, array $classes) {
+    assert_instances_of($fields, 'ReleephFieldSpecification');
+
+    $map = array();
+    foreach ($fields as $field) {
+      $map[get_class($field)] = $field;
+    }
+
+    $result = array();
+    foreach ($classes as $class) {
+      $field = idx($map, $class);
+      if (!$field) {
+        throw new Exception(
+          "Tried to select a in instance of '{$class}' but that field ".
+          "is not configured for this project!");
+      }
+
+      if (idx($result, $class)) {
+        throw new Exception(
+          "You have asked to select the field '{$class}' ".
+          "more than once!");
+      }
+
+      $result[$class] = $field;
+    }
+
+    return $result;
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php b/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php
new file mode 100644
index 000000000..610ecb2d5
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephAuthorFieldSpecification.php
@@ -0,0 +1,39 @@
+<?php
+
+final class ReleephAuthorFieldSpecification
+  extends ReleephFieldSpecification {
+
+  private static $authorMap = array();
+
+  public function bulkLoad(array $releeph_requests) {
+    foreach ($releeph_requests as $releeph_request) {
+      $commit = $releeph_request->loadPhabricatorRepositoryCommit();
+      if ($commit) {
+        $author_phid = $commit->getAuthorPHID();
+        self::$authorMap[$releeph_request->getPHID()] = $author_phid;
+      }
+    }
+
+    ReleephUserView::getNewInstance()
+      ->setUser($this->getUser())
+      ->setReleephProject($this->getReleephProject())
+      ->load(self::$authorMap);
+  }
+
+  public function getName() {
+    return 'Author';
+  }
+
+  public function renderValueForHeaderView() {
+    $rr = $this->getReleephRequest();
+    $author_phid = idx(self::$authorMap, $rr->getPHID());
+    if ($author_phid) {
+      return ReleephUserView::getNewInstance()
+        ->setRenderUserPHID($author_phid)
+        ->render();
+    } else {
+      return 'Unknown Author';
+    }
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php b/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php
new file mode 100644
index 000000000..4aa2c93f2
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephBranchCommitFieldSpecification.php
@@ -0,0 +1,30 @@
+<?php
+
+final class ReleephBranchCommitFieldSpecification
+  extends ReleephFieldSpecification {
+
+  public function getName() {
+    return 'Commit';
+  }
+
+  public function renderValueForHeaderView() {
+    $rr = $this->getReleephRequest();
+    if (!$rr->getInBranch()) {
+      return null;
+    }
+
+    $c_phid = $rr->getCommitPHID();
+    $c_id = $rr->getCommitIdentifier();
+
+    if ($c_phid) {
+      $handles = $rr->getHandles();
+      $val = $handles[$c_phid]->renderLink();
+    } else if ($c_id) {
+      $val = $c_id;
+    } else {
+      $val = '???';
+    }
+    return $val;
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php b/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php
new file mode 100644
index 000000000..3ad528f3c
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephCommitMessageFieldSpecification.php
@@ -0,0 +1,46 @@
+<?php
+
+final class ReleephCommitMessageFieldSpecification
+  extends ReleephFieldSpecification {
+
+  public function getName() {
+    return '__only_for_commit_message!';
+  }
+
+  public function shouldAppearOnCommitMessage() {
+    return true;
+  }
+
+  public function renderLabelForCommitMessage() {
+    return $this->renderCommonLabel();
+  }
+
+  public function renderValueForCommitMessage() {
+    return $this->renderCommonValue(
+      DifferentialReleephRequestFieldSpecification::ACTION_PICKS);
+  }
+
+  public function shouldAppearOnRevertMessage() {
+    return true;
+  }
+
+  public function renderLabelForRevertMessage() {
+    return $this->renderCommonLabel();
+  }
+
+  public function renderValueForRevertMessage() {
+    return $this->renderCommonValue(
+      DifferentialReleephRequestFieldSpecification::ACTION_REVERTS);
+  }
+
+  private function renderCommonLabel() {
+    return id(new DifferentialReleephRequestFieldSpecification())
+      ->renderLabelForCommitMessage();
+  }
+
+  private function renderCommonValue($action) {
+    $rq = 'RQ'.$this->getReleephRequest()->getID();
+    return "{$action} {$rq}";
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php b/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php
new file mode 100644
index 000000000..b8f4310a3
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephDiffChurnFieldSpecification.php
@@ -0,0 +1,77 @@
+<?php
+
+final class ReleephDiffChurnFieldSpecification
+  extends ReleephFieldSpecification {
+
+  const REJECTIONS_WEIGHT =  30;
+  const COMMENTS_WEIGHT   =   7;
+  const UPDATES_WEIGHT    =  10;
+  const MAX_POINTS        = 100;
+
+  public function getName() {
+    return 'Churn';
+  }
+
+  public function renderValueForHeaderView() {
+    $diff_rev = $this->getReleephRequest()->loadDifferentialRevision();
+    if (!$diff_rev) {
+      return null;
+    }
+
+    $diff_rev = $this->getReleephRequest()->loadDifferentialRevision();
+    $comments = $diff_rev->loadRelatives(
+      new DifferentialComment(),
+      'revisionID');
+
+    $counts = array();
+    foreach ($comments as $comment) {
+      $action = $comment->getAction();
+      if (!isset($counts[$action])) {
+        $counts[$action] = 0;
+      }
+      $counts[$action] += 1;
+    }
+
+    // 'none' action just means a plain comment
+    $comments   = idx($counts, 'none',     0);
+    $rejections = idx($counts, 'reject',   0);
+    $updates    = idx($counts, 'update',   0);
+
+    $points =
+      self::REJECTIONS_WEIGHT * $rejections +
+      self::COMMENTS_WEIGHT * $comments +
+      self::UPDATES_WEIGHT * $updates;
+
+    if ($points === 0) {
+      $points = 0.15 * self::MAX_POINTS;
+      $blurb = 'Silent diff';
+    } else {
+      $parts = array();
+      if ($rejections) {
+        $parts[] = pht('%d rejection(s)', $rejections);
+      }
+      if ($comments) {
+        $parts[] = pht('%d comment(s)', $comments);
+      }
+      if ($updates) {
+        $parts[] = pht('%d update(s)', $updates);
+      }
+
+      if (count($parts) === 0) {
+        $blurb = '';
+      } else if (count($parts) === 1) {
+        $blurb = head($parts);
+      } else {
+        $last = array_pop($parts);
+        $blurb = implode(', ', $parts).' and '.$last;
+      }
+    }
+
+    return id(new AphrontProgressBarView())
+      ->setValue($points)
+      ->setMax(self::MAX_POINTS)
+      ->setCaption($blurb)
+      ->render();
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php b/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php
new file mode 100644
index 000000000..9d87d616c
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephDiffMessageFieldSpecification.php
@@ -0,0 +1,37 @@
+<?php
+
+final class ReleephDiffMessageFieldSpecification
+  extends ReleephFieldSpecification {
+
+  public function getName() {
+    return 'Message';
+  }
+
+  public function renderLabelForHeaderView() {
+    return null;
+  }
+
+  public function renderValueForHeaderView() {
+    $commit_data = $this
+      ->getReleephRequest()
+      ->loadPhabricatorRepositoryCommitData();
+    if (!$commit_data) {
+      return '';
+    }
+
+    $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
+    $engine->setConfig('viewer', $this->getUser());
+    $markup = phutil_tag(
+      'div',
+      array(
+        'class' => 'phabricator-remarkup',
+      ),
+      $engine->markupText($commit_data->getCommitMessage()));
+
+    return id(new AphrontNoteView())
+      ->setTitle('Commit Message')
+      ->appendChild($markup)
+      ->render();
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php b/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php
new file mode 100644
index 000000000..586db1b1d
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephDiffSizeFieldSpecification.php
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * While this class could take advantage of bulkLoad(), in practice
+ * loadRelatives fixes all that for us.
+ */
+final class ReleephDiffSizeFieldSpecification
+  extends ReleephFieldSpecification {
+
+  const LINES_WEIGHT =  1;
+  const PATHS_WEIGHT = 30;
+  const MAX_POINTS = 1000;
+
+  public function getName() {
+    return 'Size';
+  }
+
+  public function renderValueForHeaderView() {
+    $diff_rev = $this->getReleephRequest()->loadDifferentialRevision();
+    if (!$diff_rev) {
+      return '';
+    }
+
+    $diffs = $diff_rev->loadRelatives(
+      new DifferentialDiff(),
+      'revisionID',
+      'getID',
+      'creationMethod <> "commit"');
+
+    $all_changesets = array();
+    $most_recent_changesets = null;
+    foreach ($diffs as $diff) {
+      $changesets = $diff->loadRelatives(new DifferentialChangeset(), 'diffID');
+      $all_changesets += $changesets;
+      $most_recent_changesets = $changesets;
+    }
+
+    // The score is based on all changesets for all versions of this diff
+    $all_changes = $this->countLinesAndPaths($all_changesets);
+    $points =
+      self::LINES_WEIGHT * $all_changes['code']['lines'] +
+      self::PATHS_WEIGHT * count($all_changes['code']['paths']);
+
+    // The blurb is just based on the most recent version of the diff
+    $mr_changes = $this->countLinesAndPaths($most_recent_changesets);
+
+    $test_tag = '';
+    if ($mr_changes['tests']['paths']) {
+      Javelin::initBehavior('phabricator-tooltips');
+      require_celerity_resource('aphront-tooltip-css');
+
+      $test_blurb =
+        pht('%d line(s)', $mr_changes['tests']['lines']).' and '.
+        pht('%d path(s)', count($mr_changes['tests']['paths'])).
+        " contain changes to test code:\n";
+      foreach ($mr_changes['tests']['paths'] as $mr_test_path) {
+        $test_blurb .= pht("%s\n", $mr_test_path);
+      }
+
+      $test_tag = javelin_tag(
+        'span',
+        array(
+          'sigil' => 'has-tooltip',
+          'meta' => array(
+            'tip' => $test_blurb,
+            'align' => 'E',
+            'size' => 'auto'),
+          'style' => ''),
+        ' + tests');
+    }
+
+    $blurb = hsprintf("%s%s.",
+      pht('%d line(s)', $mr_changes['code']['lines']).' and '.
+      pht('%d path(s)', count($mr_changes['code']['paths'])).' over '.
+      pht('%d diff(s)', count($diffs)),
+      $test_tag);
+
+    return id(new AphrontProgressBarView())
+      ->setValue($points)
+      ->setMax(self::MAX_POINTS)
+      ->setCaption($blurb)
+      ->render();
+  }
+
+  private function countLinesAndPaths(array $changesets) {
+    assert_instances_of($changesets, 'DifferentialChangeset');
+    $lines = 0;
+    $paths_touched = array();
+    $test_lines = 0;
+    $test_paths_touched = array();
+
+    foreach ($changesets as $ch) {
+      if ($this->getReleephProject()->isTestFile($ch->getFilename())) {
+        $test_lines += $ch->getAddLines() + $ch->getDelLines();
+        $test_paths_touched[] = $ch->getFilename();
+      } else {
+        $lines += $ch->getAddLines() + $ch->getDelLines();
+        $paths_touched[] = $ch->getFilename();
+      }
+    }
+    return array(
+      'code' => array(
+        'lines' => $lines,
+        'paths' => array_unique($paths_touched),
+      ),
+      'tests' => array(
+        'lines' => $test_lines,
+        'paths' => array_unique($test_paths_touched),
+      )
+    );
+  }
+}
diff --git a/src/applications/releeph/field/specification/ReleephFieldSpecification.php b/src/applications/releeph/field/specification/ReleephFieldSpecification.php
new file mode 100644
index 000000000..992808f12
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephFieldSpecification.php
@@ -0,0 +1,359 @@
+<?php
+
+abstract class ReleephFieldSpecification {
+
+  abstract public function getName();
+
+/* -(  Storage  )------------------------------------------------------------ */
+
+  public function getStorageKey() {
+    return null;
+  }
+
+  final public function isEditable() {
+    return $this->getStorageKey() !== null;
+  }
+
+  /**
+   * This will be called many times if you are using **Selecting**.  In
+   * particular, for N selecting fields, selectReleephRequests() is called
+   * N-squared times, each time for R ReleephRequests.
+   */
+  final public function getValue() {
+    $key = $this->getRequiredStorageKey();
+    return $this->getReleephRequest()->getDetail($key);
+  }
+
+  final public function setValue($value) {
+    $key = $this->getRequiredStorageKey();
+    return $this->getReleephRequest()->setDetail($key, $value);
+  }
+
+  /**
+   * @throws ReleephFieldParseException, to show an error.
+   */
+  public function validate($value) {
+    return;
+  }
+
+
+/* -(  Header View  )-------------------------------------------------------- */
+
+  /**
+   * Return a label for use in rendering the fields table.  If you return null,
+   * the renderLabelForHeaderView data will span both columns.
+   */
+  public function renderLabelForHeaderView() {
+    return $this->getName();
+  }
+
+  public function renderValueForHeaderView() {
+    $key = $this->getRequiredStorageKey();
+    return $this->getReleephRequest()->getDetail($key);
+  }
+
+
+/* -(  Edit View  )---------------------------------------------------------- */
+
+  public function renderEditControl(AphrontRequest $request) {
+    throw new ReleephFieldSpecificationIncompleteException($this);
+  }
+
+  public function setValueFromAphrontRequest(AphrontRequest $request) {
+    $data = $request->getRequestData();
+    $value = idx($data, $this->getRequiredStorageKey());
+    $this->validate($value);
+    $this->setValue($value);
+  }
+
+
+/* -(  Conduit  )------------------------------------------------------------ */
+
+  public function getKeyForConduit() {
+    return $this->getRequiredStorageKey();
+  }
+
+  public function getValueForConduit() {
+    return $this->getValue();
+  }
+
+  public function setValueFromConduitAPIRequest(ConduitAPIRequest $request) {
+    $value = idx(
+      $request->getValue('fields', array()),
+      $this->getRequiredStorageKey());
+    $this->validate($value);
+    $this->setValue($value);
+  }
+
+
+/* -(  Arcanist  )----------------------------------------------------------- */
+
+  public function renderHelpForArcanist() {
+    return '';
+  }
+
+
+/* -(  Context  )------------------------------------------------------------ */
+
+  private $releephProject;
+  private $releephBranch;
+  private $releephRequest;
+  private $user;
+
+  final public function setReleephProject(ReleephProject $rp) {
+    $this->releephProject = $rp;
+    return $this;
+  }
+
+  final public function setReleephBranch(ReleephBranch $rb) {
+    $this->releephRequest = $rb;
+    return $this;
+  }
+
+  final public function setReleephRequest(ReleephRequest $rr) {
+    $this->releephRequest = $rr;
+    return $this;
+  }
+
+  final public function setUser(PhabricatorUser $user) {
+    $this->user = $user;
+    return $this;
+  }
+
+  final public function getReleephProject() {
+    return $this->releephProject;
+  }
+
+  final public function getReleephBranch() {
+    return $this->releephBranch;
+  }
+
+  final public function getReleephRequest() {
+    return $this->releephRequest;
+  }
+
+  final public function getUser() {
+    return $this->user;
+  }
+
+
+/* -(  Bulk loading  )------------------------------------------------------- */
+
+  public function bulkLoad(array $releeph_requests) {
+  }
+
+
+/* -(  Selecting  )---------------------------------------------------------- */
+
+  /**
+   * Append select controls to the given form.
+   *
+   * You are given:
+   *
+   *  - the AphrontFormView to append to;
+   *
+   *  - the AphrontRequest, so you can make use of the value currently selected
+   *    in the form;
+   *
+   *  - $all_releeph_requests: an array of all the ReleephRequests without any
+   *    selection based filtering; and
+   *
+   *  - $all_releeph_requests_without_this_field: an array of ReleephRequests
+   *    that have been selected by all the other select controls on this page.
+   *
+   * The example in ReleephLevelFieldSpecification shows how to use these.
+   * $all_releeph_requests lets you find out all the values of a field in all
+   * ReleephRequests, so you can render controls for every known value.
+   *
+   * $all_releeph_requests_without_this_field lets you count how many
+   * ReleephRequests could be affected by this field's select control, after
+   * all the other fields have made their selections.
+   * ReleephLevelFieldSpecification uses this to render a preview count for
+   * each select button, and disables the button completely (but still renders
+   * it) if it couldn't possibly select anything.
+   */
+  protected function appendSelectControls(
+    AphrontFormView $form,
+    AphrontRequest $request,
+    array $all_releeph_requests,
+    array $all_releeph_requests_without_this_field) {
+
+    return null;
+  }
+
+  /**
+   * Filter the $releeph_requests using the data you set with your form
+   * controls, and which is now available in the provided AphrontRequest.
+   */
+  protected function selectReleephRequests(AphrontRequest $request,
+                                           array &$releeph_requests) {
+    return null;
+  }
+
+  /**
+   * If you have PHIDs that can be used in an AphrontFormTokenizerControl,
+   * return true here, return the PHIDs in getSelectablePHIDs(), and return the
+   * URL the Tokenizer should use for the form control in
+   * getSelectTokenizerDatasource().
+   *
+   * This is a cheap alternative to implementing appendSelectControls() and
+   * selectReleephRequests() in full.
+   */
+  protected function hasSelectablePHIDs() {
+    return false;
+  }
+
+  protected function getSelectablePHIDs() {
+    throw new ReleephFieldSpecificationIncompleteException($this);
+  }
+
+  protected function getSelectTokenizerDatasource() {
+    throw new ReleephFieldSpecificationIncompleteException($this);
+  }
+
+
+/* -(  Commit Messages  )---------------------------------------------------- */
+
+  public function shouldAppearOnCommitMessage() {
+    return false;
+  }
+
+  public function renderLabelForCommitMessage() {
+    throw new ReleephFieldSpecificationIncompleteException($this);
+  }
+
+  public function renderValueForCommitMessage() {
+    throw new ReleephFieldSpecificationIncompleteException($this);
+  }
+
+  public function shouldAppearOnRevertMessage() {
+    return false;
+  }
+
+  public function renderLabelForRevertMessage() {
+    return $this->renderLabelForCommitMessage();
+  }
+
+  public function renderValueForRevertMessage() {
+    return $this->renderValueForCommitMessage();
+  }
+
+
+/* -(  Implementation  )----------------------------------------------------- */
+
+  protected function getRequiredStorageKey() {
+    $key = $this->getStorageKey();
+    if ($key === null) {
+      throw new ReleephFieldSpecificationIncompleteException($this);
+    }
+    if (strpos($key, '.') !== false) {
+      /**
+       * Storage keys are reused for form controls, and periods in form control
+       * names break HTML forms.
+       */
+      throw new Exception(
+        "You can't use '.' in storage keys!");
+    }
+    return $key;
+  }
+
+  /**
+   * The "hook" functions ##appendSelectControlsHook()## and
+   * ##selectReleephRequestsHook()## are used with ##hasSelectablePHIDs()##, to
+   * use the tokenizing helpers if ##hasSelectablePHIDs()## returns true.
+   */
+  public function appendSelectControlsHook(
+    AphrontFormView $form,
+    AphrontRequest $request,
+    array $all_releeph_requests,
+    array $all_releeph_requests_without_this_field) {
+
+    if ($this->hasSelectablePHIDs()) {
+      $this->appendTokenizingSelectControl(
+        $form,
+        $request,
+        $all_releeph_requests,
+        $all_releeph_requests_without_this_field);
+    } else {
+      $this->appendSelectControls(
+        $form,
+        $request,
+        $all_releeph_requests,
+        $all_releeph_requests_without_this_field);
+    }
+  }
+
+  // See above
+  public function selectReleephRequestsHook(AphrontRequest $request,
+                                            array &$releeph_requests) {
+
+    if ($this->hasSelectablePHIDs()) {
+      $this->selectReleephRequestsFromTokens(
+        $request,
+        $releeph_requests);
+    } else {
+      $this->selectReleephRequests(
+        $request,
+        $releeph_requests);
+    }
+  }
+
+  private function appendTokenizingSelectControl(
+    AphrontFormView $form,
+    AphrontRequest $request,
+    array $all_releeph_requests,
+    array $all_releeph_requests_without_this_field) {
+
+    $key = urlencode(strtolower($this->getName()));
+    $selected_phids = $request->getArr($key);
+    $handles = id(new PhabricatorObjectHandleData($selected_phids))
+      ->setViewer($request->getUser())
+      ->loadHandles();
+
+    $tokens = array();
+    foreach ($selected_phids as $phid) {
+      $tokens[$phid] = $handles[$phid]->getFullName();
+    }
+
+    $datasource = $this->getSelectTokenizerDatasource();
+    $control =
+      id(new AphrontFormTokenizerControl())
+        ->setDatasource($datasource)
+        ->setName($key)
+        ->setLabel($this->getName())
+        ->setValue($tokens);
+
+    $form->appendChild($control);
+  }
+
+  private function selectReleephRequestsFromTokens(AphrontRequest $request,
+                                                   array &$releeph_requests) {
+
+    $key = urlencode(strtolower($this->getName()));
+    $selected_phids = $request->getArr($key);
+    if (!$selected_phids) {
+      return;
+    }
+
+    $selected_phid_lookup = array();
+    foreach ($selected_phids as $phid) {
+      $selected_phid_lookup[$phid] = $phid;
+    }
+
+    $filtered = array();
+    foreach ($releeph_requests as $releeph_request) {
+      $rq_phids = $this
+        ->setReleephRequest($releeph_request)
+        ->getSelectablePHIDs();
+      foreach ($rq_phids as $rq_phid) {
+        if (idx($selected_phid_lookup, $rq_phid)) {
+          $filtered[] = $releeph_request;
+          break;
+        }
+      }
+    }
+
+    $releeph_requests = $filtered;
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php b/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php
new file mode 100644
index 000000000..6ba85271c
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephIntentFieldSpecification.php
@@ -0,0 +1,81 @@
+<?php
+
+final class ReleephIntentFieldSpecification
+  extends ReleephFieldSpecification {
+
+  public function getName() {
+    return 'Intent';
+  }
+
+  public function renderValueForHeaderView() {
+    return id(new ReleephRequestIntentsView())
+      ->setReleephRequest($this->getReleephRequest())
+      ->setReleephProject($this->getReleephProject())
+      ->render();
+  }
+
+  public function shouldAppearOnCommitMessage() {
+    return true;
+  }
+
+  public function shouldAppearOnRevertMessage() {
+    return true;
+  }
+
+  public function renderLabelForCommitMessage() {
+    return "Approved By";
+  }
+
+  public function renderLabelForRevertMessage() {
+    return "Rejected By";
+  }
+
+  public function renderValueForCommitMessage() {
+    return $this->renderIntentsForCommitMessage(ReleephRequest::INTENT_WANT);
+  }
+
+  public function renderValueForRevertMessage() {
+    return $this->renderIntentsForCommitMessage(ReleephRequest::INTENT_PASS);
+  }
+
+  private function renderIntentsForCommitMessage($print_intent) {
+    $intents = $this->getReleephRequest()->getUserIntents();
+
+    $requestor = $this->getReleephRequest()->getRequestUserPHID();
+    $pusher_phids = $this->getReleephProject()->getPushers();
+
+    $phids = array_unique($pusher_phids + array_keys($intents));
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      ->setViewer($this->getUser())
+      ->loadHandles();
+
+    $tokens = array();
+    foreach ($phids as $phid) {
+      $intent = idx($intents, $phid);
+      if ($intent == $print_intent) {
+        $name = $handles[$phid]->getName();
+        $is_pusher = in_array($phid, $pusher_phids);
+        $is_requestor = $phid == $requestor;
+
+        if ($is_pusher) {
+          if ($is_requestor) {
+            $token = "{$name} (pusher and requestor)";
+          } else {
+            $token = "{$name} (pusher)";
+          }
+        } else {
+          if ($is_requestor) {
+            $token = "{$name} (requestor)";
+          } else {
+            $token = $name;
+          }
+        }
+
+        $tokens[] = $token;
+      }
+    }
+
+    return implode(', ', $tokens);
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephLevelFieldSpecification.php b/src/applications/releeph/field/specification/ReleephLevelFieldSpecification.php
new file mode 100644
index 000000000..e1866d24b
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephLevelFieldSpecification.php
@@ -0,0 +1,228 @@
+<?php
+
+/**
+ * Provides a convenient field for storing a set of levels that you can use to
+ * filter requests on.
+ *
+ * Levels are rendered with names and descriptions in the edit UI, and are
+ * automatically documented via the "arc request" interface.
+ *
+ * See ReleephSeverityFieldSpecification for an example.
+ */
+abstract class ReleephLevelFieldSpecification
+  extends ReleephFieldSpecification {
+
+  private $error;
+
+  abstract public function getLevels();
+  abstract public function getDefaultLevel();
+  abstract public function getNameForLevel($level);
+  abstract public function getDescriptionForLevel($level);
+
+  /**
+   * Use getCanonicalLevel() to convert old, unsupported levels to new ones.
+   */
+  protected function getCanonicalLevel($misc_level) {
+    return $misc_level;
+  }
+
+  public function getStorageKey() {
+    $class = get_class($this);
+    throw new ReleephFieldSpecificationIncompleteException(
+      $this,
+      "You must implement getStorageKey() for children of {$class}!");
+  }
+
+  public function renderValueForHeaderView() {
+    $raw_level = $this->getValue();
+    $level = $this->getCanonicalLevel($raw_level);
+    return $this->getNameForLevel($level);
+  }
+
+  public function renderEditControl(AphrontRequest $request) {
+    $control_name = $this->getRequiredStorageKey();
+    $all_levels = $this->getLevels();
+
+    $level = $request->getStr($control_name);
+
+    if (!$level) {
+      $level = $this->getCanonicalLevel($this->getValue());
+    }
+
+    if (!$level) {
+      $level = $this->getDefaultLevel();
+    }
+
+    $control = id(new AphrontFormRadioButtonControl())
+      ->setLabel('Level')
+      ->setName($control_name)
+      ->setValue($level);
+
+    if ($this->error) {
+      $control->setError($this->error);
+    } elseif ($this->getDefaultLevel()) {
+      $control->setError(true);
+    }
+
+    foreach ($all_levels as $level) {
+      $name = $this->getNameForLevel($level);
+      $description = $this->getDescriptionForLevel($level);
+      $control->addButton($level, $name, $description);
+    }
+
+    return $control;
+  }
+
+  public function renderHelpForArcanist() {
+    $text = '';
+    $levels = $this->getLevels();
+    $default = $this->getDefaultLevel();
+    foreach ($levels as $level) {
+      $name = $this->getNameForLevel($level);
+      $description = $this->getDescriptionForLevel($level);
+      $default_marker = ' ';
+      if ($level === $default) {
+        $default_marker = '*';
+      }
+      $text .= "    {$default_marker} **{$name}**\n";
+      $text .= phutil_console_wrap($description."\n", 8);
+    }
+    return $text;
+  }
+
+  public function validate($value) {
+    if ($value === null) {
+      $this->error = 'Required';
+      $label = $this->getName();
+      throw new ReleephFieldParseException(
+        $this,
+        "You must provide a {$label} level");
+    }
+
+    $levels = $this->getLevels();
+    if (!in_array($value, $levels)) {
+      $label = $this->getName();
+      throw new ReleephFieldParseException(
+        $this,
+        "Level '{$value}' is not a valid {$label} level in this project.");
+    }
+  }
+
+  public function setValueFromConduitAPIRequest(ConduitAPIRequest $request) {
+    $key = $this->getRequiredStorageKey();
+    $label = $this->getName();
+    $name = idx($request->getValue('fields', array()), $key);
+
+    if (!$name) {
+      $level = $this->getDefaultLevel();
+      if (!$level) {
+        throw new ReleephFieldParseException(
+          $this,
+          "No value given for {$label}, ".
+          "and no default is given for this level!");
+      }
+    } else {
+      $level = $this->getLevelByName($name);
+    }
+
+    if (!$level) {
+      throw new ReleephFieldParseException(
+        $this,
+        "Unknown {$label} level name '{$name}'");
+    }
+    $this->setValue($level);
+  }
+
+  private $nameMap = array();
+
+  public function getLevelByName($name) {
+    // Build this once
+    if (!$this->nameMap) {
+      foreach ($this->getLevels() as $level) {
+        $level_name = $this->getNameForLevel($level);
+        $this->nameMap[$level_name] = $level;
+      }
+    }
+    return idx($this->nameMap, $name);
+  }
+
+  protected function appendSelectControls(
+    AphrontFormView $form,
+    AphrontRequest $request,
+    array $all_releeph_requests,
+    array $all_releeph_requests_without_this_field) {
+
+    $buttons = array(null => 'All');
+
+    // Add in known level/names
+    foreach ($this->getLevels() as $level) {
+      $name = $this->getNameForLevel($level);
+      $buttons[$name] = $name;
+    }
+
+    // Add in any names we've seen in the wild, as well.
+    foreach ($all_releeph_requests as $releeph_request) {
+      $raw_level = $this->setReleephRequest($releeph_request)->getValue();
+      if (!$raw_level) {
+        // The ReleephRequest might not have a level set
+        continue;
+      }
+      $level = $this->getCanonicalLevel($raw_level);
+      $name = $this->getNameForLevel($level);
+      $buttons[$name] = $name;
+    }
+
+    $key = $this->getRequiredStorageKey();
+    $current = $request->getStr($key);
+
+    $counters = array(null => count($all_releeph_requests_without_this_field));
+    foreach ($all_releeph_requests_without_this_field as $releeph_request) {
+      $raw_level = $this->setReleephRequest($releeph_request)->getValue();
+      if (!$raw_level) {
+        // The ReleephRequest might not have a level set
+        continue;
+      }
+      $level = $this->getCanonicalLevel($raw_level);
+      $name = $this->getNameForLevel($level);
+
+      if (!isset($counters[$name])) {
+        $counters[$name] = 0;
+      }
+      $counters[$name]++;
+    }
+
+    $control = id(new AphrontFormCountedToggleButtonsControl())
+      ->setLabel($this->getName())
+      ->setValue($current)
+      ->setBaseURI($request->getRequestURI(), $key)
+      ->setButtons($buttons)
+      ->setCounters($counters);
+
+    $form
+      ->appendChild($control)
+      ->addHiddenInput($key, $current);
+  }
+
+  protected function selectReleephRequests(AphrontRequest $request,
+                                           array &$releeph_requests) {
+    $key = $this->getRequiredStorageKey();
+    $current = $request->getStr($key);
+
+    if (!$current) {
+      return;
+    }
+
+    $filtered = array();
+    foreach ($releeph_requests as $releeph_request) {
+      $raw_level = $this->setReleephRequest($releeph_request)->getValue();
+      $level = $this->getCanonicalLevel($raw_level);
+      $name = $this->getNameForLevel($level);
+      if ($name == $current) {
+        $filtered[] = $releeph_request;
+      }
+    }
+
+    $releeph_requests = $filtered;
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php b/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php
new file mode 100644
index 000000000..3f4ec6ae1
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephOriginalCommitFieldSpecification.php
@@ -0,0 +1,16 @@
+<?php
+
+final class ReleephOriginalCommitFieldSpecification
+  extends ReleephFieldSpecification {
+
+  public function getName() {
+    return 'Commit';
+  }
+
+  public function renderValueForHeaderView() {
+    $rr = $this->getReleephRequest();
+    $handles = $rr->getHandles();
+    return $handles[$rr->getRequestCommitPHID()]->renderLink();
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php b/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php
new file mode 100644
index 000000000..7b805cd49
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephReasonFieldSpecification.php
@@ -0,0 +1,78 @@
+<?php
+
+final class ReleephReasonFieldSpecification
+  extends ReleephFieldSpecification {
+
+  public function getName() {
+    return 'Reason';
+  }
+
+  public function getStorageKey() {
+    return 'reason';
+  }
+
+  public function renderLabelForHeaderView() {
+    return null;
+  }
+
+  public function renderValueForHeaderView() {
+    $reason = $this->getValue();
+    if (!$reason) {
+      return '';
+    }
+
+    $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
+    $engine->setConfig('viewer', $this->getUser());
+    $markup = phutil_tag(
+      'div',
+      array(
+        'class' => 'phabricator-remarkup',
+      ),
+      $engine->markupText($reason));
+
+    return id(new AphrontNoteView())
+      ->setTitle('Reason')
+      ->appendChild($markup)
+      ->render();
+  }
+
+  private $error = true;
+
+  public function renderEditControl(AphrontRequest $request) {
+    $reason = $request->getStr('reason', $this->getValue());
+    return id(new AphrontFormTextAreaControl())
+      ->setLabel('Reason')
+      ->setName('reason')
+      ->setError($this->error)
+      ->setValue($reason);
+  }
+
+  public function validate($reason) {
+    if (!$reason) {
+      $this->error = 'Required';
+      throw new ReleephFieldParseException(
+        $this,
+        "You must give a reason for your request.");
+    }
+  }
+
+  public function renderHelpForArcanist() {
+    $text =
+      "Fully explain why you are requesting this code be included ".
+      "in the next release.\n";
+    return phutil_console_wrap($text, 8);
+  }
+
+  public function shouldAppearOnCommitMessage() {
+    return true;
+  }
+
+  public function renderLabelForCommitMessage() {
+    return 'Request Reason';
+  }
+
+  public function renderValueForCommitMessage() {
+    return $this->getValue();
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephRequestorFieldSpecification.php b/src/applications/releeph/field/specification/ReleephRequestorFieldSpecification.php
new file mode 100644
index 000000000..aed8b0186
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephRequestorFieldSpecification.php
@@ -0,0 +1,59 @@
+<?php
+
+final class ReleephRequestorFieldSpecification
+  extends ReleephFieldSpecification {
+
+  public function bulkLoad(array $releeph_requests) {
+    $phids = mpull($releeph_requests, 'getRequestUserPHID');
+    ReleephUserView::getNewInstance()
+      ->setUser($this->getUser())
+      ->setReleephProject($this->getReleephProject())
+      ->load($phids);
+  }
+
+  public function getName() {
+    return 'Requestor';
+  }
+
+  public function renderValueForHeaderView() {
+    $phid = $this->getReleephRequest()->getRequestUserPHID();
+    return ReleephUserView::getNewInstance()
+      ->setRenderUserPHID($phid)
+      ->render();
+  }
+
+  public function hasSelectablePHIDs() {
+    return true;
+  }
+
+  public function getSelectTokenizerDatasource() {
+    return '/typeahead/common/users/';
+  }
+
+  public function getSelectablePHIDs() {
+    return array(
+      $this->getReleephRequest()->getRequestUserPHID(),
+    );
+  }
+
+  public function shouldAppearOnCommitMessage() {
+    return true;
+  }
+
+  public function shouldAppearOnRevertMessage() {
+    return true;
+  }
+
+  public function renderLabelForCommitMessage() {
+    return "Requested By";
+  }
+
+  public function renderValueForCommitMessage() {
+    $phid = $this->getReleephRequest()->getRequestUserPHID();
+    $handles = id(new PhabricatorObjectHandleData(array($phid)))
+      ->setViewer($this->getUser())
+      ->loadHandles();
+    return $handles[$phid]->getName();
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephRevisionFieldSpecification.php b/src/applications/releeph/field/specification/ReleephRevisionFieldSpecification.php
new file mode 100644
index 000000000..80b0d0f99
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephRevisionFieldSpecification.php
@@ -0,0 +1,37 @@
+<?php
+
+final class ReleephRevisionFieldSpecification
+  extends ReleephFieldSpecification {
+
+  public function getName() {
+    return 'Revision';
+  }
+
+  public function renderValueForHeaderView() {
+    $data = $this
+      ->getReleephRequest()
+      ->loadPhabricatorRepositoryCommitData();
+    if (!$data) {
+      return null;
+    }
+
+    $phid = $data->getCommitDetail('differential.revisionPHID');
+    if (!$phid) {
+      return null;
+    }
+
+    $handles = $this->getReleephRequest()->getHandles();
+    $handle = $handles[$phid];
+    $link = $handle
+      // Hack to remove the strike-through rendering of diff links
+      ->setStatus(null)
+      ->renderLink();
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'releeph-header-text-truncated',
+      ),
+      $link);
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephRiskFieldSpecification.php b/src/applications/releeph/field/specification/ReleephRiskFieldSpecification.php
new file mode 100644
index 000000000..7ab3a33a1
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephRiskFieldSpecification.php
@@ -0,0 +1,63 @@
+<?php
+
+final class ReleephRiskFieldSpecification
+  extends ReleephFieldSpecification {
+
+  static $defaultRisks = array(
+    'NONE'  => 'Completely safe to pick this request.',
+    'SOME'  => 'There is some risk this could break things, but not much.',
+    'HIGH'  => 'This is pretty risky, but is also very important.',
+  );
+
+  public function getName() {
+    return 'Riskiness';
+  }
+
+  public function getStorageKey() {
+    return 'risk';
+  }
+
+  public function renderLabelForHeaderView() {
+    return 'Riskiness';
+  }
+
+  private $error = true;
+
+  public function renderEditControl(AphrontRequest $request) {
+    $value = $request->getStr('risk', $this->getValue());
+    $buttons = id(new AphrontFormRadioButtonControl())
+      ->setLabel('Riskiness')
+      ->setName('risk')
+      ->setError($this->error)
+      ->setValue($value);
+    foreach (self::$defaultRisks as $value => $description) {
+      $buttons->addButton($value, $value, $description);
+    }
+    return $buttons;
+  }
+
+  public function validate($risk) {
+    if (!$risk) {
+      $this->error = 'Required';
+      throw new ReleephFieldParseException(
+        $this,
+        "No risk was given, which probably means we've changed the set ".
+        "of valid risks since you made this request.  Please pick one.");
+    }
+    if (!idx(self::$defaultRisks, $risk)) {
+      throw new ReleephFieldParseException(
+        $this,
+        "Unknown risk '{$risk}'.");
+    }
+  }
+
+  public function renderHelpForArcanist() {
+    $help = '';
+    foreach (self::$defaultRisks as $name => $description) {
+      $help .= "      **{$name}**\n";
+      $help .= phutil_console_wrap($description."\n", 8);
+    }
+    return $help;
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephSeverityFieldSpecification.php b/src/applications/releeph/field/specification/ReleephSeverityFieldSpecification.php
new file mode 100644
index 000000000..9b362cbfd
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephSeverityFieldSpecification.php
@@ -0,0 +1,46 @@
+<?php
+
+final class ReleephSeverityFieldSpecification
+  extends ReleephLevelFieldSpecification {
+
+  const HOTFIX  = 'HOTFIX';
+  const RELEASE = 'RELEASE';
+
+  public function getName() {
+    return 'Severity';
+  }
+
+  public function getStorageKey() {
+    return 'releeph:severity';
+  }
+
+  public function getLevels() {
+    return array(
+      self::HOTFIX,
+      self::RELEASE,
+    );
+  }
+
+  public function getDefaultLevel() {
+    return self::RELEASE;
+  }
+
+  public function getNameForLevel($level) {
+    static $names = array(
+      self::HOTFIX  => 'HOTFIX',
+      self::RELEASE => 'RELEASE',
+    );
+    return idx($names, $level, $level);
+  }
+
+  public function getDescriptionForLevel($level) {
+    static $descriptions = array(
+      self::HOTFIX =>
+        'Needs merging and fixing right now.',
+      self::RELEASE =>
+        'Required for the currently rolling release.',
+    );
+    return idx($descriptions, $level);
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php b/src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php
new file mode 100644
index 000000000..202e5aba8
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephStatusFieldSpecification.php
@@ -0,0 +1,89 @@
+<?php
+
+final class ReleephStatusFieldSpecification
+  extends ReleephFieldSpecification {
+
+  public function getName() {
+    return 'Status';
+  }
+
+  public function renderValueForHeaderView() {
+    return id(new ReleephRequestStatusView())
+      ->setReleephRequest($this->getReleephRequest())
+      ->render();
+  }
+
+  private static $filters = array(
+    'req' => ReleephRequest::STATUS_REQUESTED,
+    'app' => ReleephRequest::STATUS_NEEDS_PICK,
+    'rej' => ReleephRequest::STATUS_REJECTED,
+    'abn' => ReleephRequest::STATUS_ABANDONED,
+    'mer' => ReleephRequest::STATUS_PICKED,
+    'rrq' => ReleephRequest::STATUS_NEEDS_REVERT,
+    'rev' => ReleephRequest::STATUS_REVERTED,
+  );
+
+  protected function appendSelectControls(
+    AphrontFormView $form,
+    AphrontRequest $request,
+    array $all_releeph_requests,
+    array $all_releeph_requests_without_this_field) {
+
+    $filter_names = array(
+      null => 'All',
+    );
+
+    foreach (self::$filters as $code => $status) {
+      $name = ReleephRequest::getStatusDescriptionFor($status);
+      $filter_names[$code] = $name;
+    }
+
+    $key = 'status';
+    $code = $request->getStr($key);
+    $current_status = idx(self::$filters, $code);
+
+    $codes = array_flip(self::$filters);
+
+    $counters = array(null => count($all_releeph_requests_without_this_field));
+    foreach ($all_releeph_requests_without_this_field as $releeph_request) {
+      $this_status = $releeph_request->getStatus();
+      $this_code = idx($codes, $this_status);
+      if (!isset($counters[$this_code])) {
+        $counters[$this_code] = 0;
+      }
+      $counters[$this_code]++;
+    }
+
+    $control = id(new AphrontFormCountedToggleButtonsControl())
+      ->setLabel($this->getName())
+      ->setValue($code)
+      ->setBaseURI($request->getRequestURI(), $key)
+      ->setButtons($filter_names)
+      ->setCounters($counters);
+
+    $form
+      ->appendChild($control)
+      ->addHiddenInput($key, $code);
+  }
+
+  protected function selectReleephRequests(AphrontRequest $request,
+                                           array &$releeph_requests) {
+
+    $key = 'status';
+    $code = $request->getStr($key);
+    if (!$code) {
+      return;
+    }
+
+    $current_status = idx(self::$filters, $code);
+
+    $filtered = array();
+    foreach ($releeph_requests as $releeph_request) {
+      if ($releeph_request->getStatus() == $current_status) {
+        $filtered[] = $releeph_request;
+      }
+    }
+    $releeph_requests = $filtered;
+  }
+
+}
diff --git a/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php b/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php
new file mode 100644
index 000000000..7ff398604
--- /dev/null
+++ b/src/applications/releeph/field/specification/ReleephSummaryFieldSpecification.php
@@ -0,0 +1,46 @@
+<?php
+
+final class ReleephSummaryFieldSpecification
+  extends ReleephFieldSpecification {
+
+  const MAX_SUMMARY_LENGTH = 60;
+
+  public function getName() {
+    return 'Summary';
+  }
+
+  public function getStorageKey() {
+    return 'summary';
+  }
+
+  private $error = false;
+
+  public function renderEditControl(AphrontRequest $request) {
+    $summary = $request->getStr('summary', $this->getValue());
+    return id(new AphrontFormTextControl())
+      ->setLabel('Summary')
+      ->setName('summary')
+      ->setError($this->error)
+      ->setValue($summary)
+      ->setCaption(
+        'Leave this blank to use the original commit title');
+  }
+
+  public function renderHelpForArcanist() {
+    $text =
+      "A one-line title summarizing this request. ".
+      "Leave blank to use the original commit title.\n";
+    return phutil_console_wrap($text, 8);
+  }
+
+  public function validate($summary) {
+    if ($summary && strlen($summary) > self::MAX_SUMMARY_LENGTH) {
+      $this->error = 'Too long!';
+      throw new ReleephFieldParseException(
+        $this, sprintf(
+          'Please keep your summary to under %d characters.',
+          self::MAX_SUMMARY_LENGTH));
+    }
+  }
+
+}
diff --git a/src/applications/releeph/storage/ReleephBranch.php b/src/applications/releeph/storage/ReleephBranch.php
new file mode 100644
index 000000000..904cb3076
--- /dev/null
+++ b/src/applications/releeph/storage/ReleephBranch.php
@@ -0,0 +1,154 @@
+<?php
+
+final class ReleephBranch extends ReleephDAO {
+
+  protected $phid;
+  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 $cutPointCommitIdentifier;
+  protected $cutPointCommitPHID;
+
+  protected $details = array();
+
+  public function getConfiguration() {
+    return array(
+      self::CONFIG_AUX_PHID => true,
+      self::CONFIG_SERIALIZATION => array(
+        'details' => self::SERIALIZATION_JSON,
+      ),
+    ) + parent::getConfiguration();
+  }
+
+  public function generatePHID() {
+    return PhabricatorPHID::generateNewPHID(
+      ReleephPHIDConstants::PHID_TYPE_REBR);
+  }
+
+  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',
+      rawurlencode($this->loadReleephProject()->getName()),
+      rawurlencode($this->getBasename()),
+      $path
+    );
+    return PhabricatorEnv::getProductionURI(implode('/', $components));
+  }
+
+  public function loadReleephProject() {
+    return $this->loadOneRelative(
+      new ReleephProject(),
+      'id',
+      'getReleephProjectID');
+  }
+
+  private function loadReleephRequestHandles(PhabricatorUser $user, $reqs) {
+    $phids_to_phetch = array();
+    foreach ($reqs as $rr) {
+      $phids_to_phetch[] = $rr->getRequestCommitPHID();
+      $phids_to_phetch[] = $rr->getRequestUserPHID();
+      $phids_to_phetch[] = $rr->getCommitPHID();
+
+      $intents = $rr->getUserIntents();
+      if ($intents) {
+        foreach ($intents as $user_phid => $intent) {
+          $phids_to_phetch[] = $user_phid;
+        }
+      }
+
+      $request_commit = $rr->loadPhabricatorRepositoryCommit();
+      if ($request_commit) {
+        $phids_to_phetch[] = $request_commit->getAuthorPHID();
+        $phids_to_phetch[] = $rr->loadRequestCommitDiffPHID();
+      }
+    }
+    $handles = id(new PhabricatorObjectHandleData($phids_to_phetch))
+      ->setViewer($user)
+      ->loadHandles();
+    return $handles;
+  }
+
+  public function populateReleephRequestHandles(PhabricatorUser $user, $reqs) {
+    $handles = $this->loadReleephRequestHandles($user, $reqs);
+    foreach ($reqs as $req) {
+      $req->setHandles($handles);
+    }
+  }
+
+  public function loadReleephRequests(PhabricatorUser $user) {
+    $reqs = $this->loadRelatives(new ReleephRequest(), 'branchID');
+    $this->populateReleephRequestHandles($user, $reqs);
+    return $reqs;
+  }
+
+  public function isActive() {
+    return $this->getIsActive();
+  }
+
+}
diff --git a/src/applications/releeph/storage/ReleephDAO.php b/src/applications/releeph/storage/ReleephDAO.php
new file mode 100644
index 000000000..638e16a73
--- /dev/null
+++ b/src/applications/releeph/storage/ReleephDAO.php
@@ -0,0 +1,9 @@
+<?php
+
+abstract class ReleephDAO extends PhabricatorLiskDAO {
+
+  public function getApplicationName() {
+    return 'releeph';
+  }
+
+}
diff --git a/src/applications/releeph/storage/ReleephProject.php b/src/applications/releeph/storage/ReleephProject.php
new file mode 100644
index 000000000..1337340da
--- /dev/null
+++ b/src/applications/releeph/storage/ReleephProject.php
@@ -0,0 +1,176 @@
+<?php
+
+final class ReleephProject extends ReleephDAO {
+
+  const DEFAULT_BRANCH_NAMESPACE = 'releeph-releases';
+  const SYSTEM_AGENT_USERNAME_PREFIX = 'releeph-agent-';
+
+  const COMMIT_AUTHOR_NONE      = 'commit-author-none';
+  const COMMIT_AUTHOR_FROM_DIFF = 'commit-author-is-from-diff';
+  const COMMIT_AUTHOR_REQUESTOR = 'commit-author-is-requestor';
+
+  protected $phid;
+  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 $repositoryID;
+  protected $repositoryPHID;
+  protected $isActive;
+  protected $createdByUserPHID;
+  protected $arcanistProjectID;
+  protected $projectID;
+
+  protected $details = array();
+
+  public function getConfiguration() {
+    return array(
+      self::CONFIG_AUX_PHID => true,
+      self::CONFIG_SERIALIZATION => array(
+        'details' => self::SERIALIZATION_JSON,
+      ),
+    ) + parent::getConfiguration();
+  }
+
+  public function generatePHID() {
+    return PhabricatorPHID::generateNewPHID(
+      ReleephPHIDConstants::PHID_TYPE_REPR);
+  }
+
+  public function getDetail($key, $default = null) {
+    return idx($this->details, $key, $default);
+  }
+
+  public function getURI($path = null) {
+    $components = array(
+      '/releeph/project',
+      $this->getID(),
+      $path
+    );
+    return PhabricatorEnv::getProductionURI(implode('/', $components));
+  }
+
+  public function setDetail($key, $value) {
+    $this->details[$key] = $value;
+    return $this;
+  }
+
+  public function willSaveObject() {
+    // Do this first, to generate the PHID
+    parent::willSaveObject();
+
+    $banned_names = $this->getBannedNames();
+    if (in_array($this->name, $banned_names)) {
+      throw new Exception(sprintf(
+        "The name '%s' is in the list of banned project names!",
+        $this->name,
+        implode(', ', $banned_names)));
+    }
+
+    if (!$this->getDetail('releaseCounter')) {
+      $this->setDetail('releaseCounter', 0);
+    }
+  }
+
+  public function loadPhabricatorProject() {
+    if ($id = $this->getProjectID()) {
+      return id(new PhabricatorProject())->load($id);
+    }
+    return id(new PhabricatorProject())->makeEphemeral(); // dummy
+  }
+
+  public function loadArcanistProject() {
+    return $this->loadOneRelative(
+      new PhabricatorRepositoryArcanistProject(),
+      'id',
+      'getArcanistProjectID');
+  }
+
+  public function getPushers() {
+    return $this->getDetail('pushers', array());
+  }
+
+  public function isPusherPHID($phid) {
+    $pusher_phids = $this->getDetail('pushers', array());
+    return in_array($phid, $pusher_phids);
+  }
+
+  public function isPusher(PhabricatorUser $user) {
+    return $this->isPusherPHID($user->getPHID());
+  }
+
+  public function loadPhabricatorRepository() {
+    return $this->loadOneRelative(
+      new PhabricatorRepository(),
+      'id',
+      'getRepositoryID');
+  }
+
+  public function getCurrentReleaseNumber() {
+    $current_release_numbers = array();
+
+    // From the project...
+    $current_release_numbers[] = $this->getDetail('releaseCounter', 0);
+
+    // From any branches...
+    $branches = id(new ReleephBranch())->loadAllWhere(
+      'releephProjectID = %d', $this->getID());
+    if ($branches) {
+      $release_numbers = array();
+      foreach ($branches as $branch) {
+        $current_release_numbers[] = $branch->getDetail('releaseNumber', 0);
+      }
+    }
+
+    return max($current_release_numbers);
+  }
+
+  public function getReleephFieldSelector() {
+    $class = $this->getDetail('field_selector');
+    if (!$class) {
+      $key = 'releeph.field-selector';
+      $class = PhabricatorEnv::getEnvConfig($key);
+    }
+
+    if ($class) {
+      return newv($class, array());
+    } else {
+      return new ReleephDefaultFieldSelector();
+    }
+  }
+
+  /**
+   * Wrapper to setIsActive() that logs who deactivated a project
+   */
+  public function deactivate(PhabricatorUser $actor) {
+    return $this
+      ->setIsActive(0)
+      ->setDetail('last_deactivated_user', $actor->getPHID())
+      ->setDetail('last_deactivated_time', time());
+  }
+
+  // Hide this from the public
+  private function setIsActive($v) {
+    return parent::setIsActive($v);
+  }
+
+  private function getBannedNames() {
+    return array(
+      'branch', // no one's tried this... yet!
+    );
+  }
+
+  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;
+  }
+}
diff --git a/src/applications/releeph/storage/ReleephRequest.php b/src/applications/releeph/storage/ReleephRequest.php
new file mode 100644
index 000000000..d7bb01304
--- /dev/null
+++ b/src/applications/releeph/storage/ReleephRequest.php
@@ -0,0 +1,309 @@
+<?php
+
+final class ReleephRequest extends ReleephDAO {
+
+  protected $phid;
+  protected $branchID;
+  protected $requestUserPHID;
+  protected $details = array();
+  protected $userIntents = array();
+  protected $inBranch;
+  protected $pickStatus;
+
+  // Information about the thing being requested
+  protected $requestCommitIdentifier;
+  protected $requestCommitPHID;
+  protected $requestCommitOrdinal;
+
+  // Information about the last commit to the releeph branch
+  protected $commitIdentifier;
+  protected $committedByUserPHID;
+  protected $commitPHID;
+
+  // Pre-populated handles that we'll bulk load in ReleephBranch
+  private $handles;
+
+
+/* -(  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;
+
+  const STATUS_REQUESTED       = 1;
+  const STATUS_NEEDS_PICK      = 2;  // aka approved
+  const STATUS_REJECTED        = 3;
+  const STATUS_ABANDONED       = 4;
+  const STATUS_PICKED          = 5;
+  const STATUS_REVERTED        = 6;
+  const STATUS_NEEDS_REVERT    = 7;  // aka revert requested
+
+  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() {
+    $project = $this->loadReleephProject();
+    if (!$project->getPushers()) {
+      return self::INTENT_WANT;
+    }
+
+    $found_pusher_want = false;
+    foreach ($this->userIntents as $phid => $intent) {
+      if ($project->isPusherPHID($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();
+  }
+
+  private function calculateStatus() {
+    if ($this->shouldBeInBranch()) {
+      if ($this->getInBranch()) {
+        return self::STATUS_PICKED;
+      } else {
+        return self::STATUS_NEEDS_PICK;
+      }
+    } else {
+      if ($this->getInBranch()) {
+        return self::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 self::STATUS_REVERTED;
+        } elseif ($this->getPusherIntent() === ReleephRequest::INTENT_PASS) {
+          // Otherwise, if it has never been in the branch, explicitly say why:
+          return self::STATUS_REJECTED;
+        } elseif ($this->getRequestorIntent() === ReleephRequest::INTENT_WANT) {
+          return self::STATUS_REQUESTED;
+        } else {
+          return self::STATUS_ABANDONED;
+        }
+      }
+    }
+  }
+
+  public static function getStatusDescriptionFor($status) {
+    static $descriptions = array(
+      self::STATUS_REQUESTED       => 'Requested',
+      self::STATUS_REJECTED        => 'Rejected',
+      self::STATUS_ABANDONED       => 'Abandoned',
+      self::STATUS_PICKED          => 'Picked',
+      self::STATUS_REVERTED        => 'Reverted',
+      self::STATUS_NEEDS_PICK      => 'Needs Pick',
+      self::STATUS_NEEDS_REVERT    => 'Needs Revert',
+    );
+    return idx($descriptions, $status, '??');
+  }
+
+  public static function getStatusClassSuffixFor($status) {
+    $description = self::getStatusDescriptionFor($status);
+    $class = str_replace(' ', '-', strtolower($description));
+    return $class;
+  }
+
+
+/* -(  Lisk mechanics  )----------------------------------------------------- */
+
+  public function getConfiguration() {
+    return array(
+      self::CONFIG_AUX_PHID => true,
+      self::CONFIG_SERIALIZATION => array(
+        'details' => self::SERIALIZATION_JSON,
+        'userIntents' => self::SERIALIZATION_JSON,
+      ),
+    ) + parent::getConfiguration();
+  }
+
+  public function generatePHID() {
+    return PhabricatorPHID::generateNewPHID(
+      ReleephPHIDConstants::PHID_TYPE_RERQ);
+  }
+
+
+/* -(  Helpful accessors )--------------------------------------------------- */
+
+  public function setHandles($handles) {
+    $this->handles = $handles;
+    return $this;
+  }
+
+  public function getHandles() {
+    if (!$this->handles) {
+      throw new Exception(
+        "You must call ReleephBranch::populateReleephRequestHandles() first");
+    }
+    return $this->handles;
+  }
+
+  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 getReason() {
+    // Backward compatibility: reason used to be called comments
+    $reason = $this->getDetail('reason');
+    if (!$reason) {
+      return $this->getDetail('comments');
+    }
+    return $reason;
+  }
+
+  public function getSummary() {
+    /**
+     * Instead, you can use:
+     *  - getDetail('summary')    // the actual user-chosen summary
+     *  - getSummaryForDisplay()  // falls back to the original commit title
+     *
+     * Or for the fastidious:
+     *  - id(new ReleephSummaryFieldSpecification())
+     *      ->setReleephRequest($rr)
+     *      ->getValue()          // programmatic equivalent to getDetail()
+     */
+    throw new Exception(
+      "getSummary() has been deprecated!");
+  }
+
+  /**
+   * Allow a null summary, and fall back to the title of the commit.
+   */
+  public function getSummaryForDisplay() {
+    $summary = $this->getDetail('summary');
+
+    if (!$summary) {
+      $pr_commit_data = $this->loadPhabricatorRepositoryCommitData();
+      if ($pr_commit_data) {
+        $message_lines = explode("\n", $pr_commit_data->getCommitMessage());
+        $message_lines = array_filter($message_lines);
+        $summary = head($message_lines);
+      }
+    }
+
+    if (!$summary) {
+      $summary = '(no summary given and commit message empty or unparsed)';
+    }
+
+    return $summary;
+  }
+
+  public function loadRequestCommitDiffPHID() {
+    $commit_data = $this->loadPhabricatorRepositoryCommitData();
+    if (!$commit_data) {
+      return null;
+    }
+    return $commit_data->getCommitDetail('differential.revisionPHID');
+  }
+
+
+/* -(  Loading external objects  )------------------------------------------- */
+
+  public function loadReleephBranch() {
+    return $this->loadOneRelative(
+      new ReleephBranch(),
+      'id',
+      'getBranchID');
+  }
+
+  public function loadReleephProject() {
+    return $this->loadReleephBranch()->loadReleephProject();
+  }
+
+  public function loadEvents() {
+    return $this->loadRelatives(
+      new ReleephRequestEvent(),
+      'releephRequestID',
+      'getID',
+      '(1 = 1) ORDER BY dateCreated, id');
+  }
+
+  public function loadPhabricatorRepositoryCommit() {
+    return $this->loadOneRelative(
+      new PhabricatorRepositoryCommit(),
+      'phid',
+      'getRequestCommitPHID');
+  }
+
+  public function loadPhabricatorRepositoryCommitData() {
+    return $this->loadOneRelative(
+      new PhabricatorRepositoryCommitData(),
+      'commitID',
+      'getRequestCommitOrdinal');
+  }
+
+  public function loadDifferentialRevision() {
+    return $this->loadOneRelative(
+        new DifferentialRevision(),
+        'phid',
+        'loadRequestCommitDiffPHID');
+  }
+
+
+/* -(  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);
+  }
+
+}
diff --git a/src/applications/releeph/storage/event/ReleephEvent.php b/src/applications/releeph/storage/event/ReleephEvent.php
new file mode 100644
index 000000000..e3333ec4e
--- /dev/null
+++ b/src/applications/releeph/storage/event/ReleephEvent.php
@@ -0,0 +1,39 @@
+<?php
+
+final class ReleephEvent extends ReleephDAO {
+
+  const TYPE_BRANCH_CREATE = 'branch-create';
+  const TYPE_BRANCH_ACCESS = 'branch-access-change';
+
+  protected $releephProjectID;
+  protected $releephBranchID;
+  protected $type;
+  protected $epoch;
+  protected $actorPHID;
+  protected $details = array();
+
+  public function getConfiguration() {
+    return array(
+      self::CONFIG_SERIALIZATION => array(
+        'details' => self::SERIALIZATION_JSON,
+      ),
+    ) + parent::getConfiguration();
+  }
+
+  public function getDetail($key, $default = null) {
+    return idx($this->details, $key, $default);
+  }
+
+  public function setDetail($key, $value) {
+    $this->details[$key] = $value;
+    return $this;
+  }
+
+  protected function willSaveObject() {
+    parent::willSaveObject();
+    if (!$this->epoch) {
+      $this->epoch = $this->dateCreated;
+    }
+  }
+
+}
diff --git a/src/applications/releeph/storage/request/ReleephRequestEvent.php b/src/applications/releeph/storage/request/ReleephRequestEvent.php
new file mode 100644
index 000000000..b427516d4
--- /dev/null
+++ b/src/applications/releeph/storage/request/ReleephRequestEvent.php
@@ -0,0 +1,94 @@
+<?php
+
+final class ReleephRequestEvent extends ReleephDAO {
+
+  const TYPE_CREATE         = 'create';
+  const TYPE_STATUS         = 'status'; // old events
+  const TYPE_USER_INTENT    = 'user-intent';
+  const TYPE_PICK_STATUS    = 'pick-status';
+  const TYPE_COMMIT         = 'commit';
+  const TYPE_MANUAL_ACTION  = 'manual-action';
+  const TYPE_DISCOVERY      = 'discovery';
+  const TYPE_COMMENT        = 'comment';
+
+  protected $releephRequestID;
+  protected $type;
+  protected $actorPHID;
+  protected $details = array();
+
+  public function getConfiguration() {
+    return array(
+      self::CONFIG_SERIALIZATION => array(
+        'details' => self::SERIALIZATION_JSON,
+      ),
+    ) + parent::getConfiguration();
+  }
+
+  public function getDetail($key, $default = null) {
+    return idx($this->details, $key, $default);
+  }
+
+  public function setDetail($key, $value) {
+    $this->details[$key] = $value;
+    return $this;
+  }
+
+  private function setDetails(array $details) {
+    throw new Exception('Use setDetail()!');
+  }
+
+  public function setStatusBefore($status) {
+    return $this->setDetail('oldStatus', $status);
+  }
+
+  public function setStatusAfter($status) {
+    return $this->setDetail('newStatus', $status);
+  }
+
+  public function getStatusBefore() {
+    return $this->getDetail('oldStatus');
+  }
+
+  public function getStatusAfter() {
+    return $this->getDetail('newStatus');
+  }
+
+  public function getComment() {
+    return $this->getDetail('comment');
+  }
+
+  public function extractPHIDs() {
+    $phids = array();
+    $phids[] = $this->actorPHID;
+    foreach ($this->details as $key => $value) {
+      if (strpos($key, 'PHID') !== false || strpos($key, 'phid') !== false) {
+        $phids[] = $value;
+      }
+    }
+    return $phids;
+  }
+
+  public function canGroupWith(ReleephRequestEvent $next) {
+    if ($this->getActorPHID() != $next->getActorPHID()) {
+      return false;
+    }
+
+    if ($this->getComment() && $next->getComment()) {
+      return false;
+    }
+
+    // Break the chain if the next event changes the status
+    if ($next->getStatusBefore() != $next->getStatusAfter()) {
+      return false;
+    }
+
+    // Don't group if the next event starts off with a different status to the
+    // one we ended with.  This probably shouldn't ever happen.
+    if ($this->getStatusAfter() != $next->getStatusBefore()) {
+      return false;
+    }
+
+    return true;
+  }
+
+}
diff --git a/src/applications/releeph/storage/request/exception/ReleephRequestException.php b/src/applications/releeph/storage/request/exception/ReleephRequestException.php
new file mode 100644
index 000000000..6f22f8c29
--- /dev/null
+++ b/src/applications/releeph/storage/request/exception/ReleephRequestException.php
@@ -0,0 +1,3 @@
+<?php
+
+final class ReleephRequestException extends Exception {}
diff --git a/src/applications/releeph/view/ReleephProjectView.php b/src/applications/releeph/view/ReleephProjectView.php
new file mode 100644
index 000000000..49f17d135
--- /dev/null
+++ b/src/applications/releeph/view/ReleephProjectView.php
@@ -0,0 +1,155 @@
+<?php
+
+final class ReleephProjectView extends AphrontView {
+
+  private $showOpenBranches = true;
+  private $releephProject;
+  private $releephBranches;
+
+  public function setShowOpenBranches($active) {
+    $this->showOpenBranches = $active;
+    return $this;
+  }
+
+  public function setReleephProject($releeph_project) {
+    $this->releephProject = $releeph_project;
+    return $this;
+  }
+
+  public function setBranches($branches) {
+    $this->releephBranches = $branches;
+    return $this;
+  }
+
+  public function render() {
+    $releeph_project = $this->releephProject;
+
+    if ($this->showOpenBranches) {
+      $releeph_branches = mfilter($this->releephBranches, 'getIsActive');
+    } else {
+      $releeph_branches = mfilter($this->releephBranches, 'getIsActive', true);
+    }
+
+    // Load all relevant PHID handles
+    $phids = array_merge(
+      array(
+        $this->releephProject->getPHID(),
+        $this->releephProject->getRepositoryPHID(),
+      ),
+      mpull($releeph_branches, 'getCreatedByUserPHID'),
+      mpull($releeph_branches, 'getCutPointCommitPHID'),
+      $releeph_project->getPushers());
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      ->setViewer($this->getUser())
+      ->loadHandles();
+
+    // Sort branches, which requires the handles above
+    $releeph_branches = self::sortBranches($releeph_branches, $handles);
+
+    // The header
+    $repository_phid = $releeph_project->getRepositoryPHID();
+
+    $header = hsprintf(
+      '%s in %s repository',
+      $releeph_project->getName(),
+      $handles[$repository_phid]->renderLink());
+
+    if ($this->showOpenBranches) {
+      $view_other_link = phutil_tag(
+        'a',
+        array(
+          'href' => $releeph_project->getURI('closedbranches/'),
+        ),
+        'View closed branches');
+    } else {
+      $view_other_link = phutil_tag(
+        'a',
+        array(
+          'href' => $releeph_project->getURI(),
+        ),
+        'View open branches');
+    }
+
+    $header = hsprintf("%s &middot; %s", $header, $view_other_link);
+
+    // The "create branch" button
+    $create_branch_url = $releeph_project->getURI('cutbranch/');
+
+    // Pushers info
+    $pushers_info = array();
+    $pushers = $releeph_project->getPushers();
+    require_celerity_resource('releeph-project');
+    if ($pushers) {
+      $pushers_info[] = phutil_tag('h2', array(), 'Pushers');
+      foreach ($pushers as $user_phid) {
+        $handle = $handles[$user_phid];
+        $div = phutil_tag(
+          'div',
+          array(
+            'class' => 'releeph-pusher',
+            'style' => 'background-image: url('.$handle->getImageURI().');',
+          ),
+          phutil_tag(
+            'div',
+            array(
+              'class' => 'releeph-pusher-body',
+            ),
+            $handles[$user_phid]->renderLink()));
+        $pushers_info[] = $div;
+      }
+
+      $pushers_info[] = hsprintf('<div style="clear: both;"></div>');
+    }
+
+    // Put it all together
+    $panel = id(new AphrontPanelView())
+      ->setHeader($header)
+      ->appendChild(phutil_implode_html('', $pushers_info));
+
+    foreach ($releeph_branches as $ii => $releeph_branch) {
+      $box = id(new ReleephBranchBoxView())
+        ->setUser($this->user)
+        ->setHandles($handles)
+        ->setReleephBranch($releeph_branch)
+        ->setNamed();
+
+      if ($ii === 0) {
+        $box->setLatest();
+      }
+      $panel->appendChild($box);
+    }
+
+    return $panel->render();
+  }
+
+  /**
+   * Sort branches by the point at which they were cut, newest cut points
+   * first.
+   *
+   * If branches share a cut point, sort newest branch first.
+   */
+  private static function sortBranches($branches, $handles) {
+    // Group by commit phid
+    $groups = mgroup($branches, 'getCutPointCommitPHID');
+
+    // Convert commit phid to a commit timestamp
+    $ar = array();
+    foreach ($groups as $cut_phid => $group) {
+      $handle = $handles[$cut_phid];
+      // Pack (timestamp, group-with-this-timestamp) pairs into $ar
+      $ar[] = array(
+        $handle->getTimestamp(),
+        msort($group, 'getDateCreated')
+      );
+    }
+
+    $branches = array();
+    // Sort by timestamp, pull groups, and flatten into one big group
+    foreach (ipull(isort($ar, 0), 1) as $group) {
+      $branches = array_merge($branches, $group);
+    }
+
+    return array_reverse($branches);
+  }
+
+}
diff --git a/src/applications/releeph/view/branch/ReleephBranchBoxView.php b/src/applications/releeph/view/branch/ReleephBranchBoxView.php
new file mode 100644
index 000000000..54b756d3f
--- /dev/null
+++ b/src/applications/releeph/view/branch/ReleephBranchBoxView.php
@@ -0,0 +1,225 @@
+<?php
+
+final class ReleephBranchBoxView extends AphrontView {
+
+  private $releephBranch;
+  private $isLatest = false;
+  private $isNamed = false;
+  private $handles;
+
+  public function setReleephBranch(ReleephBranch $br) {
+    $this->releephBranch = $br;
+    return $this;
+  }
+
+  // Primary highlighted branch
+  public function setLatest() {
+    $this->isLatest = true;
+    return $this;
+  }
+
+  // Secondary highlighted branch(es)
+  public function setNamed() {
+    $this->isNamed = true;
+    return $this;
+  }
+
+  public function setHandles($handles) {
+    $this->handles = $handles;
+    return $this;
+  }
+
+  public function render() {
+    $br = $this->releephBranch;
+
+    require_celerity_resource('releeph-branch');
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'releeph-branch-box'.
+                   ($this->isNamed  ? ' releeph-branch-box-named'  : '').
+                   ($this->isLatest ? ' releeph-branch-box-latest' : ''),
+      ),
+      array(
+        $this->renderNames(),
+        $this->renderDatesTable(),
+        // "float: right" means the ordering here is weird
+        $this->renderButtons(),
+        $this->renderStatisticsTable(),
+        phutil_tag(
+          'div',
+          array(
+            'style' => 'clear:both;',
+          ),
+          '')));
+  }
+
+  private function renderNames() {
+    $br = $this->releephBranch;
+
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'names',
+      ),
+      array(
+        phutil_tag(
+          'h1',
+          array(),
+          $br->getDisplayName()),
+        phutil_tag(
+          'h2',
+          array(),
+          $br->getName())));
+  }
+
+  private function renderDatesTable() {
+    $br = $this->releephBranch;
+    $branch_commit_handle = $this->handles[$br->getCutPointCommitPHID()];
+
+    $properties = array();
+    $properties['Created by'] =
+
+    $cut_age = phabricator_format_relative_time(
+      time() - $branch_commit_handle->getTimestamp());
+
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'date-info',
+      ),
+      array(
+        $this->handles[$br->getCreatedByUserPHID()]->renderLink(),
+        phutil_tag('br'),
+        phutil_tag(
+          'a',
+          array(
+            'href' => $branch_commit_handle->getURI(),
+          ),
+          $cut_age.' old')));
+  }
+
+  private function renderStatisticsTable() {
+    $statistics = array();
+
+    $requests = $this->releephBranch->loadReleephRequests($this->getUser());
+    foreach ($requests as $request) {
+      $status = $request->getStatus();
+      if (!isset($statistics[$status])) {
+        $statistics[$status] = 0;
+      }
+      $statistics[$status]++;
+    }
+
+    static $col_groups = 3;
+
+    $cells = array();
+    foreach ($statistics as $status => $count) {
+      $description = ReleephRequest::getStatusDescriptionFor($status);
+      $cells[] = phutil_tag('th', array(), $count);
+      $cells[] = phutil_tag('td', array(), $description);
+    }
+
+    $rows = array();
+    while ($cells) {
+      $row_cells = array();
+      for ($ii = 0; $ii < 2 * $col_groups; $ii++) {
+        $row_cells[] = array_shift($cells);
+      }
+      $rows[] = phutil_tag('tr', array(), $row_cells);
+    }
+
+    if (!$rows) {
+      $rows = hsprintf('<tr><th></th><td>%s</td></tr>', 'none');
+    }
+
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'request-statistics',
+      ),
+      phutil_tag(
+        'table',
+        array(),
+        $rows));
+  }
+
+  private function renderButtons() {
+    $br = $this->releephBranch;
+
+    $buttons = array();
+
+    $buttons[] = phutil_tag(
+      'a',
+      array(
+        'class' => 'small grey button',
+        'href'  => $br->getURI(),
+      ),
+      'View Requests');
+
+    $repo = $br->loadReleephProject()->loadPhabricatorRepository();
+    if (!$repo) {
+      $buttons[] = phutil_tag(
+        'a',
+        array(
+          'class' => 'small button disabled',
+        ),
+        "Diffusion \xE2\x86\x97");
+    } else {
+      $diffusion_request = DiffusionRequest::newFromDictionary(array(
+        'repository' => $repo,
+      ));
+      $diffusion_branch_uri = $diffusion_request->generateURI(array(
+        'action' => 'branch',
+        'branch' => $br->getName(),
+      ));
+      $diffusion_button_class = 'small grey button';
+
+      $buttons[] = phutil_tag(
+        'a',
+        array(
+          'class'  => $diffusion_button_class,
+          'target' => '_blank',
+          'href'   => $diffusion_branch_uri,
+        ),
+        "Diffusion \xE2\x86\x97");
+    }
+
+    $releeph_project = $br->loadReleephProject();
+    if (!$releeph_project->getPushers() ||
+        $releeph_project->isPusher($this->user)) {
+
+      $buttons[] = phutil_tag(
+        'a',
+        array(
+          'class' => 'small blue button',
+          'href'  => $br->getURI('edit/'),
+        ),
+        'Edit');
+
+      if ($br->isActive()) {
+        $button_text = "Close";
+        $href = $br->getURI('close/');
+      } else {
+        $button_text = "Re-open";
+        $href = $br->getURI('re-open/');
+      }
+      $buttons[] = javelin_tag(
+        'a',
+        array(
+          'class' => 'small blue button',
+          'href'  => $href,
+          'sigil' => 'workflow',
+        ),
+        $button_text);
+    }
+
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'buttons',
+      ),
+      $buttons);
+  }
+
+}
diff --git a/src/applications/releeph/view/branch/ReleephBranchPreviewView.php b/src/applications/releeph/view/branch/ReleephBranchPreviewView.php
new file mode 100644
index 000000000..8f5f344f6
--- /dev/null
+++ b/src/applications/releeph/view/branch/ReleephBranchPreviewView.php
@@ -0,0 +1,60 @@
+<?php
+
+final class ReleephBranchPreviewView extends AphrontFormControl {
+
+  private $statics = array();
+  private $dynamics = array();
+
+  public function addControl($param_name, AphrontFormControl $control) {
+    $celerity_id = celerity_generate_unique_node_id();
+    $control->setID($celerity_id);
+    $this->dynamics[$param_name] = $celerity_id;
+    return $this;
+  }
+
+  public function addStatic($param_name, $value) {
+    $this->statics[$param_name] = $value;
+    return $this;
+  }
+
+  public function getCustomControlClass() {
+    require_celerity_resource('releeph-preview-branch');
+    return 'releeph-preview-branch';
+  }
+
+  public function renderInput() {
+    static $required_params = array(
+      'arcProjectID',
+      'projectName',
+      'isSymbolic',
+      'template',
+    );
+
+    $all_params = array_merge($this->statics, $this->dynamics);
+    foreach ($required_params as $param_name) {
+      if (idx($all_params, $param_name) === null) {
+        throw new Exception(
+          "'{$param_name}' is not set as either a static or dynamic!");
+      }
+    }
+
+    $output_id = celerity_generate_unique_node_id();
+
+    Javelin::initBehavior('releeph-preview-branch', array(
+      'uri'           => '/releeph/branch/preview/',
+      'outputID'      => $output_id,
+      'params'        => array(
+        'static'  => $this->statics,
+        'dynamic' => $this->dynamics,
+      )
+    ));
+
+    return phutil_tag(
+      'div',
+      array(
+        'id' => $output_id,
+      ),
+      '');
+  }
+
+}
diff --git a/src/applications/releeph/view/branch/ReleephBranchTemplate.php b/src/applications/releeph/view/branch/ReleephBranchTemplate.php
new file mode 100644
index 000000000..cef13ee25
--- /dev/null
+++ b/src/applications/releeph/view/branch/ReleephBranchTemplate.php
@@ -0,0 +1,241 @@
+<?php
+
+final class ReleephBranchTemplate {
+
+  const KEY = 'releeph.default-branch-template';
+
+  public static function getDefaultTemplate() {
+    return PhabricatorEnv::getEnvConfig(self::KEY);
+  }
+
+  public static function getRequiredDefaultTemplate() {
+    $template = self::getDefaultTemplate();
+    if (!$template) {
+      throw new Exception(sprintf(
+        "Config setting '%s' must be set, ".
+        "or you must provide a branch-template for each project!",
+        self::KEY));
+    }
+    return $template;
+  }
+
+  public static function getFakeCommitHandleFor($arc_project_id) {
+    $arc_project = id(new PhabricatorRepositoryArcanistProject())
+      ->load($arc_project_id);
+    if (!$arc_project) {
+      throw new Exception(
+        "No Arc project found with id '{$arc_project_id}'!");
+    }
+
+    $repository = $arc_project->loadRepository();
+    return id(new PhabricatorObjectHandle())
+      ->setName($repository->formatCommitName('100000000000'));
+  }
+
+  private $commitHandle;
+  private $branchDate = null;
+  private $projectName;
+  private $isSymbolic;
+
+  public function setCommitHandle(PhabricatorObjectHandle $handle) {
+    $this->commitHandle = $handle;
+    return $this;
+  }
+
+  public function setBranchDate($branch_date) {
+    $this->branchDate = $branch_date;
+    return $this;
+  }
+
+  public function setReleephProjectName($project_name) {
+    $this->projectName = $project_name;
+    return $this;
+  }
+
+  public function setSymbolic($is_symbolic) {
+    $this->isSymbolic = $is_symbolic;
+    return $this;
+  }
+
+  public function interpolate($template) {
+    if (!$this->projectName) {
+      return array('', array());
+    }
+
+    list($name, $name_errors) = $this->interpolateInner(
+      $template,
+      $this->isSymbolic);
+
+    if ($this->isSymbolic) {
+      return array($name, $name_errors);
+    } else {
+      $validate_errors = $this->validateAsBranchName($name);
+      $errors = array_merge($name_errors, $validate_errors);
+      return array($name, $errors);
+    }
+  }
+
+  public static function getHelpRemarkup() {
+    return <<<EOTEXT
+
+==== Interpolations ====
+
+| Code  | Meaning
+| ----- | -------
+| `%P`  | The name of your project, 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 projects:
+
+  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
+    ;
+  }
+
+  /*
+   * xsprintf() would be useful here, but that's for formatting concrete lists
+   * of things in a certain way...
+   *
+   *    animal_printf('%A %A %A', $dog1, $dog2, $dog3);
+   *
+   * ...rather than interpolating percent-control-strings like strftime does.
+   */
+  private function interpolateInner($template, $is_symbolic) {
+    $name = $template;
+    $errors = array();
+
+    $safe_project_name = str_replace(' ', '-', $this->projectName);
+    $short_commit_id = last(
+      preg_split('/r[A-Z]+/', $this->commitHandle->getName()));
+
+    $interpolations = array();
+    for ($ii = 0; $ii < strlen($name); $ii++) {
+      $char = substr($name, $ii, 1);
+      $prev = null;
+      if ($ii > 0) {
+        $prev = substr($name, $ii - 1, 1);
+      }
+      $next = substr($name, $ii + 1, 1);
+      if ($next && $char == '%' && $prev != '%') {
+        $interpolations[$ii] = $next;
+      }
+    }
+
+    $variable_interpolations = array();
+
+    $reverse_interpolations = $interpolations;
+    krsort($reverse_interpolations);
+
+    if ($this->branchDate) {
+      $branch_date = $this->branchDate;
+    } else {
+      $branch_date = $this->commitHandle->getTimestamp();
+    }
+
+    foreach ($reverse_interpolations as $position => $code) {
+      $replacement = null;
+      switch ($code) {
+        case 'v':
+          $replacement = $this->commitHandle->getName();
+          $is_variable = true;
+          break;
+
+        case 'V':
+          $replacement = $short_commit_id;
+          $is_variable = true;
+          break;
+
+        case 'P':
+          $replacement = $safe_project_name;
+          $is_variable = false;
+          break;
+
+        case 'p':
+          $replacement = strtolower($safe_project_name);
+          $is_variable = false;
+          break;
+
+        default:
+          // Format anything else using strftime()
+          $replacement = strftime("%{$code}", $branch_date);
+          $is_variable = true;
+          break;
+      }
+
+      if ($is_variable) {
+        $variable_interpolations[] = $code;
+      }
+      $name = substr_replace($name, $replacement, $position, 2);
+    }
+
+    if (!$is_symbolic && !$variable_interpolations) {
+      $errors[] = "Include additional interpolations that aren't static!";
+    }
+
+    return array($name, $errors);
+  }
+
+  private function validateAsBranchName($name) {
+    $errors = array();
+
+    if (preg_match('{^/}', $name) || preg_match('{/$}', $name)) {
+      $errors[] = "Branches cannot begin or end with '/'";
+    }
+
+    if (preg_match('{//+}', $name)) {
+      $errors[] = "Branches cannot contain multiple consective '/'";
+    }
+
+    $parts = array_filter(explode('/', $name));
+    foreach ($parts as $index => $part) {
+      $part_error = null;
+      if (preg_match('{^\.}', $part) || preg_match('{\.$}', $part)) {
+        $errors[] = "Path components cannot begin or end with '.'";
+      } elseif (preg_match('{^(?!\w)}', $part)) {
+        $errors[] = "Path components must begin with an alphanumeric";
+      } elseif (!preg_match('{^\w ([\w-_%\.]* [\w-_%])?$}x', $part)) {
+        $errors[] =
+          "Path components may only contain alphanumerics ".
+          "or '-', '_', or '.'";
+      }
+    }
+
+    return $errors;
+  }
+
+}
diff --git a/src/applications/releeph/view/project/list/ReleephActiveProjectListView.php b/src/applications/releeph/view/project/list/ReleephActiveProjectListView.php
new file mode 100644
index 000000000..6b9d533f2
--- /dev/null
+++ b/src/applications/releeph/view/project/list/ReleephActiveProjectListView.php
@@ -0,0 +1,102 @@
+<?php
+
+final class ReleephActiveProjectListView extends AphrontView {
+
+  private $releephProjects;
+
+  public function setReleephProjects(array $releeph_projects) {
+    $this->releephProjects = $releeph_projects;
+    return $this;
+  }
+
+  public function render() {
+    $rows = array();
+    foreach ($this->releephProjects as $releeph_project) {
+      $project_uri = $releeph_project->getURI();
+
+      $name_link = phutil_tag(
+        'a',
+        array(
+          'href' => $project_uri,
+          'style' => 'font-weight: bold;',
+        ),
+        $releeph_project->getName());
+
+      $edit_button = phutil_tag(
+        'a',
+        array(
+          'href'  => $releeph_project->getURI('edit/'),
+          'class' => 'small grey button',
+        ),
+        'Edit');
+
+      $deactivate_button = javelin_tag(
+        'a',
+        array(
+          'href'  => $releeph_project->getURI('action/deactivate/'),
+          'class' => 'small grey button',
+          'sigil' => 'workflow',
+        ),
+        'Remove');
+
+      $arc_project = $releeph_project->loadArcanistProject();
+      if ($arc_project) {
+        $arc_project_name = $arc_project->getName();
+      } else {
+        $arc_project_name = phutil_tag(
+          'i',
+          array(),
+          'Deleted Arcanist Project');
+      }
+
+      $repo = $releeph_project->loadPhabricatorRepository();
+
+      if ($repo) {
+        $vcs_type =
+          PhabricatorRepositoryType::getNameForRepositoryType(
+            $repo->getVersionControlSystem());
+
+        $rows[] = array(
+          $name_link,
+          $repo->getName(),
+          $arc_project_name,
+          $vcs_type,
+          $edit_button,
+          $deactivate_button,
+        );
+      } else {
+        $rows[] = array(
+          $name_link,
+          phutil_tag('i', array(), 'Deleted Repository'),
+          $arc_project_name,
+          null,
+          null,
+          $deactivate_button,
+        );
+      }
+    }
+
+    $table = new AphrontTableView($rows);
+
+    $table->setHeaders(array(
+      'Name',
+      'Repository',
+      'Arcanist Project',
+      'Type',
+      '',
+      ''
+    ));
+
+    $table->setColumnClasses(array(
+      null,
+      null,
+      'wide',
+      null,
+      'action',
+      'action'
+    ));
+
+    return $table->render();
+  }
+
+}
diff --git a/src/applications/releeph/view/project/list/ReleephInactiveProjectListView.php b/src/applications/releeph/view/project/list/ReleephInactiveProjectListView.php
new file mode 100644
index 000000000..765145e20
--- /dev/null
+++ b/src/applications/releeph/view/project/list/ReleephInactiveProjectListView.php
@@ -0,0 +1,112 @@
+<?php
+
+final class ReleephInactiveProjectListView extends AphrontView {
+
+  private $releephProjects;
+
+  public function setReleephProjects(array $releeph_projects) {
+    $this->releephProjects = $releeph_projects;
+    return $this;
+  }
+
+  public function render() {
+    $rows = array();
+
+    $phids = array();
+    foreach ($this->releephProjects as $releeph_project) {
+      $phids[] = $releeph_project->getCreatedByUserPHID();
+      if ($phid = $releeph_project->getDetail('last_deactivated_user')) {
+        $phids[] = $phid;
+      }
+    }
+
+    $handles = id(new PhabricatorObjectHandleData($phids))
+      ->setViewer($this->getUser())
+      ->loadHandles();
+
+    foreach ($this->releephProjects as $releeph_project) {
+      $repository = $releeph_project->loadPhabricatorRepository();
+
+      if (!$repository) {
+        // Ignore projects referring to repositories that have been deleted.
+        continue;
+      }
+
+      $activate_link = javelin_tag(
+        'a',
+        array(
+          'href'  => $releeph_project->getURI('action/activate/'),
+          'class' => 'small grey button',
+          'sigil' => 'workflow',
+        ),
+        'Revive');
+
+      $delete_link = javelin_tag(
+        'a',
+        array(
+          'href'  => $releeph_project->getURI('action/delete/'),
+          'class' => 'small grey button',
+          'sigil' => 'workflow',
+        ),
+        'Delete');
+
+      $rows[] = array(
+        $releeph_project->getName(),
+        $repository->getName(),
+        $this->renderCreationInfo($releeph_project, $handles),
+        $this->renderDeletionInfo($releeph_project, $handles),
+        $activate_link,
+        $delete_link,
+      );
+    }
+
+    $table = new AphrontTableView($rows);
+
+    $table->setHeaders(array(
+      'Name',
+      'Repository',
+      'Created',
+      'Deleted',
+      '',
+      '',
+    ));
+
+    $table->setColumnClasses(array(
+      null,
+      null,
+      null,
+      'wide',
+      'action',
+      'action',
+    ));
+
+    return $table->render();
+  }
+
+  private function renderCreationInfo($releeph_project, $handles) {
+    $creator = $handles[$releeph_project->getCreatedByUserPHID()];
+    $when = $releeph_project->getDateCreated();
+    return hsprintf(
+      '%s by %s',
+      phabricator_relative_date($when, $this->user),
+      $creator->getName());
+  }
+
+  private function renderDeletionInfo($releeph_project, $handles) {
+    $deleted_on = $releeph_project->getDetail('last_deactivated_time');
+
+    $deleted_by_name = null;
+    $deleted_by_phid = $releeph_project->getDetail('last_deactivated_user');
+    if ($deleted_by_phid) {
+      $deleted_by_name = $handles[$deleted_by_phid]->getName();
+    } else {
+      $deleted_by_name = 'unknown';
+    }
+
+    return hsprintf(
+      '%s by %s',
+      phabricator_relative_date($deleted_on, $this->user),
+      $deleted_by_name);
+  }
+
+}
diff --git a/src/applications/releeph/view/request/ReleephRequestIntentsView.php b/src/applications/releeph/view/request/ReleephRequestIntentsView.php
new file mode 100644
index 000000000..b9c78680a
--- /dev/null
+++ b/src/applications/releeph/view/request/ReleephRequestIntentsView.php
@@ -0,0 +1,104 @@
+<?php
+
+final class ReleephRequestIntentsView extends AphrontView {
+
+  private $releephRequest;
+  private $releephProject;
+
+  public function setReleephRequest(ReleephRequest $rq) {
+    $this->releephRequest = $rq;
+    return $this;
+  }
+
+  public function setReleephProject(ReleephProject $rp) {
+    $this->releephProject = $rp;
+    return $this;
+  }
+
+  public function render() {
+    require_celerity_resource('releeph-intents');
+
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'releeph-intents',
+      ),
+      array(
+        $this->renderIntentList(ReleephRequest::INTENT_WANT),
+        $this->renderIntentList(ReleephRequest::INTENT_PASS)
+      ));
+  }
+
+  private function renderIntentList($render_intent) {
+    if (!$this->releephProject) {
+      throw new Exception("Must call setReleephProject() first!");
+    }
+
+    $project = $this->releephProject;
+    $request = $this->releephRequest;
+    $handles = $request->getHandles();
+
+    $is_want = $render_intent == ReleephRequest::INTENT_WANT;
+    $should = $request->shouldBeInBranch();
+
+    $pusher_links = array();
+    $user_links = array();
+
+    $intents = $request->getUserIntents();
+    foreach ($intents as $user_phid => $user_intent) {
+      if ($user_intent == $render_intent) {
+        $is_pusher = $project->isPusherPHID($user_phid);
+
+        if ($is_pusher) {
+          $pusher_links[] = phutil_tag(
+            'span',
+            array(
+              'class' => 'pusher'
+            ),
+            $handles[$user_phid]->renderLink());
+        } else {
+          $class = 'bystander';
+          if ($request->getRequestUserPHID() == $user_phid) {
+            $class = 'requestor';
+          }
+          $user_links[] = phutil_tag(
+            'span',
+            array(
+              'class' => $class,
+            ),
+            $handles[$user_phid]->renderLink());
+        }
+      }
+    }
+
+    // Don't render anything
+    if (!$pusher_links && !$user_links) {
+      return null;
+    }
+
+    $links = array_merge($pusher_links, $user_links);
+    if ($links) {
+      $markup = $links;
+    } else {
+      $markup = array('&nbsp;');
+    }
+
+    // Stick an arrow up front
+    $arrow_class = 'arrow '.$render_intent;
+    array_unshift($markup, phutil_tag(
+      'div',
+      array(
+        'class' => $arrow_class,
+      ),
+      ''));
+
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'intents',
+      ),
+      $markup);
+  }
+
+
+}
diff --git a/src/applications/releeph/view/request/ReleephRequestStatusView.php b/src/applications/releeph/view/request/ReleephRequestStatusView.php
new file mode 100644
index 000000000..4076f037f
--- /dev/null
+++ b/src/applications/releeph/view/request/ReleephRequestStatusView.php
@@ -0,0 +1,53 @@
+<?php
+
+final class ReleephRequestStatusView extends AphrontView {
+
+  private $releephRequest;
+
+  public function setReleephRequest(ReleephRequest $rq) {
+    $this->releephRequest = $rq;
+    return $this;
+  }
+
+  public function render() {
+    require_celerity_resource('releeph-status');
+
+    $request = $this->releephRequest;
+    $status = $request->getStatus();
+    $pick_status = $request->getPickStatus();
+
+    $description = ReleephRequest::getStatusDescriptionFor($status);
+
+    $warning = null;
+
+    if ($status == ReleephRequest::STATUS_NEEDS_PICK) {
+      if ($pick_status == ReleephRequest::PICK_FAILED) {
+        $warning = 'Last pick failed!';
+      }
+    } elseif ($status == ReleephRequest::STATUS_NEEDS_REVERT) {
+      if ($pick_status == ReleephRequest::REVERT_FAILED) {
+        $warning = 'Last revert failed!';
+      }
+    }
+
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'releeph-status',
+      ),
+      array(
+        phutil_tag(
+          'div',
+          array(
+            'class' => 'description',
+          ),
+          $description),
+        phutil_tag(
+          'div',
+          array(
+            'class' => 'warning',
+          ),
+          $warning)));
+  }
+
+}
diff --git a/src/applications/releeph/view/request/ReleephRequestTypeaheadControl.php b/src/applications/releeph/view/request/ReleephRequestTypeaheadControl.php
new file mode 100644
index 000000000..a6f0355fd
--- /dev/null
+++ b/src/applications/releeph/view/request/ReleephRequestTypeaheadControl.php
@@ -0,0 +1,58 @@
+<?php
+
+final class ReleephRequestTypeaheadControl extends AphrontFormControl {
+
+  private $repo;
+  private $startTime;
+
+  public function setRepo(PhabricatorRepository $repo) {
+    $this->repo = $repo;
+    return $this;
+  }
+
+  public function setStartTime($epoch) {
+    $this->startTime = $epoch;
+    return $this;
+  }
+
+  public function getCustomControlClass() {
+    return 'releeph-request-typeahead';
+  }
+
+  public function renderInput() {
+    $id = celerity_generate_unique_node_id();
+
+    $div = phutil_tag(
+      'div',
+      array(
+        'style' => 'position: relative;',
+        'id' => $id,
+      ),
+      phutil_tag(
+        'input',
+        array(
+          'autocomplete' => 'off',
+          'type' => 'text',
+          'name' => $this->getName(),
+        ),
+        ''));
+
+    require_celerity_resource('releeph-request-typeahead-css');
+
+    Javelin::initBehavior('releeph-request-typeahead', array(
+      'id'  => $id,
+      'src' => '/releeph/request/typeahead/',
+      'placeholder' => 'Type a commit id or first line of commit message...',
+      'value'       => $this->getValue(),
+      'aux' => array(
+        'repo'      => $this->repo->getID(),
+        'callsign'  => $this->repo->getCallsign(),
+        'since'     => $this->startTime,
+        'limit'     => 16,
+      )
+    ));
+
+    return $div;
+  }
+
+}
diff --git a/src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php b/src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php
new file mode 100644
index 000000000..98dd9d44b
--- /dev/null
+++ b/src/applications/releeph/view/request/header/ReleephRequestHeaderListView.php
@@ -0,0 +1,113 @@
+<?php
+
+final class ReleephRequestHeaderListView
+  extends AphrontView {
+
+  private $originType;
+  private $releephProject;
+  private $releephBranch;
+  private $releephRequests;
+  private $aphrontRequest;
+  private $reload = false;
+
+  private $errors = array();
+
+  public function setOriginType($origin) {
+    $this->originType = $origin;
+    return $this;
+  }
+
+  public function setReleephProject(ReleephProject $rp) {
+    $this->releephProject = $rp;
+    return $this;
+  }
+
+  public function setReleephBranch(ReleephBranch $rb) {
+    $this->releephBranch = $rb;
+    return $this;
+  }
+
+  public function setReleephRequests(array $requests) {
+    assert_instances_of($requests, 'ReleephRequest');
+    $this->releephRequests = $requests;
+    return $this;
+  }
+
+  public function setAphrontRequest(AphrontRequest $request) {
+    $this->aphrontRequest = $request;
+    return $this;
+  }
+
+  public function setReloadOnStateChange($bool) {
+    $this->reload = $bool;
+    return $this;
+  }
+
+  public function render() {
+    $views = $this->renderInner();
+    require_celerity_resource('phabricator-notification-css');
+    Javelin::initBehavior('releeph-request-state-change', array(
+      'reload' => $this->reload,
+    ));
+
+    $error_view = null;
+    if ($this->errors) {
+      $error_view = id(new AphrontErrorView())
+        ->setTitle('Bulk load errors')
+        ->setSeverity(AphrontErrorView::SEVERITY_WARNING)
+        ->setErrors($this->errors)
+        ->render();
+    }
+
+    $list = phutil_tag(
+      'div',
+      array(
+        'data-sigil' => 'releeph-request-header-list',
+      ),
+      $views);
+
+    return $this->renderSingleView(array(
+      $error_view,
+      $list));
+  }
+
+  /**
+   * Required for generating markup for ReleephRequestActionController.
+   *
+   * That controller just needs the markup, and doesn't need to start the
+   * javelin behavior.
+   */
+  public function renderInner() {
+    $selector = $this->releephProject->getReleephFieldSelector();
+    $fields = $selector->getFieldSpecifications();
+    foreach ($fields as $field) {
+      $field
+        ->setReleephProject($this->releephProject)
+        ->setReleephBranch($this->releephBranch)
+        ->setUser($this->user);
+      try {
+        $field->bulkLoad($this->releephRequests);
+      } catch (Exception $ex) {
+        $this->errors[] = $ex;
+      }
+    }
+
+    $field_groups = $selector->arrangeFieldsForHeaderView($fields);
+
+    $views = array();
+    foreach ($this->releephRequests as $releeph_request) {
+      $views[] = id(new ReleephRequestHeaderView())
+        ->setUser($this->user)
+        ->setAphrontRequest($this->aphrontRequest)
+        ->setOriginType($this->originType)
+        ->setReleephProject($this->releephProject)
+        ->setReleephBranch($this->releephBranch)
+        ->setReleephRequest($releeph_request)
+        ->setReleephFieldGroups($field_groups)
+        ->render();
+    }
+
+    return $views;
+  }
+
+}
diff --git a/src/applications/releeph/view/request/header/ReleephRequestHeaderView.php b/src/applications/releeph/view/request/header/ReleephRequestHeaderView.php
new file mode 100644
index 000000000..87753e5b8
--- /dev/null
+++ b/src/applications/releeph/view/request/header/ReleephRequestHeaderView.php
@@ -0,0 +1,334 @@
+<?php
+
+final class ReleephRequestHeaderView extends AphrontView {
+
+  const THROW_PARAM = '__releeph_throw';
+
+  private $aphrontRequest;
+  private $releephRequest;
+  private $releephBranch;
+  private $releephProject;
+  private $originType;
+  private $fieldGroups;
+
+  public function setAphrontRequest(AphrontRequest $request) {
+    $this->aphrontRequest = $request;
+    return $this;
+  }
+
+  public function setReleephProject(ReleephProject $rp) {
+    $this->releephProject = $rp;
+    return $this;
+  }
+
+  public function setReleephBranch(ReleephBranch $rb) {
+    $this->releephBranch = $rb;
+    return $this;
+  }
+
+  public function setReleephRequest(ReleephRequest $rr) {
+    $this->releephRequest = $rr;
+    return $this;
+  }
+
+  public function setOriginType($origin) {
+    // For the Edit controller
+    $this->originType = $origin;
+    return $this;
+  }
+
+  public function setReleephFieldGroups(array $field_groups) {
+    $this->fieldGroups = $field_groups;
+    return $this;
+  }
+
+  protected function getOrigin() {
+    return $this->originType;
+  }
+
+  public function render() {
+    require_celerity_resource('releeph-core');
+    $all_properties_table = $this->renderFields();
+
+    require_celerity_resource('releeph-colors');
+    $status = $this->releephRequest->getStatus();
+    $rr_div_class =
+      'releeph-request-header '.
+      'releeph-request-header-border '.
+      'releeph-border-color-'.ReleephRequest::getStatusClassSuffixFor($status);
+
+    $hidden_link = phutil_tag(
+      'a',
+      array(
+        'href'        => '/RQ'.$this->releephRequest->getID(),
+        'target'      => '_blank',
+        'data-sigil'  => 'hidden-link',
+      ),
+      '');
+
+    $focus_char = phutil_tag(
+      'div',
+      array(
+        'class' => 'focus-char',
+        'data-sigil' => 'focus-char',
+      ),
+      "\xE2\x98\x86");
+
+    $rr_div = phutil_tag(
+      'div',
+      array(
+        'data-sigil' => 'releeph-request-header',
+        'class' => $rr_div_class,
+      ),
+      array(
+        phutil_tag(
+          'div',
+          array(),
+          array(
+            phutil_tag(
+              'h1',
+              array(),
+              array(
+                $focus_char,
+                $this->renderTitleLink(),
+                $hidden_link
+              )),
+            $all_properties_table,
+          )),
+        phutil_tag(
+          'div',
+          array(
+            'class' => 'button-divider',
+          ),
+          $this->renderActionButtonsTable())));
+
+    return $rr_div;
+  }
+
+  private function renderFields() {
+    $field_row_groups = $this->fieldGroups;
+
+    $trs = array();
+    foreach ($field_row_groups as $field_column_group) {
+      $tds = array();
+      foreach ($field_column_group as $side => $fields) {
+        $rows = array();
+        foreach ($fields as $field) {
+          $rows[] = $this->renderOneField($field);
+        }
+        $pane = phutil_tag(
+          'table',
+          array(
+            'class' => 'fields',
+          ),
+          $rows);
+        $tds[] = phutil_tag(
+          'td',
+          array(
+            'class' => 'side '.$side,
+          ),
+          $pane);
+      }
+      $trs[] = phutil_tag(
+        'tr',
+        array(),
+        $tds);
+    }
+
+    return phutil_tag(
+      'table',
+      array(
+        'class' => 'panes',
+      ),
+      $trs);
+  }
+
+  private function renderOneField(ReleephFieldSpecification $field) {
+    $field
+      ->setUser($this->user)
+      ->setReleephProject($this->releephProject)
+      ->setReleephBranch($this->releephBranch)
+      ->setReleephRequest($this->releephRequest);
+
+    $label = $field->renderLabelForHeaderView();
+    try {
+      $value = $field->renderValueForHeaderView();
+    } catch (Exception $ex) {
+      if ($this->aphrontRequest->getInt(self::THROW_PARAM)) {
+        throw $ex;
+      } else {
+        $value = $this->renderExceptionIcon($ex);
+      }
+    }
+
+    if ($value) {
+      if (!$label) {
+        return phutil_tag(
+          'tr',
+          array(),
+          phutil_tag('td', array('colspan' => 2), $value));
+      } else {
+        return phutil_tag(
+          'tr',
+          array(),
+          array(
+            phutil_tag('th', array(), $label),
+            phutil_tag('td', array(), $value)));
+      }
+    }
+  }
+
+  private function renderExceptionIcon(Exception $ex) {
+    Javelin::initBehavior('phabricator-tooltips');
+    require_celerity_resource('aphront-tooltip-css');
+    $throw_uri = $this
+      ->aphrontRequest
+      ->getRequestURI()
+      ->setQueryParam(self::THROW_PARAM, 1);
+
+    $message = $ex->getMessage();
+    if (!$message) {
+      $message = get_class($ex).' with no message.';
+    }
+
+    return javelin_tag(
+      'a',
+      array(
+        'class' => 'releeph-field-error',
+        'sigil' => 'has-tooltip',
+        'meta'  => array(
+          'tip'   => $message,
+          'size'  => 400,
+          'align' => 'E',
+        ),
+        'href' => $throw_uri,
+      ),
+      '!!!');
+  }
+
+  private function renderTitleLink() {
+    $rq_id = $this->releephRequest->getID();
+    $summary = $this->releephRequest->getSummaryForDisplay();
+    return phutil_tag(
+      'a',
+      array(
+        'href' => '/RQ'.$rq_id,
+      ),
+      hsprintf(
+        'RQ%d: %s',
+        $rq_id,
+        $summary));
+  }
+
+  private function renderActionButtonsTable() {
+    $left_buttons = array();
+    $right_buttons = array();
+
+    $user_phid = $this->user->getPHID();
+    $is_pusher = $this->releephProject->isPusherPHID($user_phid);
+    $is_requestor = $this->releephRequest->getRequestUserPHID() === $user_phid;
+
+    $current_intent = idx(
+      $this->releephRequest->getUserIntents(),
+      $this->user->getPHID());
+
+    if ($is_pusher) {
+      $left_buttons[] = $this->renderIntentButton(true, 'Approve', 'green');
+      $left_buttons[] = $this->renderIntentButton(false, 'Reject');
+    } else {
+      if ($is_requestor) {
+        $right_buttons[] = $this->renderIntentButton(true, 'Request');
+        $right_buttons[] = $this->renderIntentButton(false, 'Remove');
+      } else {
+        $right_buttons[] = $this->renderIntentButton(true, 'Want');
+        $right_buttons[] = $this->renderIntentButton(false, 'Pass');
+      }
+    }
+
+    // Allow the pusher to mark a request as manually picked or reverted.
+    if ($is_pusher || $is_requestor) {
+      if ($this->releephRequest->getInBranch()) {
+        $left_buttons[] = $this->renderActionButton(
+          'Mark Manually Reverted',
+          'mark-manually-reverted');
+      } else {
+        $left_buttons[] = $this->renderActionButton(
+          'Mark Manually Picked',
+          'mark-manually-picked');
+      }
+    }
+
+    $right_buttons[] = phutil_tag(
+      'a',
+      array(
+        'href' => '/releeph/request/edit/'.$this->releephRequest->getID().
+                  '?origin='.$this->originType,
+        'class' => 'small blue button',
+      ),
+      'Edit');
+
+    if (!$left_buttons && !$right_buttons) {
+      return;
+    }
+
+    $cells = array();
+    foreach ($left_buttons as $button) {
+      $cells[] = phutil_tag('td', array('align' => 'left'), $button);
+    }
+    $cells[] = phutil_tag('td', array('class' => 'wide'), '');
+    foreach ($right_buttons as $button) {
+      $cells[] = phutil_tag('td', array('align' => 'right'), $button);
+    }
+
+    $table = phutil_tag(
+      'table',
+      array(
+        'class' => 'buttons',
+      ),
+      phutil_tag(
+        'tr',
+        array(),
+        $cells));
+
+    return $table;
+  }
+
+  private function renderIntentButton($want, $name, $class = null) {
+    $current_intent = idx(
+      $this->releephRequest->getUserIntents(),
+      $this->user->getPHID());
+
+    if ($current_intent) {
+      // If this is a "want" button, and they already want it, disable the
+      // button (and vice versa for the "pass" case.)
+      if (($want && $current_intent == ReleephRequest::INTENT_WANT) ||
+          (!$want && $current_intent == ReleephRequest::INTENT_PASS)) {
+
+        $class .= ' disabled';
+      }
+    }
+
+    $action = $want ? 'want' : 'pass';
+    return $this->renderActionButton($name, $action, $class);
+  }
+
+  private function renderActionButton($name, $action, $class=null) {
+    $attributes = array(
+      'class' => 'small button '.$class,
+      'sigil' => 'releeph-request-state-change '.$action,
+      'meta'  => null,
+    );
+
+    if ($class != 'disabled') {
+      // NB the trailing slash on $uri is critical, otherwise the URI will
+      // redirect to one with a slash, which will turn our GET into a POST.
+      $attributes['meta'] = sprintf(
+        '/releeph/request/action/%s/%d/',
+        $action,
+        $this->releephRequest->getID());
+    }
+
+    return javelin_tag('a', $attributes, $name);
+  }
+
+}
diff --git a/src/applications/releeph/view/requestevent/ReleephRequestEventListView.php b/src/applications/releeph/view/requestevent/ReleephRequestEventListView.php
new file mode 100644
index 000000000..ab0bca7d5
--- /dev/null
+++ b/src/applications/releeph/view/requestevent/ReleephRequestEventListView.php
@@ -0,0 +1,266 @@
+<?php
+
+final class ReleephRequestEventListView extends AphrontView {
+
+  private $events;
+  private $handles;
+
+  public function setEvents(array $events) {
+    assert_instances_of($events, 'ReleephRequestEvent');
+    $this->events = $events;
+    return $this;
+  }
+
+  public function setHandles(array $handles) {
+    assert_instances_of($handles, 'PhabricatorObjectHandle');
+    $this->handles = $handles;
+    return $this;
+  }
+
+  public function render() {
+    $views = array();
+
+    $discovered_commits = array();
+    foreach ($this->events as $event) {
+      $commit_id = $event->getDetail('newCommitIdentifier');
+      switch ($event->getType()) {
+        case ReleephRequestEvent::TYPE_DISCOVERY:
+          $discovered_commits[$commit_id] = true;
+          break;
+      }
+    }
+
+    $markup_engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
+    $markup_engine->setConfig('viewer', $this->getUser());
+
+    foreach ($this->events as $event) {
+      $description = $this->describeEvent($event);
+      if (!$description) {
+        continue;
+      }
+
+      if ($event->getType() === ReleephRequestEvent::TYPE_COMMIT) {
+        $commit_id = $event->getDetail('newCommitIdentifier');
+        if (idx($discovered_commits, $commit_id)) {
+          continue;
+        }
+      }
+
+      $actor_handle = $this->handles[$event->getActorPHID()];
+      $description = $this->describeEvent($event);
+      $action = phutil_tag(
+        'div',
+        array(),
+        array(
+          $actor_handle->renderLink(),
+          ' ',
+          $description));
+
+      $view = id(new PhabricatorTransactionView())
+        ->setUser($this->user)
+        ->setImageURI($actor_handle->getImageURI())
+        ->setEpoch($event->getDateCreated())
+        ->setActions(array($action))
+        ->addClass($this->getTransactionClass($event));
+
+      $comment = $this->getEventComment($event);
+      if ($comment) {
+        $markup = phutil_tag(
+          'div',
+          array(
+            'class' => 'phabricator-remarkup',
+          ),
+          phutil_safe_html(
+            $markup_engine->markupText($comment)));
+        $view->appendChild($markup);
+      }
+
+      $views[] = $view;
+    }
+
+    return phutil_tag(
+      'div',
+      array(
+        'class' => 'releeph-request-event-list',
+      ),
+      $views);
+  }
+
+  public function renderForEmail() {
+    $items = array();
+    foreach ($this->events as $event) {
+      $description = $this->describeEvent($event);
+      if (!$description) {
+        continue;
+      }
+      $actor = $this->handles[$event->getActorPHID()]->getName();
+      $items[] = $actor.' '.$description;
+
+      $comment = $this->getEventComment($event);
+      if ($comment) {
+        $items[] = preg_replace('/^/m', '  ', $comment);
+      }
+    }
+
+    return implode("\n\n", $items);
+  }
+
+  private function describeEvent(ReleephRequestEvent $event) {
+    $type = $event->getType();
+
+    switch ($type) {
+      case ReleephRequestEvent::TYPE_CREATE:
+        return "created this request.";
+        break;
+
+      case ReleephRequestEvent::TYPE_STATUS:
+        $status = $event->getStatusAfter();
+        return sprintf(
+          "updated status to %s.",
+          ReleephRequest::getStatusDescriptionFor($status));
+        break;
+
+      case ReleephRequestEvent::TYPE_USER_INTENT:
+        $intent = $event->getDetail('newIntent');
+        $was_pusher = $event->getDetail('wasPusher');
+        if ($intent == ReleephRequest::INTENT_WANT) {
+          if ($was_pusher) {
+            $verb = "approved";
+          } else {
+            $verb = "wanted";
+          }
+        } else {
+          if ($was_pusher) {
+            $verb = "rejected";
+          } else {
+            $verb = "passed on";
+          }
+        }
+        return "{$verb} this request.";
+        break;
+
+      case ReleephRequestEvent::TYPE_PICK_STATUS:
+        $pick_status = $event->getDetail('newPickStatus');
+        switch ($pick_status) {
+          case ReleephRequest::PICK_FAILED:
+            return "found a conflict when picking.";
+            break;
+
+          case ReleephRequest::REVERT_FAILED:
+            return "found a conflict when reverting.";
+            break;
+
+          case ReleephRequest::PICK_OK:
+          case ReleephRequest::REVERT_OK:
+            // (nothing)
+            break;
+
+          default:
+            return "changed pick-status to {$pick_status}.";
+            break;
+        }
+        break;
+
+      case ReleephRequestEvent::TYPE_MANUAL_ACTION:
+        $action = $event->getDetail('action');
+        return "claimed to have manually {$action}ed this request.";
+        break;
+
+      case ReleephRequestEvent::TYPE_COMMIT:
+        $action = $event->getDetail('action');
+        if ($action) {
+          return "{$action}ed this request.";
+        } else {
+          return "did something with this request.";
+        }
+        break;
+
+      case ReleephRequestEvent::TYPE_DISCOVERY:
+        $action = $event->getDetail('action');
+        if ($action) {
+          return "{$action}ed this request.";
+        } else {
+          // It's unlikely we'll have action-less TYPE_DISCOVERY events, but I
+          // used this during testing and I guess it's a useful safety net.
+          return "discovered this request in the branch.";
+        }
+        break;
+
+      case ReleephRequestEvent::TYPE_COMMENT:
+        return "commented on this request.";
+        break;
+
+      default:
+        return "did event of type {$type}.";
+        break;
+    }
+  }
+
+  private function getEventComment(ReleephRequestEvent $event) {
+    switch ($event->getType()) {
+      case ReleephRequestEvent::TYPE_CREATE:
+        $commit_phid = $event->getDetail('commitPHID');
+        return sprintf(
+          "Commit %s was requested.",
+          $this->handles[$commit_phid]->getName());
+        break;
+
+      case ReleephRequestEvent::TYPE_STATUS:
+      case ReleephRequestEvent::TYPE_USER_INTENT:
+      case ReleephRequestEvent::TYPE_PICK_STATUS:
+      case ReleephRequestEvent::TYPE_MANUAL_ACTION:
+        // no comment!
+        break;
+
+      case ReleephRequestEvent::TYPE_COMMIT:
+        return sprintf(
+          "Closed by commit %s.",
+          $event->getDetail('newCommitIdentifier'));
+        break;
+
+      case ReleephRequestEvent::TYPE_DISCOVERY:
+        $author_phid = $event->getDetail('authorPHID');
+        $commit_phid = $event->getDetail('newCommitPHID');
+        if ($author_phid && $author_phid != $event->getActorPHID()) {
+          return sprintf(
+            "Closed by commit %s (with author set to @%s).",
+            $this->handles[$commit_phid]->getName(),
+            $this->handles[$author_phid]->getName());
+        } else {
+          return sprintf(
+            'Closed by commit %s.',
+            $this->handles[$commit_phid]->getName());
+        }
+        break;
+
+      case ReleephRequestEvent::TYPE_COMMENT:
+        return $event->getComment();
+        break;
+    }
+  }
+
+  private function getTransactionClass($event) {
+    switch ($event->getType()) {
+      case ReleephRequestEvent::TYPE_COMMIT:
+      case ReleephRequestEvent::TYPE_DISCOVERY:
+        $action = $event->getDetail('action');
+        if ($action == 'pick') {
+          return 'releeph-border-color-picked';
+        } else {
+          return 'releeph-border-color-abandoned';
+        }
+        break;
+
+      case ReleephRequestEvent::TYPE_COMMENT:
+        return 'releeph-border-color-comment';
+        break;
+
+      default:
+        $status_after = $event->getStatusAfter();
+        $class_suffix = ReleephRequest::getStatusClassSuffixFor($status_after);
+        return ' releeph-border-color-'.$class_suffix;
+        break;
+    }
+  }
+
+}
diff --git a/src/applications/releeph/view/user/ReleephDefaultUserView.php b/src/applications/releeph/view/user/ReleephDefaultUserView.php
new file mode 100644
index 000000000..93819cdad
--- /dev/null
+++ b/src/applications/releeph/view/user/ReleephDefaultUserView.php
@@ -0,0 +1,9 @@
+<?php
+
+final class ReleephDefaultUserView extends ReleephUserView {
+
+  public function render() {
+    return $this->getHandle()->renderLink();
+  }
+
+}
diff --git a/src/applications/releeph/view/user/ReleephUserView.php b/src/applications/releeph/view/user/ReleephUserView.php
new file mode 100644
index 000000000..129c846ba
--- /dev/null
+++ b/src/applications/releeph/view/user/ReleephUserView.php
@@ -0,0 +1,74 @@
+<?php
+
+abstract class ReleephUserView extends AphrontView {
+
+  /**
+   * This function should bulk load everything you need to render all the given
+   * user phids.
+   *
+   * Many parts of Releeph load users for rendering.  Accordingly, this
+   * function will be called multiple times for each part of the UI that
+   * renders users, so you should accumulate your results on each call.
+   *
+   * You should also implement render() (from AphrontView) to render each
+   * user's PHID.
+   */
+  protected function loadInner(array $phids) {
+    // This is a hook!
+  }
+
+  final public static function getNewInstance() {
+    $key = 'releeph.user-view';
+    $class = PhabricatorEnv::getEnvConfig($key);
+    return newv($class, array());
+  }
+
+  private static $handles = array();
+  private static $seen = array();
+
+  final public function load(array $phids) {
+    $todo = array();
+
+    foreach ($phids as $key => $phid) {
+      if (!idx(self::$seen, $phid)) {
+        $todo[$key] = $phid;
+        self::$seen[$phid] = true;
+      }
+    }
+
+    if ($todo) {
+      self::$handles = array_merge(
+        self::$handles,
+        id(new PhabricatorObjectHandleData($todo))
+          ->setViewer($this->getUser())
+          ->loadHandles());
+      $this->loadInner($todo);
+    }
+  }
+
+  private $phid;
+  private $releephProject;
+
+  final public function setRenderUserPHID($phid) {
+    $this->phid = $phid;
+    return $this;
+  }
+
+  final public function setReleephProject(ReleephProject $project) {
+    $this->releephProject = $project;
+    return $this;
+  }
+
+  final protected function getRenderUserPHID() {
+    return $this->phid;
+  }
+
+  final protected function getReleephProject() {
+    return $this->releephProject;
+  }
+
+  final protected function getHandle() {
+    return self::$handles[$this->phid];
+  }
+
+}
diff --git a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
index 743be93d3..6cf673a37 100644
--- a/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
+++ b/src/infrastructure/internationalization/PhabricatorBaseEnglishTranslation.php
@@ -1,292 +1,298 @@
 <?php
 
 abstract class PhabricatorBaseEnglishTranslation
   extends PhabricatorTranslation {
 
   final public function getLanguage() {
     return 'en';
   }
 
   public function getTranslations() {
     return array(
       'Differential Revision(s)' => array(
         'Differential Revision',
         'Differential Revisions',
       ),
       'file(s)' => array('file', 'files'),
       'Maniphest Task(s)' => array('Maniphest Task', 'Maniphest Tasks'),
 
       'Please fix these errors and try again.' => array(
         'Please fix this error and try again.',
         'Please fix these errors and try again.',
       ),
 
       '%d Error(s)' => array('%d Error', '%d Errors'),
       '%d Warning(s)' => array('%d Warning', '%d Warnings'),
       '%d Auto-Fix(es)' => array('%d Auto-Fix', '%d Auto-Fixes'),
       '%d Advice(s)' => array('%d Advice', '%d Pieces of Advice'),
       '%d Detail(s)' => array('%d Detail', '%d Details'),
 
       '(%d line(s))' => array('(%d line)', '(%d lines)'),
 
       'COMMIT(S)' => array('COMMIT', 'COMMITS'),
 
       '%d line(s)' => array('%d line', '%d lines'),
+      '%d path(s)' => array('%d path', '%d paths'),
+      '%d diff(s)' => array('%d diff', '%d diffs'),
 
       'added %d commit(s): %s' => array(
         'added commit: %2$s',
         'added commits: %2$s',
       ),
 
       'removed %d commit(s): %s' => array(
         'removed commit: %2$s',
         'removed commits: %2$s',
       ),
 
       'changed %d commit(s), added %d: %s; removed %d: %s' =>
         'changed commits, added: %3$s; removed: %5$s',
 
       'ATTACHED %d COMMIT(S)' => array(
         'ATTACHED COMMIT',
         'ATTACHED COMMITS',
       ),
 
       'added %d dependencie(s): %s' => array(
         'added dependency: %2$s',
         'added dependencies: %2$s',
       ),
 
       'added %d dependent task(s): %s' => array(
         'added dependent task: %2$s',
         'added dependent tasks: %2$s',
       ),
 
       'removed %d dependencie(s): %s' => array(
         'removed dependency: %2$s',
         'removed dependencies: %2$s',
       ),
 
       'removed %d dependent task(s): %s' => array(
         'removed dependent task: %2$s',
         'removed dependent tasks: %2$s',
       ),
 
       'changed %d dependencie(s), added %d: %s; removed %d: %s' =>
         'changed dependencies, added: %3$s; removed: %5$s',
 
       'changed %d dependent task(s), added %d: %s; removed %d: %s',
         'changed dependent tasks, added: %3$s; removed: %5$s',
 
       'DEPENDENT %d TASK(s)' => array(
         'DEPENDENT TASK',
         'DEPENDENT TASKS',
       ),
 
       'DEPENDS ON %d TASK(S)' => array(
         'DEPENDS ON TASK',
         'DEPENDS ON TASKS',
       ),
 
       'DIFFERENTIAL %d REVISION(S)' => array(
         'DIFFERENTIAL REVISION',
         'DIFFERENTIAL REVISIONS',
       ),
 
       'added %d revision(s): %s' => array(
         'added revision: %2$s',
         'added revisions: %2$s',
       ),
 
       'removed %d revision(s): %s' => array(
         'removed revision: %2$s',
         'removed revisions: %2$s',
       ),
 
       'changed %d revision(s), added %d: %s; removed %d: %s' =>
         'changed revisions, added %3$s; removed %5$s',
 
       'There are %d raw fact(s) in storage.' => array(
         'There is %d raw fact in storage.',
         'There are %d raw facts in storage.',
       ),
 
       'There are %d aggregate fact(s) in storage.' => array(
         'There is %d aggregate fact in storage.',
         'There are %d aggregate facts in storage.',
       ),
 
       '%d Commit(s) Awaiting Audit' => array(
         '%d Commit Awaiting Audit',
         '%d Commits Awaiting Audit',
       ),
 
       '%d Problem Commit(s)' => array(
         '%d Problem Commit',
         '%d Problem Commits',
       ),
 
       '%d Review(s) Blocking Others' => array(
         '%d Review Blocking Others',
         '%d Reviews Blocking Others',
       ),
 
       '%d Review(s) Need Attention' => array(
         '%d Review Needs Attention',
         '%d Reviews Need Attention',
       ),
 
       '%d Review(s) Waiting on Others' => array(
         '%d Review Waiting on Others',
         '%d Reviews Waiting on Others',
       ),
 
       '%d Flagged Object(s)' => array(
         '%d Flagged Object',
         '%d Flagged Objects',
       ),
 
       '%d Unbreak Now Task(s)!' => array(
         '%d Unbreak Now Task!',
         '%d Unbreak Now Tasks!',
       ),
 
       '%d Assigned Task(s)' => array(
         '%d Assigned Task',
         '%d Assigned Tasks',
       ),
 
       'Show %d Lint Message(s)' => array(
         'Show %d Lint Message',
         'Show %d Lint Messages',
       ),
       'Hide %d Lint Message(s)' => array(
         'Hide %d Lint Message',
         'Hide %d Lint Messages',
       ),
       'Switch for %d Lint Message(s)' => array(
         'Switch for %d Lint Message',
         'Switch for %d Lint Messages',
       ),
       '%d Lint Message(s)' => array(
         '%d Lint Message',
         '%d Lint Messages',
       ),
 
       'This is a binary file. It is %s byte(s) in length.' => array(
         'This is a binary file. It is %s byte in length.',
         'This is a binary file. It is %s bytes in length.',
       ),
 
       '%d Action(s) Have No Effect' => array(
         'Action Has No Effect',
         'Actions Have No Effect',
       ),
 
       '%d Action(s) With No Effect' => array(
         'Action With No Effect',
         'Actions With No Effect',
       ),
 
       '%s added %d subscriber(s): %s.' => array(
         array(
           '%s added a subscriber: %3$s.',
           '%s added subscribers: %3$s.',
         ),
       ),
 
       '%s removed %d subscriber(s): %s.' => array(
         array(
           '%s removed a subscriber: %3$s.',
           '%s removed subscribers: %3$s.',
         ),
       ),
 
       '%s added %d participant(s): %s.' => array(
         array(
           '%s added a participant: %3$s.',
           '%s added participants: %3$s.',
         ),
       ),
 
       '%s removed %d participant(s): %s.' => array(
         array(
           '%s removed a participant: %3$s.',
           '%s removed participants: %3$s.',
         ),
       ),
 
       '%s Line(s)' => array(
         '%s Line',
         '%s Lines',
       ),
 
       "Indexing %d object(s) of type %s." => array(
         "Indexing %d object of type %s.",
         "Indexing %d object of type %s.",
       ),
 
       'Run these %d command(s):' => array(
         'Run this command:',
         'Run these commands:',
       ),
 
       'Install these %d PHP extension(s):' => array(
         'Install this PHP extension:',
         'Install these PHP extensions:',
       ),
 
       'The current Phabricator configuration has these %d value(s):' => array(
         'The current Phabricator configuration has this value:',
         'The current Phabricator configuration has these values:',
       ),
 
       'To update these %d value(s), run these command(s) from the command line:'
       => array(
         'To update this value, run this command from the command line:',
         'To update these values, run these commands from the command line:',
       ),
 
       'You can update these %d value(s) here:' => array(
         'You can update this value here:',
         'You can update these values here:',
       ),
 
       'The current PHP configuration has these %d value(s):' => array(
         'The current PHP configuration has this value:',
         'The current PHP configuration has these values:',
       ),
 
       'To update these %d value(s), edit your PHP configuration file.' => array(
         'To update this %d value, edit your PHP configuration file.',
         'To update these %d values, edit your PHP configuration file.',
       ),
 
       'To update these %d value(s), edit your PHP configuration file, located '.
       'here:' => array(
         'To update this value, edit your PHP configuration file, located '.
         'here:',
         'To update these values, edit your PHP configuration file, located '.
         'here:',
       ),
 
       'PHP also loaded these configuration file(s):' => array(
         'PHP also loaded this configuration file:',
         'PHP also loaded these configuration files:',
       ),
 
       'You have %d unresolved setup issue(s)...' => array(
         'You have an unresolved setup issue...',
         'You have %d unresolved setup issues...',
       ),
 
       '%s added %d inline comment(s).' => array(
         array(
           '%s added an inline comment.',
           '%s added inline comments.',
         ),
       ),
 
+      '%d comment(s)' => array('%d comment', '%d comments'),
+      '%d rejection(s)' => array('%d rejection', '%d rejections'),
+      '%d update(s)' => array('%d update', '%d updates'),
+
     );
   }
 
 }
diff --git a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
index 2d4d5ec19..7a3a96fb7 100644
--- a/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
+++ b/src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
@@ -1,1171 +1,1179 @@
 <?php
 
 final class PhabricatorBuiltinPatchList extends PhabricatorSQLPatchList {
 
   public function getNamespace() {
     return 'phabricator';
   }
 
   private function getPatchPath($file) {
     $root = dirname(phutil_get_library_root('phabricator'));
     $path = $root.'/resources/sql/patches/'.$file;
 
     // Make sure it exists.
     Filesystem::readFile($path);
 
     return $path;
   }
 
   public function getPatches() {
     return array(
       'db.audit' => array(
         'type'  => 'db',
         'name'  => 'audit',
         'after' => array( /* First Patch */ ),
       ),
       'db.calendar' => array(
         'type'  => 'db',
         'name'  => 'calendar',
       ),
       'db.chatlog' => array(
         'type'  => 'db',
         'name'  => 'chatlog',
       ),
       'db.conduit' => array(
         'type'  => 'db',
         'name'  => 'conduit',
       ),
       'db.countdown' => array(
         'type'  => 'db',
         'name'  => 'countdown',
       ),
       'db.daemon' => array(
         'type'  => 'db',
         'name'  => 'daemon',
       ),
       'db.differential' => array(
         'type'  => 'db',
         'name'  => 'differential',
       ),
       'db.draft' => array(
         'type'  => 'db',
         'name'  => 'draft',
       ),
       'db.drydock' => array(
         'type'  => 'db',
         'name'  => 'drydock',
       ),
       'db.feed' => array(
         'type'  => 'db',
         'name'  => 'feed',
       ),
       'db.file' => array(
         'type'  => 'db',
         'name'  => 'file',
       ),
       'db.flag' => array(
         'type'  => 'db',
         'name'  => 'flag',
       ),
       'db.harbormaster' => array(
         'type'  => 'db',
         'name'  => 'harbormaster',
       ),
       'db.herald' => array(
         'type'  => 'db',
         'name'  => 'herald',
       ),
       'db.maniphest' => array(
         'type'  => 'db',
         'name'  => 'maniphest',
       ),
       'db.meta_data' => array(
         'type'  => 'db',
         'name'  => 'meta_data',
       ),
       'db.metamta' => array(
         'type'  => 'db',
         'name'  => 'metamta',
       ),
       'db.oauth_server' => array(
         'type'  => 'db',
         'name'  => 'oauth_server',
       ),
       'db.owners' => array(
         'type'  => 'db',
         'name'  => 'owners',
       ),
       'db.pastebin' => array(
         'type'  => 'db',
         'name'  => 'pastebin',
       ),
       'db.phame' => array(
         'type'  => 'db',
         'name'  => 'phame',
       ),
       'db.phriction' => array(
         'type'  => 'db',
         'name'  => 'phriction',
       ),
       'db.project' => array(
         'type'  => 'db',
         'name'  => 'project',
       ),
       'db.repository' => array(
         'type'  => 'db',
         'name'  => 'repository',
       ),
       'db.search' => array(
         'type'  => 'db',
         'name'  => 'search',
       ),
       'db.slowvote' => array(
         'type'  => 'db',
         'name'  => 'slowvote',
       ),
       'db.timeline' => array(
         'type'  => 'db',
         'name'  => 'timeline',
       ),
       'db.user' => array(
         'type'  => 'db',
         'name'  => 'user',
       ),
       'db.worker' => array(
         'type'  => 'db',
         'name'  => 'worker',
       ),
       'db.xhpastview' => array(
         'type'  => 'db',
         'name'  => 'xhpastview',
       ),
       'db.cache' => array(
         'type'  => 'db',
         'name'  => 'cache',
       ),
       'db.fact' => array(
         'type'  => 'db',
         'name'  => 'fact',
       ),
       'db.ponder' => array(
         'type'    => 'db',
         'name'    => 'ponder',
       ),
       'db.xhprof' => array(
         'type'    => 'db',
         'name'    => 'xhprof',
       ),
       'db.pholio' => array(
         'type'    => 'db',
         'name'    => 'pholio',
       ),
       'db.conpherence' => array(
         'type'    => 'db',
         'name'    => 'conpherence',
       ),
       'db.config' => array(
         'type'    => 'db',
         'name'    => 'config',
       ),
       'db.token' => array(
         'type'    => 'db',
         'name'    => 'token',
       ),
+      'db.releeph' => array(
+        'type'    => 'db',
+        'name'    => 'releeph',
+      ),
       '0000.legacy.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('0000.legacy.sql'),
         'legacy'  => 0,
       ),
       '000.project.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('000.project.sql'),
         'legacy'  => 0,
       ),
       '001.maniphest_projects.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('001.maniphest_projects.sql'),
         'legacy'  => 1,
       ),
       '002.oauth.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('002.oauth.sql'),
         'legacy'  => 2,
       ),
       '003.more_oauth.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('003.more_oauth.sql'),
         'legacy'  => 3,
       ),
       '004.daemonrepos.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('004.daemonrepos.sql'),
         'legacy'  => 4,
       ),
       '005.workers.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('005.workers.sql'),
         'legacy'  => 5,
       ),
       '006.repository.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('006.repository.sql'),
         'legacy'  => 6,
       ),
       '007.daemonlog.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('007.daemonlog.sql'),
         'legacy'  => 7,
       ),
       '008.repoopt.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('008.repoopt.sql'),
         'legacy'  => 8,
       ),
       '009.repo_summary.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('009.repo_summary.sql'),
         'legacy'  => 9,
       ),
       '010.herald.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('010.herald.sql'),
         'legacy'  => 10,
       ),
       '011.badcommit.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('011.badcommit.sql'),
         'legacy'  => 11,
       ),
       '012.dropphidtype.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('012.dropphidtype.sql'),
         'legacy'  => 12,
       ),
       '013.commitdetail.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('013.commitdetail.sql'),
         'legacy'  => 13,
       ),
       '014.shortcuts.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('014.shortcuts.sql'),
         'legacy'  => 14,
       ),
       '015.preferences.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('015.preferences.sql'),
         'legacy'  => 15,
       ),
       '016.userrealnameindex.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('016.userrealnameindex.sql'),
         'legacy'  => 16,
       ),
       '017.sessionkeys.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('017.sessionkeys.sql'),
         'legacy'  => 17,
       ),
       '018.owners.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('018.owners.sql'),
         'legacy'  => 18,
       ),
       '019.arcprojects.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('019.arcprojects.sql'),
         'legacy'  => 19,
       ),
       '020.pathcapital.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('020.pathcapital.sql'),
         'legacy'  => 20,
       ),
       '021.xhpastview.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('021.xhpastview.sql'),
         'legacy'  => 21,
       ),
       '022.differentialcommit.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('022.differentialcommit.sql'),
         'legacy'  => 22,
       ),
       '023.dxkeys.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('023.dxkeys.sql'),
         'legacy'  => 23,
       ),
       '024.mlistkeys.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('024.mlistkeys.sql'),
         'legacy'  => 24,
       ),
       '025.commentopt.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('025.commentopt.sql'),
         'legacy'  => 25,
       ),
       '026.diffpropkey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('026.diffpropkey.sql'),
         'legacy'  => 26,
       ),
       '027.metamtakeys.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('027.metamtakeys.sql'),
         'legacy'  => 27,
       ),
       '028.systemagent.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('028.systemagent.sql'),
         'legacy'  => 28,
       ),
       '029.cursors.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('029.cursors.sql'),
         'legacy'  => 29,
       ),
       '030.imagemacro.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('030.imagemacro.sql'),
         'legacy'  => 30,
       ),
       '031.workerrace.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('031.workerrace.sql'),
         'legacy'  => 31,
       ),
       '032.viewtime.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('032.viewtime.sql'),
         'legacy'  => 32,
       ),
       '033.privtest.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('033.privtest.sql'),
         'legacy'  => 33,
       ),
       '034.savedheader.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('034.savedheader.sql'),
         'legacy'  => 34,
       ),
       '035.proxyimage.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('035.proxyimage.sql'),
         'legacy'  => 35,
       ),
       '036.mailkey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('036.mailkey.sql'),
         'legacy'  => 36,
       ),
       '037.setuptest.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('037.setuptest.sql'),
         'legacy'  => 37,
       ),
       '038.admin.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('038.admin.sql'),
         'legacy'  => 38,
       ),
       '039.userlog.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('039.userlog.sql'),
         'legacy'  => 39,
       ),
       '040.transform.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('040.transform.sql'),
         'legacy'  => 40,
       ),
       '041.heraldrepetition.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('041.heraldrepetition.sql'),
         'legacy'  => 41,
       ),
       '042.commentmetadata.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('042.commentmetadata.sql'),
         'legacy'  => 42,
       ),
       '043.pastebin.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('043.pastebin.sql'),
         'legacy'  => 43,
       ),
       '044.countdown.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('044.countdown.sql'),
         'legacy'  => 44,
       ),
       '045.timezone.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('045.timezone.sql'),
         'legacy'  => 45,
       ),
       '046.conduittoken.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('046.conduittoken.sql'),
         'legacy'  => 46,
       ),
       '047.projectstatus.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('047.projectstatus.sql'),
         'legacy'  => 47,
       ),
       '048.relationshipkeys.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('048.relationshipkeys.sql'),
         'legacy'  => 48,
       ),
       '049.projectowner.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('049.projectowner.sql'),
         'legacy'  => 49,
       ),
       '050.taskdenormal.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('050.taskdenormal.sql'),
         'legacy'  => 50,
       ),
       '051.projectfilter.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('051.projectfilter.sql'),
         'legacy'  => 51,
       ),
       '052.pastelanguage.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('052.pastelanguage.sql'),
         'legacy'  => 52,
       ),
       '053.feed.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('053.feed.sql'),
         'legacy'  => 53,
       ),
       '054.subscribers.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('054.subscribers.sql'),
         'legacy'  => 54,
       ),
       '055.add_author_to_files.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('055.add_author_to_files.sql'),
         'legacy'  => 55,
       ),
       '056.slowvote.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('056.slowvote.sql'),
         'legacy'  => 56,
       ),
       '057.parsecache.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('057.parsecache.sql'),
         'legacy'  => 57,
       ),
       '058.missingkeys.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('058.missingkeys.sql'),
         'legacy'  => 58,
       ),
       '059.engines.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('059.engines.php'),
         'legacy'  => 59,
       ),
       '060.phriction.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('060.phriction.sql'),
         'legacy'  => 60,
       ),
       '061.phrictioncontent.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('061.phrictioncontent.sql'),
         'legacy'  => 61,
       ),
       '062.phrictionmenu.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('062.phrictionmenu.sql'),
         'legacy'  => 62,
       ),
       '063.pasteforks.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('063.pasteforks.sql'),
         'legacy'  => 63,
       ),
       '064.subprojects.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('064.subprojects.sql'),
         'legacy'  => 64,
       ),
       '065.sshkeys.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('065.sshkeys.sql'),
         'legacy'  => 65,
       ),
       '066.phrictioncontent.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('066.phrictioncontent.sql'),
         'legacy'  => 66,
       ),
       '067.preferences.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('067.preferences.sql'),
         'legacy'  => 67,
       ),
       '068.maniphestauxiliarystorage.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('068.maniphestauxiliarystorage.sql'),
         'legacy'  => 68,
       ),
       '069.heraldxscript.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('069.heraldxscript.sql'),
         'legacy'  => 69,
       ),
       '070.differentialaux.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('070.differentialaux.sql'),
         'legacy'  => 70,
       ),
       '071.contentsource.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('071.contentsource.sql'),
         'legacy'  => 71,
       ),
       '072.blamerevert.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('072.blamerevert.sql'),
         'legacy'  => 72,
       ),
       '073.reposymbols.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('073.reposymbols.sql'),
         'legacy'  => 73,
       ),
       '074.affectedpath.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('074.affectedpath.sql'),
         'legacy'  => 74,
       ),
       '075.revisionhash.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('075.revisionhash.sql'),
         'legacy'  => 75,
       ),
       '076.indexedlanguages.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('076.indexedlanguages.sql'),
         'legacy'  => 76,
       ),
       '077.originalemail.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('077.originalemail.sql'),
         'legacy'  => 77,
       ),
       '078.nametoken.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('078.nametoken.sql'),
         'legacy'  => 78,
       ),
       '079.nametokenindex.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('079.nametokenindex.php'),
         'legacy'  => 79,
       ),
       '080.filekeys.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('080.filekeys.sql'),
         'legacy'  => 80,
       ),
       '081.filekeys.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('081.filekeys.php'),
         'legacy'  => 81,
       ),
       '082.xactionkey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('082.xactionkey.sql'),
         'legacy'  => 82,
       ),
       '083.dxviewtime.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('083.dxviewtime.sql'),
         'legacy'  => 83,
       ),
       '084.pasteauthorkey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('084.pasteauthorkey.sql'),
         'legacy'  => 84,
       ),
       '085.packagecommitrelationship.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('085.packagecommitrelationship.sql'),
         'legacy'  => 85,
       ),
       '086.formeraffil.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('086.formeraffil.sql'),
         'legacy'  => 86,
       ),
       '087.phrictiondelete.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('087.phrictiondelete.sql'),
         'legacy'  => 87,
       ),
       '088.audit.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('088.audit.sql'),
         'legacy'  => 88,
       ),
       '089.projectwiki.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('089.projectwiki.sql'),
         'legacy'  => 89,
       ),
       '090.forceuniqueprojectnames.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('090.forceuniqueprojectnames.php'),
         'legacy'  => 90,
       ),
       '091.uniqueslugkey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('091.uniqueslugkey.sql'),
         'legacy'  => 91,
       ),
       '092.dropgithubnotification.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('092.dropgithubnotification.sql'),
         'legacy'  => 92,
       ),
       '093.gitremotes.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('093.gitremotes.php'),
         'legacy'  => 93,
       ),
       '094.phrictioncolumn.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('094.phrictioncolumn.sql'),
         'legacy'  => 94,
       ),
       '095.directory.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('095.directory.sql'),
         'legacy'  => 95,
       ),
       '096.filename.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('096.filename.sql'),
         'legacy'  => 96,
       ),
       '097.heraldruletypes.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('097.heraldruletypes.sql'),
         'legacy'  => 97,
       ),
       '098.heraldruletypemigration.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('098.heraldruletypemigration.php'),
         'legacy'  => 98,
       ),
       '099.drydock.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('099.drydock.sql'),
         'legacy'  => 99,
       ),
       '100.projectxaction.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('100.projectxaction.sql'),
         'legacy'  => 100,
       ),
       '101.heraldruleapplied.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('101.heraldruleapplied.sql'),
         'legacy'  => 101,
       ),
       '102.heraldcleanup.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('102.heraldcleanup.php'),
         'legacy'  => 102,
       ),
       '103.heraldedithistory.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('103.heraldedithistory.sql'),
         'legacy'  => 103,
       ),
       '104.searchkey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('104.searchkey.sql'),
         'legacy'  => 104,
       ),
       '105.mimetype.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('105.mimetype.sql'),
         'legacy'  => 105,
       ),
       '106.chatlog.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('106.chatlog.sql'),
         'legacy'  => 106,
       ),
       '107.oauthserver.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('107.oauthserver.sql'),
         'legacy'  => 107,
       ),
       '108.oauthscope.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('108.oauthscope.sql'),
         'legacy'  => 108,
       ),
       '109.oauthclientphidkey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('109.oauthclientphidkey.sql'),
         'legacy'  => 109,
       ),
       '110.commitaudit.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('110.commitaudit.sql'),
         'legacy'  => 110,
       ),
       '111.commitauditmigration.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('111.commitauditmigration.php'),
         'legacy'  => 111,
       ),
       '112.oauthaccesscoderedirecturi.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('112.oauthaccesscoderedirecturi.sql'),
         'legacy'  => 112,
       ),
       '113.lastreviewer.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('113.lastreviewer.sql'),
         'legacy'  => 113,
       ),
       '114.auditrequest.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('114.auditrequest.sql'),
         'legacy'  => 114,
       ),
       '115.prepareutf8.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('115.prepareutf8.sql'),
         'legacy'  => 115,
       ),
       '116.utf8-backup-first-expect-wait.sql' => array(
         'type'    => 'sql',
         'name'    =>
           $this->getPatchPath('116.utf8-backup-first-expect-wait.sql'),
         'legacy'  => 116,
       ),
       '117.repositorydescription.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('117.repositorydescription.php'),
         'legacy'  => 117,
       ),
       '118.auditinline.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('118.auditinline.sql'),
         'legacy'  => 118,
       ),
       '119.filehash.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('119.filehash.sql'),
         'legacy'  => 119,
       ),
       '120.noop.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('120.noop.sql'),
         'legacy'  => 120,
       ),
       '121.drydocklog.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('121.drydocklog.sql'),
         'legacy'  => 121,
       ),
       '122.flag.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('122.flag.sql'),
         'legacy'  => 122,
       ),
       '123.heraldrulelog.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('123.heraldrulelog.sql'),
         'legacy'  => 123,
       ),
       '124.subpriority.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('124.subpriority.sql'),
         'legacy'  => 124,
       ),
       '125.ipv6.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('125.ipv6.sql'),
         'legacy'  => 125,
       ),
       '126.edges.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('126.edges.sql'),
         'legacy'  => 126,
       ),
       '127.userkeybody.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('127.userkeybody.sql'),
         'legacy'  => 127,
       ),
       '128.phabricatorcom.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('128.phabricatorcom.sql'),
         'legacy'  => 128,
       ),
       '129.savedquery.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('129.savedquery.sql'),
         'legacy'  => 129,
       ),
       '130.denormalrevisionquery.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('130.denormalrevisionquery.sql'),
         'legacy'  => 130,
       ),
       '131.migraterevisionquery.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('131.migraterevisionquery.php'),
         'legacy'  => 131,
       ),
       '132.phame.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('132.phame.sql'),
         'legacy'  => 132,
       ),
       '133.imagemacro.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('133.imagemacro.sql'),
         'legacy'  => 133,
       ),
       '134.emptysearch.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('134.emptysearch.sql'),
         'legacy'  => 134,
       ),
       '135.datecommitted.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('135.datecommitted.sql'),
         'legacy'  => 135,
       ),
       '136.sex.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('136.sex.sql'),
         'legacy'  => 136,
       ),
       '137.auditmetadata.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('137.auditmetadata.sql'),
         'legacy'  => 137,
       ),
       '138.notification.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('138.notification.sql'),
       ),
       'holidays.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('holidays.sql'),
       ),
       'userstatus.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('userstatus.sql'),
       ),
       'emailtable.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('emailtable.sql'),
       ),
       'emailtableport.sql' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('emailtableport.php'),
       ),
       'emailtableremove.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('emailtableremove.sql'),
       ),
       'phiddrop.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('phiddrop.sql'),
       ),
       'testdatabase.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('testdatabase.sql'),
       ),
       'ldapinfo.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('ldapinfo.sql'),
       ),
       'threadtopic.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('threadtopic.sql'),
       ),
       'usertranslation.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('usertranslation.sql'),
       ),
       'differentialbookmarks.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('differentialbookmarks.sql'),
       ),
       'harbormasterobject.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('harbormasterobject.sql'),
       ),
       'markupcache.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('markupcache.sql'),
       ),
       'maniphestxcache.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('maniphestxcache.sql'),
       ),
       'migrate-maniphest-dependencies.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('migrate-maniphest-dependencies.php'),
       ),
       'migrate-differential-dependencies.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath(
           'migrate-differential-dependencies.php'),
       ),
       'phameblog.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('phameblog.sql'),
       ),
       'migrate-maniphest-revisions.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('migrate-maniphest-revisions.php'),
       ),
       'daemonstatus.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('daemonstatus.sql'),
       ),
       'symbolcontexts.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('symbolcontexts.sql'),
       ),
       'migrate-project-edges.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('migrate-project-edges.php'),
       ),
       'fact-raw.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('fact-raw.sql'),
       ),
       'ponder.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('ponder.sql')
       ),
       'policy-project.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('policy-project.sql'),
       ),
       'daemonstatuskey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('daemonstatuskey.sql'),
       ),
       'edgetype.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('edgetype.sql'),
       ),
       'ponder-comments.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('ponder-comments.sql'),
       ),
       'pastepolicy.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('pastepolicy.sql'),
       ),
       'xhprof.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('xhprof.sql'),
       ),
       'draft-metadata.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('draft-metadata.sql'),
       ),
       'phamedomain.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('phamedomain.sql'),
       ),
       'ponder-mailkey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('ponder-mailkey.sql'),
       ),
       'ponder-mailkey-populate.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('ponder-mailkey-populate.php'),
       ),
       'phamepolicy.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('phamepolicy.sql'),
       ),
       'phameoneblog.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('phameoneblog.sql'),
       ),
       'statustxt.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('statustxt.sql'),
       ),
       'daemontaskarchive.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('daemontaskarchive.sql'),
       ),
       'drydocktaskid.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('drydocktaskid.sql'),
       ),
       'drydockresoucetype.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('drydockresourcetype.sql'),
       ),
       'liskcounters.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('liskcounters.sql'),
       ),
       'liskcounters.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('liskcounters.php'),
       ),
       'dropfileproxyimage.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('dropfileproxyimage.sql'),
       ),
       'repository-lint.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('repository-lint.sql'),
       ),
       'liskcounters-task.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('liskcounters-task.sql'),
       ),
       'pholio.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('pholio.sql'),
       ),
       'owners-exclude.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('owners-exclude.sql'),
       ),
       '20121209.pholioxactions.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20121209.pholioxactions.sql'),
       ),
       '20121209.xmacroadd.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20121209.xmacroadd.sql'),
       ),
       '20121209.xmacromigrate.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('20121209.xmacromigrate.php'),
       ),
       '20121209.xmacromigratekey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20121209.xmacromigratekey.sql'),
       ),
       '20121220.generalcache.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20121220.generalcache.sql'),
       ),
       '20121226.config.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20121226.config.sql'),
       ),
       '20130101.confxaction.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130101.confxaction.sql'),
       ),
       '20130102.metamtareceivedmailmessageidhash.sql' => array(
         'type'    => 'sql',
         'name'    =>
           $this->getPatchPath('20130102.metamtareceivedmailmessageidhash.sql'),
       ),
       '20130103.filemetadata.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130103.filemetadata.sql'),
       ),
       '20130111.conpherence.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130111.conpherence.sql'),
       ),
       '20130127.altheraldtranscript.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130127.altheraldtranscript.sql'),
       ),
       '20130201.revisionunsubscribed.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('20130201.revisionunsubscribed.php'),
       ),
       '20130201.revisionunsubscribed.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130201.revisionunsubscribed.sql'),
       ),
       '20130131.conpherencepics.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130131.conpherencepics.sql'),
       ),
       '20130214.chatlogchannel.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130214.chatlogchannel.sql'),
       ),
       '20130214.chatlogchannelid.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130214.chatlogchannelid.sql'),
       ),
       '20130214.token.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130214.token.sql'),
       ),
       '20130215.phabricatorfileaddttl.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130215.phabricatorfileaddttl.sql'),
       ),
       '20130217.cachettl.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130217.cachettl.sql'),
       ),
       '20130218.updatechannelid.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('20130218.updatechannelid.php'),
       ),
       '20130218.longdaemon.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130218.longdaemon.sql'),
       ),
       '20130219.commitsummary.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130219.commitsummary.sql'),
       ),
       '20130219.commitsummarymig.php' => array(
         'type'    => 'php',
         'name'    => $this->getPatchPath('20130219.commitsummarymig.php'),
       ),
       '20130222.dropchannel.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130222.dropchannel.sql'),
       ),
       '20130226.commitkey.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130226.commitkey.sql'),
       ),
       '20131302.maniphestvalue.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20131302.maniphestvalue.sql'),
       ),
       '20130304.lintauthor.sql' => array(
         'type'    => 'sql',
         'name'    => $this->getPatchPath('20130304.lintauthor.sql'),
       ),
+      'releeph.sql' => array(
+        'type'    => 'sql',
+        'name'    => $this->getPatchPath('releeph.sql'),
+      ),
     );
   }
 
 }
diff --git a/webroot/rsrc/css/application/releeph/releeph-branch.css b/webroot/rsrc/css/application/releeph/releeph-branch.css
new file mode 100644
index 000000000..2bc7c83a7
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-branch.css
@@ -0,0 +1,79 @@
+/**
+ * @provides releeph-branch
+ */
+
+.releeph-branch-box {
+  margin-bottom: .5em;
+  padding: .5em .5em .5em;
+
+  border: 2px solid #d5d5d5;
+  /*border-top-color: #D5D5D5;
+  border-right-color: #BBB;
+  border-bottom-color: #A4A4A4;
+  border-left-color: #BBB;*/
+
+  background: #bbb;
+}
+
+/* Types of branch */
+
+.releeph-branch-box-named {
+  background: #ddd;
+}
+
+.releeph-branch-box-latest {
+  background: #ffd;
+}
+
+/* Branch symbolic name and full name */
+
+.releeph-branch-box .names {
+  width: 25em;
+  float: left;
+  margin-bottom: 1em;
+}
+
+.releeph-branch-box .names h1 {
+  font-size: 125%;
+  padding: 0px;
+}
+
+.releeph-branch-box .names h2 {
+  font-weight: normal;
+  font-size: 85%;
+}
+
+/* Date info */
+
+.releeph-branch-box .date-info {
+  width: 10%;
+  float: left;
+  color: #555;
+  margin-bottom: .3em;
+}
+
+/* Statistics table */
+
+.releeph-branch-box .request-statistics {
+  float: right;
+  padding-right: 2em;
+  font-size: 85%;
+}
+
+.releeph-branch-box .request-statistics th {
+  width: 1em;
+  text-align: right;
+  padding-right: .4em;
+  padding-left: .4em;
+}
+
+.releeph-branch-box .request-statistics td {
+  white-space: nowrap;
+  font-style: italic;
+}
+
+/* Buttons */
+
+.releeph-branch-box .buttons {
+  float: right;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-colors.css b/webroot/rsrc/css/application/releeph/releeph-colors.css
new file mode 100644
index 000000000..481ff7031
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-colors.css
@@ -0,0 +1,35 @@
+/**
+ * @provides releeph-colors
+ */
+
+.releeph-border-color-failed {
+  border-color: #d2d;
+}
+
+.releeph-border-color-requested {
+  border-color: #ddd;
+}
+
+.releeph-border-color-comment {
+  border-color: #ddd;
+}
+
+.releeph-border-color-needs-pick {
+  border-color: #096;
+}
+
+.releeph-border-color-rejected {
+  border-color: #d00;
+}
+
+.releeph-border-color-needs-revert {
+  border-color: #d00;
+}
+
+.releeph-border-color-abandoned {
+  border-color: #222;
+}
+
+.releeph-border-color-picked {
+  border-color: #069;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-core.css b/webroot/rsrc/css/application/releeph/releeph-core.css
new file mode 100644
index 000000000..fdeb2810c
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-core.css
@@ -0,0 +1,199 @@
+/**
+ * @provides releeph-core
+ */
+
+.releeph-request-header {
+  margin: .5em 2em 3em;
+
+  /**
+   * Copied from the old .differential-panel, present in commit
+   * f04d8ab1a747dc9719d378d9286088b677ce224c
+   *
+   * (As is the <h1> code below)
+   */
+  max-width:    1120px;
+  border:       1px solid #666622;
+  background:   #efefdf;
+  padding:      15px 20px;
+  font-size:    13px;
+}
+
+.releeph-request-header h1 {
+  width: 100%;
+  border-bottom: 1px solid #aaaa99;
+  padding-bottom: 8px;
+  margin-bottom: 8px;
+  position: relative;
+}
+
+.releeph-request-header .focus-char {
+  left: -10px;
+  display: none;
+  float: left;
+  position: absolute;
+  top: 0px;
+  left: -1em;
+
+  font-weight: bold;
+
+  color: #880;
+  font-family: "Hiragino Kaku Gothic Pro", "Osaka", "Zapf Dingbats";
+}
+
+.releeph-request-header.focus .focus-char {
+  display: block;
+}
+
+.releeph-request-header-border {
+  border-width: 1px 10px 1px;
+  border-color: #ddd;
+}
+
+
+/* Laying out properties / fields */
+
+.releeph-request-header table.panes {
+  width: 100%;
+}
+
+.releeph-request-header table.panes td.side {
+  width: 50%;
+  max-width: 1em;
+}
+
+.releeph-request-header table.panes td.side.left {
+  padding-right: 20px;
+  border-right: 3px solid #bbb;
+}
+
+.releeph-request-header table.panes td.side.right {
+  padding-left: 20px;
+}
+
+.releeph-request-header table.panes td.side table.fields {
+  width: 100%;
+}
+
+.releeph-request-header table.panes td.side table.fields tr {
+  vertical-align: middle;
+}
+
+.releeph-request-header table.panes td.side table.fields th {
+  font-weight: bold;
+  text-align: right;
+  padding-right: 1em;
+  white-space: nowrap;
+}
+
+.releeph-request-header table.panes td.side table.fields td {
+  width: 100%; /* wide! */
+  max-width: 1em;
+}
+
+
+/* Buttons */
+
+.releeph-request-header .button-divider {
+  clear: both;
+  margin-top: 1.5em;
+  border-top: 1px solid #bbb;
+}
+
+.releeph-request-header .buttons {
+  width: 100%;
+}
+
+.releeph-request-header .buttons tr {
+  padding: 1em;
+  margin: 3em;
+}
+
+.releeph-request-header .buttons td {
+  padding: 1em .5em 0.2em;
+}
+
+.releeph-request-header .buttons td.wide {
+  width: 100%;
+}
+
+/* Colors: match differential colors */
+
+.releeph-request-comment {
+  border-color: #ddd;
+}
+
+.releeph-request-comment-pusher {
+  background:   #8DEE8D;
+  border-color: #096;
+}
+
+.releeph-request-comment-pusher div {
+  background:   #8DEE8D;
+}
+
+/* The diff size bar */
+
+.releeph-request-header .diff-bar {
+  border: 0px;
+}
+
+.releeph-request-header .diff-bar div {
+  width: 100px;
+  border: 1px solid;
+  border-top-color: #A4A4A4;
+  border-right-color: #BBB;
+  border-bottom-color: #D5D5D5;
+  border-left-color: #BBB;
+  background: white;
+  float: left;
+  margin-right: 1em;
+}
+
+.releeph-request-header .diff-bar div div {
+  height: 10px;
+}
+
+.releeph-request-header .diff-bar span {
+  color: #555;
+}
+
+/* Rendering pick / commit errors, etc. */
+
+.releeph-request-pick-failed-event h1:before {
+  content: '\2014  ';
+}
+
+.releeph-request-pick-failed-event h1:after {
+  content: ' \2014';
+}
+
+.releeph-request-pick-failed-event h1 {
+  padding: 3px 10px 3px;
+  margin-bottom: 0.5em;
+  background: #ffb;
+  font-size: small;
+}
+
+.releeph-request-pick-failed-event div {
+  font-family: monospace;
+  margin-bottom: 1.5em;
+  padding-left: 1em;
+  width: 70em;
+}
+
+/* History view of request */
+
+.releeph-request-event-list {
+  margin: .5em 2em .5em;
+}
+
+
+/* Shorten long header-text */
+
+.releeph-header-text-truncated {
+  width: 100%;
+  float: left;
+  white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-intents.css b/webroot/rsrc/css/application/releeph/releeph-intents.css
new file mode 100644
index 000000000..9e7691149
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-intents.css
@@ -0,0 +1,37 @@
+/**
+ * @provides releeph-intents
+ */
+
+.releeph-intents .intents {
+  clear: left;
+  width: 100%;
+  margin-top: 3px;
+}
+
+.releeph-intents .arrow {
+  float: left;
+  clear: left;
+  margin-right: 0.4em;
+  padding: 8px;
+  background: transparent 0 0 no-repeat;
+}
+
+.releeph-intents .arrow.want {
+  background-image: url('/rsrc/custom/image/icon/tango/go-next.png');
+}
+
+.releeph-intents .arrow.pass {
+  background-image: url('/rsrc/custom/image/icon/tango/go-previous-gray.png');
+}
+
+.releeph-intents a {
+  margin-right: 0.4em;
+}
+
+.releeph-intents .pusher {
+  font-weight: bold;
+}
+
+.releeph-intents .requestor {
+  font-weight: normal;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-preview-branch.css b/webroot/rsrc/css/application/releeph/releeph-preview-branch.css
new file mode 100644
index 000000000..2bce6632d
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-preview-branch.css
@@ -0,0 +1,29 @@
+/**
+ * @provides releeph-preview-branch
+ */
+
+.releeph-preview-branch {
+  min-height: 4em;
+  position: relative;
+}
+
+.releeph-preview-branch .error {
+  padding-left: 22px;
+  background-repeat: no-repeat;
+  background-size: 16px auto;
+  background-image: url(/rsrc/custom/image/releeph/releeph_warning.png);
+  float: left;
+  position: absolute;
+  top: 2.5em;
+}
+
+.releeph-preview-branch .name {
+  clear: both;
+  float: left;
+  position: absolute;
+  font-family: monospace;
+  font-size: 9pt !important;
+  background: white;
+  top: 0.7em;
+  padding: 2px;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-project.css b/webroot/rsrc/css/application/releeph/releeph-project.css
new file mode 100644
index 000000000..3a14751bd
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-project.css
@@ -0,0 +1,25 @@
+/**
+ * @provides releeph-project
+ */
+
+/**
+ * ...from aphront-transaction.css
+ */
+
+.releeph-pusher {
+  background: 2px 2px no-repeat;
+  margin-top: 1em;
+  margin-bottom: 1.25em;
+  margin-right: 1em;
+  min-height: 50px;
+  padding: 2px 0px;
+
+  background-color: white;
+  border: 2px solid gray;
+  float: left;
+}
+
+.releeph-pusher-body {
+  margin-left: 54px;
+  padding: 1em;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css b/webroot/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css
new file mode 100644
index 000000000..7101f7878
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-request-differential-create-dialog.css
@@ -0,0 +1,17 @@
+/**
+ * @provides releeph-request-differential-create-dialog
+ */
+
+.releeph-request-differential-create-dialog h1 {
+  color: gray;
+  font-style: italic;
+  font-size: 16px;
+  margin-top: 0.8em;
+}
+
+.releeph-request-differential-create-dialog a {
+  font-weight: bold;
+  margin-left: 2em;
+  display: block;
+  margin-top: 1em;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-request-typeahead.css b/webroot/rsrc/css/application/releeph/releeph-request-typeahead.css
new file mode 100644
index 000000000..91a81acea
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-request-typeahead.css
@@ -0,0 +1,27 @@
+/**
+ * @provides releeph-request-typeahead-css
+ */
+
+.releeph-request-typeahead .commit-id {
+  color: #aaf; /* blue... */
+  font-family: monospace;
+  font-size: 100%;
+  display: block;
+  float: left;
+}
+
+.releeph-request-typeahead .author-info {
+  color: #080; /* ...and green, for search results! */
+  text-align: right;
+  display: block;
+  float: right;
+  padding-left: 1em;
+}
+
+.releeph-request-typeahead .focused .author-info {
+  color: #8b8;
+}
+
+.releeph-request-typeahead .summary {
+  clear: both;
+}
diff --git a/webroot/rsrc/css/application/releeph/releeph-status.css b/webroot/rsrc/css/application/releeph/releeph-status.css
new file mode 100644
index 000000000..f41330e97
--- /dev/null
+++ b/webroot/rsrc/css/application/releeph/releeph-status.css
@@ -0,0 +1,26 @@
+/**
+ * @provides releeph-status
+ */
+
+.releeph-status .description {
+  background: #d3d3d3;
+  padding: 2px 6px 3px;
+  margin-right: 4px;
+  margin-bottom: 5px;
+  display: block;
+  float: left;
+  border-radius: 8px;
+  -moz-border-radius: 8px;
+  -webkit-border-radius: 8px;
+  text-decoration: none;
+}
+
+.releeph-status .warning {
+  margin-top: 2px;
+  margin-left: 0.8em;
+  float: left;
+  padding-left: 22px;
+  background-repeat: no-repeat;
+  background-size: 16px auto;
+  background-image: url(/rsrc/custom/image/releeph/releeph_warning.png);
+}
diff --git a/webroot/rsrc/js/application/releeph/releeph-preview-branch.js b/webroot/rsrc/js/application/releeph/releeph-preview-branch.js
new file mode 100644
index 000000000..76e406bd7
--- /dev/null
+++ b/webroot/rsrc/js/application/releeph/releeph-preview-branch.js
@@ -0,0 +1,49 @@
+/**
+ * @provides javelin-behavior-releeph-preview-branch
+ * @requires javelin-behavior
+ *           javelin-dom
+ *           javelin-stratcom
+ *           javelin-uri
+ *           javelin-util
+ */
+
+JX.behavior('releeph-preview-branch', function(config) {
+
+  var uri = JX.$U(config.uri);
+  for (param_name in config.params.static) {
+    var value = config.params.static[param_name];
+    uri.setQueryParam(param_name, value);
+  }
+
+  var output = JX.$(config.outputID);
+
+  var dynamics = config.params.dynamic;
+
+  function renderPreview() {
+    for (param_name in dynamics) {
+      var node_id = dynamics[param_name];
+      var input = JX.$(node_id);
+      uri.setQueryParam(param_name, input.value);
+    }
+    var request = new JX.Request(uri, function(response) {
+      JX.DOM.setContent(output, JX.$H(response.markup));
+    });
+    request.send();
+  }
+
+  renderPreview();
+
+  for (ii in dynamics) {
+    var node_id = dynamics[ii];
+    var input = JX.$(node_id);
+    JX.DOM.listen(
+      input,
+      ['keyup', 'click', 'change'],
+      null,
+      function(e) {
+        renderPreview();
+      }
+    );
+  }
+
+});
diff --git a/webroot/rsrc/js/application/releeph/releeph-request-state-change.js b/webroot/rsrc/js/application/releeph/releeph-request-state-change.js
new file mode 100644
index 000000000..286d527b8
--- /dev/null
+++ b/webroot/rsrc/js/application/releeph/releeph-request-state-change.js
@@ -0,0 +1,145 @@
+/**
+ * @provides javelin-behavior-releeph-request-state-change
+ * @requires javelin-behavior
+ *           javelin-dom
+ *           javelin-stratcom
+ *           javelin-util
+ *           phabricator-keyboard-shortcut
+ *           phabricator-notification
+ */
+
+JX.behavior('releeph-request-state-change', function(config) {
+  var root = JX.DOM.find(document, 'div', 'releeph-request-header-list');
+
+  function getRequestHeaderNodes() {
+    return JX.DOM.scry(root, 'div', 'releeph-request-header');
+  }
+
+  /**
+   * Keyboard navigation
+   */
+  var keynav_cursor = -1;
+  var notification = new JX.Notification();
+
+  function keynavJump(manager, delta) {
+    // Calculate this everytime, because the DOM changes.
+    var headers = getRequestHeaderNodes();
+    keynav_cursor += delta;
+
+    if (keynav_cursor < 0) {
+      keynav_cursor = -1;
+      window.scrollTo(0);
+      keynavMarkup();
+      return;
+    }
+
+    if (keynav_cursor >= headers.length) {
+      keynav_cursor = headers.length - 1;
+    }
+
+    var focus = headers[keynav_cursor];
+    manager.scrollTo(focus);
+
+    keynavMarkup();
+  }
+
+  function keynavMarkup() {
+    var headers = getRequestHeaderNodes();
+    for (ii in headers) {
+      JX.DOM.alterClass(headers[ii], 'focus', ii == keynav_cursor);
+    }
+  }
+
+  function keynavAction(manager, action_name) {
+    var headers = getRequestHeaderNodes();
+    var header = headers[keynav_cursor];
+
+    if (keynav_cursor < 0) {
+      return;
+    }
+
+    var sigil = action_name;
+    var button = JX.DOM.find(header, 'a', sigil);
+    if (button) {
+      button.click();
+    }
+  }
+
+  function keynavNavigateToRequestPage() {
+    var headers = getRequestHeaderNodes();
+    var header = headers[keynav_cursor];
+    JX.DOM.find(header, 'a', 'hidden-link').click();
+  }
+
+  new JX.KeyboardShortcut('j', 'Jump to next request.')
+    .setHandler(function(manager) {
+      keynavJump(manager, +1);
+    })
+    .register();
+
+  new JX.KeyboardShortcut('k', 'Jump to previous request.')
+    .setHandler(function(manager) {
+      keynavJump(manager, -1);
+    })
+    .register();
+
+  new JX.KeyboardShortcut('a', 'Approve the selected request.')
+    .setHandler(function(manager) {
+      keynavAction(manager, 'want');
+    })
+    .register();
+
+  new JX.KeyboardShortcut('r', 'Reject the selected request.')
+    .setHandler(function(manager) {
+      keynavAction(manager, 'pass');
+    })
+    .register();
+
+  new JX.KeyboardShortcut('g', "Open selected request's page in a new tab.")
+    .setHandler(function(manager) {
+      keynavNavigateToRequestPage();
+    })
+    .register();
+
+
+  /**
+   * AJAXy state changes for request buttons.
+   */
+  function request_action(node, url) {
+    var request = new JX.Request(url, function(response) {
+      if (config.reload) {
+        window.location.reload();
+      } else {
+        var markup = JX.$H(response.markup);
+        JX.DOM.replace(node, markup);
+        keynavMarkup();
+      }
+    });
+
+    request.send();
+  }
+
+  JX.Stratcom.listen(
+    'click',
+    'releeph-request-state-change',
+    function(e) {
+      var button = e.getNode('releeph-request-state-change');
+      var node = e.getNode('releeph-request-header');
+      var url = e.getNodeData('releeph-request-state-change');
+
+      // If this button has no action, or we've already responded to the first
+      // click...
+      if (!url || button.disabled) {
+        return;
+      }
+
+      // There's a race condition here though :(
+
+      JX.DOM.alterClass(button, 'disabled', true);
+      button.disabled = true;
+
+      e.prevent();
+      request_action(node, url);
+    }
+  );
+});
diff --git a/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js b/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js
new file mode 100644
index 000000000..fd932dd73
--- /dev/null
+++ b/webroot/rsrc/js/application/releeph/releeph-request-typeahead.js
@@ -0,0 +1,84 @@
+/**
+ * @provides javelin-behavior-releeph-request-typeahead
+ * @requires javelin-behavior
+ *           javelin-util
+ *           javelin-dom
+ *           javelin-typeahead
+ *           javelin-tokenizer
+ *           javelin-typeahead-preloaded-source
+ *           javelin-typeahead-ondemand-source
+ *           javelin-dom
+ *           javelin-stratcom
+ *           javelin-util
+ */
+
+JX.behavior('releeph-request-typeahead', function(config) {
+  var root = JX.$(config.id);
+  var datasource = new JX.TypeaheadOnDemandSource(config.src);
+  var callsign = config.aux.callsign;
+
+  datasource.setAuxiliaryData(config.aux);
+
+  datasource.setTransformer(
+    function(object) {
+      var full_commit_id = object[0];
+      var short_commit_id = object[1];
+      var author = object[2];
+      var ago = object[3];
+      var summary = object[4];
+
+      var callsign_commit_id = 'r' + callsign + short_commit_id;
+
+      var box =
+        JX.$N(
+          'div',
+          {},
+          [
+            JX.$N(
+              'div',
+              { className: 'commit-id' },
+              callsign_commit_id
+            ),
+            JX.$N(
+              'div',
+              { className: 'author-info' },
+              ago + ' ago by ' + author
+            ),
+            JX.$N(
+              'div',
+              { className: 'summary' },
+              summary
+            ),
+          ]
+        );
+
+      return {
+        name: callsign_commit_id,
+        tokenizable: callsign_commit_id + ' '+ short_commit_id + ' ' + summary,
+        display: box,
+        uri: null,
+        id: full_commit_id
+      };
+    });
+
+  /**
+   * The default normalizer removes useful control characters that would help
+   * out search.  For example, I was just trying to search for a commit with
+   * the string "a_file" in the message, which was normalized to "afile".
+   */
+  datasource.setNormalizer(function(query) {
+    return query;
+  });
+
+  datasource.setMaximumResultCount(config.aux.limit);
+
+  var typeahead = new JX.Typeahead(root);
+  typeahead.setDatasource(datasource);
+
+  var placeholder = config.value || config.placeholder;
+  if (placeholder) {
+    typeahead.setPlaceholder(placeholder);
+  }
+
+  typeahead.start();
+});