diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php
index 86185280b1..85784c1c31 100644
--- a/src/__celerity_resource_map__.php
+++ b/src/__celerity_resource_map__.php
@@ -1,1927 +1,1927 @@
 <?php
 
 /**
  * This file is automatically generated. Use 'celerity_mapper.php' to rebuild
  * it.
  * @generated
  */
 
 celerity_register_resource_map(array(
   '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-calendar-view-css' =>
   array(
     'uri' => '/res/c86d9a4b/rsrc/css/aphront/calendar-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/calendar-view.css',
   ),
   'aphront-contextbar-view-css' =>
   array(
-    'uri' => '/res/3e2f3045/rsrc/css/aphront/context-bar.css',
+    'uri' => '/res/9e0c2ed7/rsrc/css/aphront/context-bar.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/context-bar.css',
   ),
   'aphront-crumbs-view-css' =>
   array(
     'uri' => '/res/9009e6bd/rsrc/css/aphront/crumbs-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/crumbs-view.css',
   ),
   'aphront-dark-console-css' =>
   array(
     'uri' => '/res/1a9f84bb/rsrc/css/aphront/dark-console.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/dark-console.css',
   ),
   'aphront-dialog-view-css' =>
   array(
     'uri' => '/res/1c0a5f75/rsrc/css/aphront/dialog-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/dialog-view.css',
   ),
   'aphront-error-view-css' =>
   array(
     'uri' => '/res/e4c5e4ed/rsrc/css/aphront/error-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/error-view.css',
   ),
   'aphront-form-view-css' =>
   array(
     'uri' => '/res/464a73e6/rsrc/css/aphront/form-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/form-view.css',
   ),
   'aphront-headsup-action-list-view-css' =>
   array(
     'uri' => '/res/84743e20/rsrc/css/aphront/headsup-action-list-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/headsup-action-list-view.css',
   ),
   'aphront-list-filter-view-css' =>
   array(
     'uri' => '/res/0f5ddaba/rsrc/css/aphront/list-filter-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/list-filter-view.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/f4157618/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-side-nav-view-css' =>
   array(
     'uri' => '/res/ba0e18dd/rsrc/css/aphront/side-nav-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/side-nav-view.css',
   ),
   'aphront-table-view-css' =>
   array(
     'uri' => '/res/f4f39a2e/rsrc/css/aphront/table-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/table-view.css',
   ),
   'aphront-tokenizer-control-css' =>
   array(
     'uri' => '/res/f530af47/rsrc/css/aphront/tokenizer.css',
     'type' => 'css',
     'requires' =>
     array(
       0 => 'aphront-typeahead-control-css',
     ),
     'disk' => '/rsrc/css/aphront/tokenizer.css',
   ),
   'aphront-typeahead-control-css' =>
   array(
     'uri' => '/res/a05236a6/rsrc/css/aphront/typeahead.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/aphront/typeahead.css',
   ),
   'differential-changeset-view-css' =>
   array(
     'uri' => '/res/2b0c9b6a/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/0bc9223a/rsrc/css/application/differential/core.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/core.css',
   ),
   'differential-inline-comment-editor' =>
   array(
     'uri' => '/res/ff5f42a9/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-dom',
       1 => 'javelin-workflow',
       2 => 'javelin-util',
       3 => 'javelin-stratcom',
       4 => 'javelin-install',
     ),
     'disk' => '/rsrc/js/application/differential/DifferentialInlineCommentEditor.js',
   ),
   'differential-local-commits-view-css' =>
   array(
     'uri' => '/res/8cdacd82/rsrc/css/application/differential/local-commits-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/local-commits-view.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/be9a95b4/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-detail-css' =>
   array(
     'uri' => '/res/33592453/rsrc/css/application/differential/revision-detail.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/revision-detail.css',
   ),
   'differential-revision-history-css' =>
   array(
     'uri' => '/res/0d7d515d/rsrc/css/application/differential/revision-history.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/differential/revision-history.css',
   ),
   'differential-table-of-contents-css' =>
   array(
     'uri' => '/res/d173445b/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/bc39d876/rsrc/css/application/diffusion/commit-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/diffusion/commit-view.css',
   ),
   'diffusion-source-css' =>
   array(
     'uri' => '/res/db4566b6/rsrc/css/application/diffusion/diffusion-source.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/diffusion/diffusion-source.css',
   ),
   'files-css' =>
   array(
     'uri' => '/res/a265a77d/rsrc/css/application/files/files.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/files/files.css',
   ),
   'herald-css' =>
   array(
     'uri' => '/res/ed5556e6/rsrc/css/application/herald/herald.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/herald/herald.css',
   ),
   'herald-rule-editor' =>
   array(
     'uri' => '/res/ec9eea63/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',
   ),
   'javelin-behavior' =>
   array(
     'uri' => '/res/0017f840/rsrc/js/javelin/lib/behavior.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-magical-init',
     ),
     'disk' => '/rsrc/js/javelin/lib/behavior.js',
   ),
-  0 =>
-  array(
-    'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js',
-    'type' => 'js',
-    'requires' =>
-    array(
-      0 => 'javelin-uri',
-      1 => 'javelin-php-serializer',
-    ),
-    'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js',
-  ),
   'javelin-behavior-aphront-basic-tokenizer' =>
   array(
     'uri' => '/res/9be30797/rsrc/js/application/core/behavior-tokenizer.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-typeahead',
       2 => 'javelin-tokenizer',
       3 => 'javelin-typeahead-preloaded-source',
       4 => 'javelin-typeahead-ondemand-source',
       5 => 'javelin-dom',
       6 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-tokenizer.js',
   ),
   'javelin-behavior-aphront-drag-and-drop' =>
   array(
     'uri' => '/res/ac21045a/rsrc/js/application/core/behavior-drag-and-drop.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-util',
       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/fa7527f9/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',
     ),
     'disk' => '/rsrc/js/application/core/behavior-drag-and-drop-textarea.js',
   ),
   'javelin-behavior-aphront-form-disable-on-submit' =>
   array(
     'uri' => '/res/6c659ede/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-countdown-timer' =>
   array(
     'uri' => '/res/5ee9cb13/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/c80156c4/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-differential-accept-with-errors' =>
   array(
     'uri' => '/res/41c4685b/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/99e1b311/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js',
+    'uri' => '/res/eb142486/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-tokenizer',
       3 => 'javelin-typeahead',
       4 => 'javelin-typeahead-preloaded-source',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js',
   ),
   'javelin-behavior-differential-comment-jump' =>
   array(
     'uri' => '/res/be77fced/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/4bb3ae9a/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/31a8ef7b/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/768b60c9/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/f5ce5987/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/6efe5cd2/rsrc/js/application/differential/behavior-populate.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-workflow',
       2 => 'javelin-util',
       3 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/differential/behavior-populate.js',
   ),
   'javelin-behavior-differential-show-all-comments' =>
   array(
     'uri' => '/res/bcc990f0/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-more' =>
   array(
     'uri' => '/res/68a8e485/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-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-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/a5cb42a5/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-files-drag-and-drop' =>
   array(
     'uri' => '/res/0e84cc42/rsrc/js/application/core/behavior-files-drag-and-drop.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-uri',
       3 => 'phabricator-drag-and-drop-file-upload',
     ),
     'disk' => '/rsrc/js/application/core/behavior-files-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-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-project-create' =>
   array(
     'uri' => '/res/85a0eaf9/rsrc/js/application/maniphest/behavior-project-create.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-stratcom',
       3 => 'javelin-workflow',
     ),
     'disk' => '/rsrc/js/application/maniphest/behavior-project-create.js',
   ),
   'javelin-behavior-maniphest-transaction-controls' =>
   array(
     'uri' => '/res/33bd237a/rsrc/js/application/maniphest/behavior-transaction-controls.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-tokenizer',
       3 => 'javelin-typeahead',
       4 => 'javelin-typeahead-preloaded-source',
     ),
     '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/44e86555/rsrc/js/application/maniphest/behavior-transaction-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-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-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/94b009e2/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-workflow',
       2 => 'javelin-json',
       3 => 'phabricator-keyboard-shortcut',
     ),
     'disk' => '/rsrc/js/application/core/behavior-keyboard-shortcuts.js',
   ),
   'javelin-behavior-phabricator-object-selector' =>
   array(
     'uri' => '/res/1f7867ca/rsrc/js/application/core/behavior-object-selector.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-request',
       3 => 'javelin-util',
       4 => 'javelin-stratcom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-object-selector.js',
   ),
   'javelin-behavior-phabricator-watch-anchor' =>
   array(
     'uri' => '/res/880e3de4/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-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-projects-resource-editor' =>
   array(
     'uri' => '/res/ffdde7d9/rsrc/js/application/projects/projects-resource-editor.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'phabricator-prefab',
       2 => 'multirow-row-manager',
       3 => 'javelin-tokenizer',
       4 => 'javelin-typeahead-preloaded-source',
       5 => 'javelin-typeahead',
       6 => 'javelin-dom',
       7 => 'javelin-json',
       8 => 'javelin-util',
     ),
     'disk' => '/rsrc/js/application/projects/projects-resource-editor.js',
   ),
   'javelin-behavior-refresh-csrf' =>
   array(
     'uri' => '/res/88beba4c/rsrc/js/application/core/behavior-refresh-csrf.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-request',
       1 => 'javelin-behavior',
       2 => 'javelin-dom',
     ),
     'disk' => '/rsrc/js/application/core/behavior-refresh-csrf.js',
   ),
   'javelin-behavior-repository-crossreference' =>
   array(
     'uri' => '/res/49472f48/rsrc/js/application/repository/repository-crossreference.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-dom',
       2 => 'javelin-uri',
     ),
     'disk' => '/rsrc/js/application/repository/repository-crossreference.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/079f49c3/rsrc/js/application/core/behavior-workflow.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-behavior',
       1 => 'javelin-stratcom',
       2 => 'javelin-workflow',
     ),
     '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/b2e8a5b6/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/f42fa6ea/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/97e25a7f/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/0e72d59b/rsrc/js/javelin/core/init.js',
     'type' => 'js',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/js/javelin/core/init.js',
   ),
   'javelin-mask' =>
   array(
     'uri' => '/res/03ef78b8/rsrc/js/javelin/lib/Mask.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-vector',
       2 => '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/b3257b7d/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',
     ),
     'disk' => '/rsrc/js/javelin/lib/Request.js',
   ),
   'javelin-resource' =>
   array(
     'uri' => '/res/1ebc5a0d/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/d7a3d1e9/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/1b1c2148/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/7dea2b98/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/7c0d631f/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/8606f519/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-uri' =>
   array(
     'uri' => '/res/393ace00/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/2180bc95/rsrc/js/javelin/core/util.js',
     'type' => 'js',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/js/javelin/core/util.js',
   ),
   'javelin-vector' =>
   array(
     'uri' => '/res/50535cb8/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/519c4e1a/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',
   ),
   'mainphest-task-detail-css' =>
   array(
     'uri' => '/res/8cf452e0/rsrc/css/application/maniphest/task-detail.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/maniphest/task-detail.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/14cb4b5d/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/552bb734/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/e6c51eb6/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',
     ),
     'disk' => '/rsrc/js/application/owners/OwnersPathEditor.js',
   ),
   'owners-path-editor-css' =>
   array(
     'uri' => '/res/9bc5332c/rsrc/css/application/owners/owners-path-editor.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/owners/owners-path-editor.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-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/89b939ae/rsrc/css/core/buttons.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/core/buttons.css',
   ),
   'phabricator-core-css' =>
   array(
     'uri' => '/res/f912ffab/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-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/63a06ad9/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',
     ),
     'disk' => '/rsrc/js/application/core/DragAndDropFileUpload.js',
   ),
   'phabricator-dropdown-menu' =>
   array(
     'uri' => '/res/d55c3771/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-feed-css' =>
   array(
     'uri' => '/res/7d1d0015/rsrc/css/application/feed/feed.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/feed/feed.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/04767571/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-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-object-selector-css' =>
   array(
     'uri' => '/res/608461d2/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-prefab' =>
   array(
     'uri' => '/res/5784a112/rsrc/js/application/core/Prefab.js',
     'type' => 'js',
     'requires' =>
     array(
       0 => 'javelin-install',
       1 => 'javelin-util',
       2 => 'javelin-dom',
     ),
     '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',
   ),
+  0 =>
+  array(
+    'uri' => '/res/b6096fdd/rsrc/js/javelin/lib/__tests__/URI.js',
+    'type' => 'js',
+    'requires' =>
+    array(
+      0 => 'javelin-uri',
+      1 => 'javelin-php-serializer',
+    ),
+    'disk' => '/rsrc/js/javelin/lib/__tests__/URI.js',
+  ),
   'phabricator-remarkup-css' =>
   array(
     'uri' => '/res/39f358b8/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/dcd87f90/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-slowvote-css' =>
   array(
     'uri' => '/res/94d20443/rsrc/css/application/slowvote/slowvote.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/slowvote/slowvote.css',
   ),
   'phabricator-standard-page-view' =>
   array(
     'uri' => '/res/ec5acaed/rsrc/css/application/base/standard-page-view.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/base/standard-page-view.css',
   ),
   'phabricator-ui-example-css' =>
   array(
     'uri' => '/res/0cef078b/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',
   ),
   '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',
   ),
   'project-edit-css' =>
   array(
     'uri' => '/res/c192b5f9/rsrc/css/application/projects/project-edit.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/application/projects/project-edit.css',
   ),
   'syntax-highlighting-css' =>
   array(
     'uri' => '/res/5669beb6/rsrc/css/core/syntax.css',
     'type' => 'css',
     'requires' =>
     array(
     ),
     'disk' => '/rsrc/css/core/syntax.css',
   ),
 ), array(
   'packages' =>
   array(
     '03ef179e' =>
     array(
       'name' => 'diffusion.pkg.css',
       'symbols' =>
       array(
         0 => 'diffusion-commit-view-css',
       ),
       'uri' => '/res/pkg/03ef179e/diffusion.pkg.css',
       'type' => 'css',
     ),
-    '15c4a6dd' =>
-    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 => 'differential-inline-comment-editor',
-      ),
-      'uri' => '/res/pkg/15c4a6dd/differential.pkg.js',
-      'type' => 'js',
-    ),
     '46547a92' =>
     array(
       'name' => 'core.pkg.js',
       'symbols' =>
       array(
         0 => 'javelin-mask',
         1 => 'javelin-workflow',
         2 => 'javelin-behavior-workflow',
         3 => 'javelin-behavior-aphront-form-disable-on-submit',
         4 => 'phabricator-keyboard-shortcut-manager',
         5 => 'phabricator-keyboard-shortcut',
         6 => 'javelin-behavior-phabricator-keyboard-shortcuts',
         7 => 'javelin-behavior-refresh-csrf',
         8 => 'javelin-behavior-phabricator-watch-anchor',
       ),
       'uri' => '/res/pkg/46547a92/core.pkg.js',
       'type' => 'js',
     ),
     '540effd7' =>
     array(
       'name' => 'typeahead.pkg.js',
       'symbols' =>
       array(
         0 => 'javelin-typeahead',
         1 => 'javelin-typeahead-normalizer',
         2 => 'javelin-typeahead-source',
         3 => 'javelin-typeahead-preloaded-source',
         4 => 'javelin-typeahead-ondemand-source',
         5 => 'javelin-tokenizer',
         6 => 'javelin-behavior-aphront-basic-tokenizer',
       ),
       'uri' => '/res/pkg/540effd7/typeahead.pkg.js',
       'type' => 'js',
     ),
     '775f5bae' =>
     array(
       'name' => 'core.pkg.css',
       'symbols' =>
       array(
         0 => 'phabricator-core-css',
         1 => 'phabricator-core-buttons-css',
         2 => 'phabricator-standard-page-view',
         3 => 'aphront-dialog-view-css',
         4 => 'aphront-form-view-css',
         5 => 'aphront-panel-view-css',
         6 => 'aphront-side-nav-view-css',
         7 => 'aphront-table-view-css',
         8 => 'aphront-crumbs-view-css',
         9 => 'aphront-tokenizer-control-css',
         10 => 'aphront-typeahead-control-css',
         11 => 'aphront-list-filter-view-css',
         12 => 'phabricator-directory-css',
         13 => 'phabricator-remarkup-css',
         14 => 'syntax-highlighting-css',
       ),
       'uri' => '/res/pkg/775f5bae/core.pkg.css',
       'type' => 'css',
     ),
     '80580cea' =>
     array(
       'name' => 'differential.pkg.css',
       'symbols' =>
       array(
         0 => 'differential-core-view-css',
         1 => 'differential-changeset-view-css',
         2 => 'differential-revision-detail-css',
         3 => 'differential-revision-history-css',
         4 => 'differential-table-of-contents-css',
         5 => 'differential-revision-comment-css',
         6 => 'differential-revision-add-comment-css',
         7 => 'differential-revision-comment-list-css',
         8 => 'phabricator-object-selector-css',
         9 => 'aphront-headsup-action-list-view-css',
         10 => 'phabricator-content-source-view-css',
         11 => 'differential-local-commits-view-css',
       ),
       'uri' => '/res/pkg/80580cea/differential.pkg.css',
       'type' => 'css',
     ),
     'b164acea' =>
     array(
       'name' => 'javelin.pkg.js',
       'symbols' =>
       array(
         0 => 'javelin-util',
         1 => 'javelin-install',
         2 => 'javelin-event',
         3 => 'javelin-stratcom',
         4 => 'javelin-behavior',
         5 => 'javelin-request',
         6 => 'javelin-vector',
         7 => 'javelin-dom',
         8 => 'javelin-json',
         9 => 'javelin-uri',
       ),
       'uri' => '/res/pkg/b164acea/javelin.pkg.js',
       'type' => 'js',
     ),
+    'e2820c7b' =>
+    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 => 'differential-inline-comment-editor',
+      ),
+      'uri' => '/res/pkg/e2820c7b/differential.pkg.js',
+      'type' => 'js',
+    ),
   ),
   'reverse' =>
   array(
     'aphront-crumbs-view-css' => '775f5bae',
     'aphront-dialog-view-css' => '775f5bae',
     'aphront-form-view-css' => '775f5bae',
     'aphront-headsup-action-list-view-css' => '80580cea',
     'aphront-list-filter-view-css' => '775f5bae',
     'aphront-panel-view-css' => '775f5bae',
     'aphront-side-nav-view-css' => '775f5bae',
     'aphront-table-view-css' => '775f5bae',
     'aphront-tokenizer-control-css' => '775f5bae',
     'aphront-typeahead-control-css' => '775f5bae',
     'differential-changeset-view-css' => '80580cea',
     'differential-core-view-css' => '80580cea',
-    'differential-inline-comment-editor' => '15c4a6dd',
+    'differential-inline-comment-editor' => 'e2820c7b',
     'differential-local-commits-view-css' => '80580cea',
     'differential-revision-add-comment-css' => '80580cea',
     'differential-revision-comment-css' => '80580cea',
     'differential-revision-comment-list-css' => '80580cea',
     'differential-revision-detail-css' => '80580cea',
     'differential-revision-history-css' => '80580cea',
     'differential-table-of-contents-css' => '80580cea',
     'diffusion-commit-view-css' => '03ef179e',
     'javelin-behavior' => 'b164acea',
     'javelin-behavior-aphront-basic-tokenizer' => '540effd7',
-    'javelin-behavior-aphront-drag-and-drop' => '15c4a6dd',
-    'javelin-behavior-aphront-drag-and-drop-textarea' => '15c4a6dd',
+    'javelin-behavior-aphront-drag-and-drop' => 'e2820c7b',
+    'javelin-behavior-aphront-drag-and-drop-textarea' => 'e2820c7b',
     'javelin-behavior-aphront-form-disable-on-submit' => '46547a92',
-    'javelin-behavior-differential-accept-with-errors' => '15c4a6dd',
-    'javelin-behavior-differential-add-reviewers-and-ccs' => '15c4a6dd',
-    'javelin-behavior-differential-comment-jump' => '15c4a6dd',
-    'javelin-behavior-differential-diff-radios' => '15c4a6dd',
-    'javelin-behavior-differential-edit-inline-comments' => '15c4a6dd',
-    'javelin-behavior-differential-feedback-preview' => '15c4a6dd',
-    'javelin-behavior-differential-keyboard-navigation' => '15c4a6dd',
-    'javelin-behavior-differential-populate' => '15c4a6dd',
-    'javelin-behavior-differential-show-more' => '15c4a6dd',
+    'javelin-behavior-differential-accept-with-errors' => 'e2820c7b',
+    'javelin-behavior-differential-add-reviewers-and-ccs' => 'e2820c7b',
+    'javelin-behavior-differential-comment-jump' => 'e2820c7b',
+    'javelin-behavior-differential-diff-radios' => 'e2820c7b',
+    'javelin-behavior-differential-edit-inline-comments' => 'e2820c7b',
+    'javelin-behavior-differential-feedback-preview' => 'e2820c7b',
+    'javelin-behavior-differential-keyboard-navigation' => 'e2820c7b',
+    'javelin-behavior-differential-populate' => 'e2820c7b',
+    'javelin-behavior-differential-show-more' => 'e2820c7b',
     'javelin-behavior-phabricator-keyboard-shortcuts' => '46547a92',
-    'javelin-behavior-phabricator-object-selector' => '15c4a6dd',
+    'javelin-behavior-phabricator-object-selector' => 'e2820c7b',
     'javelin-behavior-phabricator-watch-anchor' => '46547a92',
     'javelin-behavior-refresh-csrf' => '46547a92',
     'javelin-behavior-workflow' => '46547a92',
     'javelin-dom' => 'b164acea',
     'javelin-event' => 'b164acea',
     'javelin-install' => 'b164acea',
     'javelin-json' => 'b164acea',
     'javelin-mask' => '46547a92',
     'javelin-request' => 'b164acea',
     'javelin-stratcom' => 'b164acea',
     'javelin-tokenizer' => '540effd7',
     'javelin-typeahead' => '540effd7',
     'javelin-typeahead-normalizer' => '540effd7',
     'javelin-typeahead-ondemand-source' => '540effd7',
     'javelin-typeahead-preloaded-source' => '540effd7',
     'javelin-typeahead-source' => '540effd7',
     'javelin-uri' => 'b164acea',
     'javelin-util' => 'b164acea',
     'javelin-vector' => 'b164acea',
     'javelin-workflow' => '46547a92',
     'phabricator-content-source-view-css' => '80580cea',
     'phabricator-core-buttons-css' => '775f5bae',
     'phabricator-core-css' => '775f5bae',
     'phabricator-directory-css' => '775f5bae',
-    'phabricator-drag-and-drop-file-upload' => '15c4a6dd',
+    'phabricator-drag-and-drop-file-upload' => 'e2820c7b',
     'phabricator-keyboard-shortcut' => '46547a92',
     'phabricator-keyboard-shortcut-manager' => '46547a92',
     'phabricator-object-selector-css' => '80580cea',
     'phabricator-remarkup-css' => '775f5bae',
-    'phabricator-shaped-request' => '15c4a6dd',
+    'phabricator-shaped-request' => 'e2820c7b',
     'phabricator-standard-page-view' => '775f5bae',
     'syntax-highlighting-css' => '775f5bae',
   ),
 ));
diff --git a/src/applications/differential/controller/commentpreview/DifferentialCommentPreviewController.php b/src/applications/differential/controller/commentpreview/DifferentialCommentPreviewController.php
index 8bdca49ec1..4c611a2bdd 100644
--- a/src/applications/differential/controller/commentpreview/DifferentialCommentPreviewController.php
+++ b/src/applications/differential/controller/commentpreview/DifferentialCommentPreviewController.php
@@ -1,82 +1,83 @@
 <?php
 
 /*
  * Copyright 2012 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 class DifferentialCommentPreviewController extends DifferentialController {
 
   private $id;
 
   public function willProcessRequest(array $data) {
     $this->id = $data['id'];
   }
 
   public function processRequest() {
 
     $request = $this->getRequest();
 
     $author_phid = $request->getUser()->getPHID();
 
     $action = $request->getStr('action');
 
     $engine = PhabricatorMarkupEngine::newDifferentialMarkupEngine();
 
     $comment = new DifferentialComment();
     $comment->setContent($request->getStr('content'));
     $comment->setAction($action);
     $comment->setAuthorPHID($author_phid);
 
     $handles = array($author_phid);
 
     $reviewers = $request->getStr('reviewers');
-    if ($action == DifferentialAction::ACTION_ADDREVIEWERS && $reviewers) {
+    if (($action == DifferentialAction::ACTION_ADDREVIEWERS
+        || $action == DifferentialAction::ACTION_REQUEST) && $reviewers) {
       $reviewers = explode(',', $reviewers);
       $comment->setMetadata(array(
         DifferentialComment::METADATA_ADDED_REVIEWERS => $reviewers));
       $handles = array_merge($handles, $reviewers);
     }
 
     $ccs = $request->getStr('ccs');
     if ($action == DifferentialAction::ACTION_ADDCCS && $ccs) {
       $ccs = explode(',', $ccs);
       $comment->setMetadata(array(
         DifferentialComment::METADATA_ADDED_CCS => $ccs));
       $handles = array_merge($handles, $ccs);
     }
 
     $handles = id(new PhabricatorObjectHandleData($handles))
       ->loadHandles();
 
     $view = new DifferentialRevisionCommentView();
     $view->setUser($request->getUser());
     $view->setComment($comment);
     $view->setHandles($handles);
     $view->setMarkupEngine($engine);
     $view->setPreview(true);
     $view->setTargetDiff(null);
 
     $draft = new PhabricatorDraft();
     $draft
       ->setAuthorPHID($author_phid)
       ->setDraftKey('differential-comment-'.$this->id)
       ->setDraft($comment->getContent())
       ->replace();
 
     return id(new AphrontAjaxResponse())
       ->setContent($view->render());
   }
 
 }
diff --git a/src/applications/differential/editor/comment/DifferentialCommentEditor.php b/src/applications/differential/editor/comment/DifferentialCommentEditor.php
index bb9625f4a1..3498f421d6 100644
--- a/src/applications/differential/editor/comment/DifferentialCommentEditor.php
+++ b/src/applications/differential/editor/comment/DifferentialCommentEditor.php
@@ -1,553 +1,569 @@
 <?php
 
 /*
  * Copyright 2012 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 class DifferentialCommentEditor {
 
   protected $revision;
   protected $actorPHID;
   protected $action;
 
   protected $attachInlineComments;
   protected $message;
   protected $changedByCommit;
   protected $addedReviewers = array();
   private $addedCCs = array();
 
   private $parentMessageID;
   private $contentSource;
 
   public function __construct(
     DifferentialRevision $revision,
     $actor_phid,
     $action) {
 
     $this->revision = $revision;
     $this->actorPHID  = $actor_phid;
     $this->action   = $action;
   }
 
   public function setParentMessageID($parent_message_id) {
     $this->parentMessageID = $parent_message_id;
     return $this;
   }
 
   public function setMessage($message) {
     $this->message = $message;
     return $this;
   }
 
   public function setAttachInlineComments($attach) {
     $this->attachInlineComments = $attach;
     return $this;
   }
 
   public function setChangedByCommit($changed_by_commit) {
     $this->changedByCommit = $changed_by_commit;
     return $this;
   }
 
   public function getChangedByCommit() {
     return $this->changedByCommit;
   }
 
   public function setAddedReviewers($added_reviewers) {
     $this->addedReviewers = $added_reviewers;
     return $this;
   }
 
   public function getAddedReviewers() {
     return $this->addedReviewers;
   }
 
   public function setAddedCCs($added_ccs) {
     $this->addedCCs = $added_ccs;
     return $this;
   }
 
   public function getAddedCCs() {
     return $this->addedCCs;
   }
 
   public function setContentSource(PhabricatorContentSource $content_source) {
     $this->contentSource = $content_source;
     return $this;
   }
 
   public function save() {
     $revision = $this->revision;
     $action = $this->action;
     $actor_phid = $this->actorPHID;
     $actor = id(new PhabricatorUser())->loadOneWhere('PHID = %s', $actor_phid);
     $actor_is_author = ($actor_phid == $revision->getAuthorPHID());
     $actor_is_admin = $actor->getIsAdmin();
     $revision_status = $revision->getStatus();
 
     $revision->loadRelationships();
     $reviewer_phids = $revision->getReviewers();
     if ($reviewer_phids) {
       $reviewer_phids = array_combine($reviewer_phids, $reviewer_phids);
     }
 
     $metadata = array();
 
     $inline_comments = array();
     if ($this->attachInlineComments) {
       $inline_comments = id(new DifferentialInlineComment())->loadAllWhere(
         'authorPHID = %s AND revisionID = %d AND commentID IS NULL',
         $this->actorPHID,
         $revision->getID());
     }
 
     switch ($action) {
       case DifferentialAction::ACTION_COMMENT:
         if (!$this->message && !$inline_comments) {
           throw new DifferentialActionHasNoEffectException(
             "You are submitting an empty comment with no action: ".
             "you must act on the revision or post a comment.");
         }
         break;
 
       case DifferentialAction::ACTION_RESIGN:
         if ($actor_is_author) {
           throw new Exception('You can not resign from your own revision!');
         }
         if (empty($reviewer_phids[$actor_phid])) {
           throw new DifferentialActionHasNoEffectException(
             "You can not resign from this revision because you are not ".
             "a reviewer.");
         }
         DifferentialRevisionEditor::alterReviewers(
           $revision,
           $reviewer_phids,
           $rem = array($actor_phid),
           $add = array(),
           $actor_phid);
         break;
 
       case DifferentialAction::ACTION_ABANDON:
         if (!($actor_is_author || $actor_is_admin)) {
           throw new Exception('You can only abandon your own revisions.');
         }
 
         if ($revision_status == ArcanistDifferentialRevisionStatus::COMMITTED) {
           throw new DifferentialActionHasNoEffectException(
             "You can not abandon this revision because it has already ".
             "been committed.");
         }
 
         if ($revision_status == ArcanistDifferentialRevisionStatus::ABANDONED) {
           throw new DifferentialActionHasNoEffectException(
             "You can not abandon this revision because it has already ".
             "been abandoned.");
         }
 
         $revision->setStatus(ArcanistDifferentialRevisionStatus::ABANDONED);
         break;
 
       case DifferentialAction::ACTION_ACCEPT:
         if ($actor_is_author) {
           throw new Exception('You can not accept your own revision.');
         }
         if (($revision_status !=
              ArcanistDifferentialRevisionStatus::NEEDS_REVIEW) &&
             ($revision_status !=
              ArcanistDifferentialRevisionStatus::NEEDS_REVISION)) {
 
           switch ($revision_status) {
             case ArcanistDifferentialRevisionStatus::ACCEPTED:
               throw new DifferentialActionHasNoEffectException(
                 "You can not accept this revision because someone else ".
                 "already accepted it.");
             case ArcanistDifferentialRevisionStatus::ABANDONED:
               throw new DifferentialActionHasNoEffectException(
                 "You can not accept this revision because it has been ".
                 "abandoned.");
             case ArcanistDifferentialRevisionStatus::COMMITTED:
               throw new DifferentialActionHasNoEffectException(
                 "You can not accept this revision because it has already ".
                 "been committed.");
             default:
               throw new Exception(
                 "Unexpected revision state '{$revision_status}'!");
           }
         }
 
         $revision
           ->setStatus(ArcanistDifferentialRevisionStatus::ACCEPTED);
 
         if (!isset($reviewer_phids[$actor_phid])) {
           DifferentialRevisionEditor::alterReviewers(
             $revision,
             $reviewer_phids,
             $rem = array(),
             $add = array($actor_phid),
             $actor_phid);
         }
         break;
 
       case DifferentialAction::ACTION_REQUEST:
         if (!$actor_is_author) {
           throw new Exception('You must own a revision to request review.');
         }
 
         switch ($revision_status) {
           case ArcanistDifferentialRevisionStatus::ACCEPTED:
           case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
             $revision->setStatus(
               ArcanistDifferentialRevisionStatus::NEEDS_REVIEW);
             break;
           case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
             throw new DifferentialActionHasNoEffectException(
               "You can not request review of this revision because it has ".
               "been abandoned.");
           case ArcanistDifferentialRevisionStatus::ABANDONED:
             throw new DifferentialActionHasNoEffectException(
               "You can not request review of this revision because it has ".
               "been abandoned.");
           case ArcanistDifferentialRevisionStatus::COMMITTED:
             throw new DifferentialActionHasNoEffectException(
               "You can not request review of this revision because it has ".
               "already been committed.");
           default:
             throw new Exception(
               "Unexpected revision state '{$revision_status}'!");
         }
 
+        $added_reviewers = $this->addReviewers();
+        if ($added_reviewers) {
+          $key = DifferentialComment::METADATA_ADDED_REVIEWERS;
+          $metadata[$key] = $added_reviewers;
+        }
+
         break;
 
       case DifferentialAction::ACTION_REJECT:
         if ($actor_is_author) {
           throw new Exception(
             'You can not request changes to your own revision.');
         }
 
         switch ($revision_status) {
           case ArcanistDifferentialRevisionStatus::ACCEPTED:
           case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
           case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
             // NOTE: We allow you to reject an already-rejected revision
             // because it doesn't create any ambiguity and avoids a rather
             // needless dialog.
             break;
           case ArcanistDifferentialRevisionStatus::ABANDONED:
             throw new DifferentialActionHasNoEffectException(
               "You can not request changes to this revision because it has ".
               "been abandoned.");
           case ArcanistDifferentialRevisionStatus::COMMITTED:
             throw new DifferentialActionHasNoEffectException(
               "You can not request changes to this revision because it has ".
               "already been committed.");
           default:
             throw new Exception(
               "Unexpected revision state '{$revision_status}'!");
         }
 
         if (!isset($reviewer_phids[$actor_phid])) {
           DifferentialRevisionEditor::alterReviewers(
             $revision,
             $reviewer_phids,
             $rem = array(),
             $add = array($actor_phid),
             $actor_phid);
         }
 
         $revision
           ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVISION);
         break;
 
       case DifferentialAction::ACTION_RETHINK:
         if (!$actor_is_author) {
           throw new Exception(
             "You can not plan changes to somebody else's revision");
         }
 
         switch ($revision_status) {
           case ArcanistDifferentialRevisionStatus::ACCEPTED:
           case ArcanistDifferentialRevisionStatus::NEEDS_REVISION:
           case ArcanistDifferentialRevisionStatus::NEEDS_REVIEW:
             break;
           case ArcanistDifferentialRevisionStatus::ABANDONED:
             throw new DifferentialActionHasNoEffectException(
               "You can not plan changes to this revision because it has ".
               "been abandoned.");
           case ArcanistDifferentialRevisionStatus::COMMITTED:
             throw new DifferentialActionHasNoEffectException(
               "You can not plan changes to this revision because it has ".
               "already been committed.");
           default:
             throw new Exception(
               "Unexpected revision state '{$revision_status}'!");
         }
 
         $revision
           ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVISION);
         break;
 
       case DifferentialAction::ACTION_RECLAIM:
         if (!$actor_is_author) {
           throw new Exception('You can not reclaim a revision you do not own.');
         }
 
 
         if ($revision_status != ArcanistDifferentialRevisionStatus::ABANDONED) {
           throw new DifferentialActionHasNoEffectException(
             "You can not reclaim this revision because it is not abandoned.");
         }
 
         $revision
           ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW);
         break;
 
       case DifferentialAction::ACTION_COMMIT:
         $revision
           ->setStatus(ArcanistDifferentialRevisionStatus::COMMITTED);
         break;
 
       case DifferentialAction::ACTION_ADDREVIEWERS:
-        $added_reviewers = $this->getAddedReviewers();
-        $user_tried_to_add = count($added_reviewers);
-
-        foreach ($added_reviewers as $k => $user_phid) {
-          if ($user_phid == $revision->getAuthorPHID()) {
-            unset($added_reviewers[$k]);
-          }
-          if (!empty($reviewer_phids[$user_phid])) {
-            unset($added_reviewers[$k]);
-          }
-        }
-
-        $added_reviewers = array_unique($added_reviewers);
+        $added_reviewers = $this->addReviewers();
 
         if ($added_reviewers) {
-          DifferentialRevisionEditor::alterReviewers(
-            $revision,
-            $reviewer_phids,
-            $rem = array(),
-            $add = $added_reviewers,
-            $actor_phid);
-
           $key = DifferentialComment::METADATA_ADDED_REVIEWERS;
           $metadata[$key] = $added_reviewers;
 
         } else {
+          $user_tried_to_add = count($this->getAddedReviewers());
           if ($user_tried_to_add == 0) {
             throw new DifferentialActionHasNoEffectException(
               "You can not add reviewers, because you did not specify any ".
               "reviewers.");
           } else if ($user_tried_to_add == 1) {
             throw new DifferentialActionHasNoEffectException(
               "You can not add that reviewer, because they are already an ".
               "author or reviewer.");
           } else {
             throw new DifferentialActionHasNoEffectException(
               "You can not add those reviewers, because they are all already ".
               "authors or reviewers.");
           }
         }
 
         break;
       case DifferentialAction::ACTION_ADDCCS:
         $added_ccs = $this->getAddedCCs();
         $user_tried_to_add = count($added_ccs);
 
         $added_ccs = $this->filterAddedCCs($added_ccs);
 
         if ($added_ccs) {
           foreach ($added_ccs as $cc) {
             DifferentialRevisionEditor::addCC(
               $revision,
               $cc,
               $this->actorPHID);
           }
 
           $key = DifferentialComment::METADATA_ADDED_CCS;
           $metadata[$key] = $added_ccs;
 
         } else {
           if ($user_tried_to_add == 0) {
             throw new DifferentialActionHasNoEffectException(
               "You can not add CCs, because you did not specify any ".
               "CCs.");
           } else if ($user_tried_to_add == 1) {
             throw new DifferentialActionHasNoEffectException(
               "You can not add that CC, because they are already an ".
               "author, reviewer or CC.");
           } else {
             throw new DifferentialActionHasNoEffectException(
               "You can not add those CCs, because they are all already ".
               "authors, reviewers or CCs.");
           }
         }
         break;
       default:
         throw new Exception('Unsupported action.');
     }
 
     // Always save the revision (even if we didn't actually change any of its
     // properties) so that it jumps to the top of the revision list when sorted
     // by "updated". Notably, this allows "ping" comments to push it to the
     // top of the action list.
     $revision->save();
 
     if ($action != DifferentialAction::ACTION_RESIGN &&
         $this->actorPHID != $revision->getAuthorPHID() &&
         !in_array($this->actorPHID, $revision->getReviewers())) {
       DifferentialRevisionEditor::addCC(
         $revision,
         $this->actorPHID,
         $this->actorPHID);
     }
 
     $comment = id(new DifferentialComment())
       ->setAuthorPHID($this->actorPHID)
       ->setRevisionID($revision->getID())
       ->setAction($action)
       ->setContent((string)$this->message)
       ->setMetadata($metadata);
 
     if ($this->contentSource) {
       $comment->setContentSource($this->contentSource);
     }
 
     $comment->save();
 
     $changesets = array();
     if ($inline_comments) {
       $load_ids = mpull($inline_comments, 'getChangesetID');
       if ($load_ids) {
         $load_ids = array_unique($load_ids);
         $changesets = id(new DifferentialChangeset())->loadAllWhere(
           'id in (%Ld)',
           $load_ids);
       }
       foreach ($inline_comments as $inline) {
         $inline->setCommentID($comment->getID());
         $inline->save();
       }
     }
 
     // Find any "@mentions" in the comment blocks.
     $content_blocks = array($comment->getContent());
     foreach ($inline_comments as $inline) {
       $content_blocks[] = $inline->getContent();
     }
     $mention_ccs = PhabricatorMarkupEngine::extractPHIDsFromMentions(
       $content_blocks);
     if ($mention_ccs) {
       $mention_ccs = $this->filterAddedCCs($mention_ccs);
       if ($mention_ccs) {
         $metadata = $comment->getMetadata();
         $metacc = idx(
           $metadata,
           DifferentialComment::METADATA_ADDED_CCS,
           array());
         foreach ($mention_ccs as $cc_phid) {
           DifferentialRevisionEditor::addCC(
             $revision,
             $cc_phid,
             $this->actorPHID);
           $metacc[] = $cc_phid;
         }
         $metadata[DifferentialComment::METADATA_ADDED_CCS] = $metacc;
 
         $comment->setMetadata($metadata);
         $comment->save();
       }
     }
 
     $phids = array($this->actorPHID);
     $handles = id(new PhabricatorObjectHandleData($phids))
       ->loadHandles();
     $actor_handle = $handles[$this->actorPHID];
 
     $xherald_header = HeraldTranscript::loadXHeraldRulesHeader(
       $revision->getPHID());
 
     id(new DifferentialCommentMail(
       $revision,
       $actor_handle,
       $comment,
       $changesets,
       $inline_comments))
       ->setToPHIDs(
         array_merge(
           $revision->getReviewers(),
           array($revision->getAuthorPHID())))
       ->setCCPHIDs($revision->getCCPHIDs())
       ->setChangedByCommit($this->getChangedByCommit())
       ->setXHeraldRulesHeader($xherald_header)
       ->setParentMessageID($this->parentMessageID)
       ->send();
 
     $event_data = array(
       'revision_id'          => $revision->getID(),
       'revision_phid'        => $revision->getPHID(),
       'revision_name'        => $revision->getTitle(),
       'revision_author_phid' => $revision->getAuthorPHID(),
       'action'               => $comment->getAction(),
       'feedback_content'     => $comment->getContent(),
       'actor_phid'           => $this->actorPHID,
     );
     id(new PhabricatorTimelineEvent('difx', $event_data))
       ->recordEvent();
 
     // TODO: Move to a daemon?
     id(new PhabricatorFeedStoryPublisher())
       ->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_DIFFERENTIAL)
       ->setStoryData($event_data)
       ->setStoryTime(time())
       ->setStoryAuthorPHID($this->actorPHID)
       ->setRelatedPHIDs(
         array(
           $revision->getPHID(),
           $this->actorPHID,
           $revision->getAuthorPHID(),
         ))
       ->publish();
 
     // TODO: Move to a daemon?
     PhabricatorSearchDifferentialIndexer::indexRevision($revision);
 
     return $comment;
   }
 
   private function filterAddedCCs(array $ccs) {
     $revision = $this->revision;
 
     $current_ccs = $revision->getCCPHIDs();
     $current_ccs = array_fill_keys($current_ccs, true);
 
     $reviewer_phids = $revision->getReviewers();
     $reviewer_phids = array_fill_keys($reviewer_phids, true);
 
     foreach ($ccs as $key => $cc) {
       if (isset($current_ccs[$cc])) {
         unset($ccs[$key]);
       }
       if (isset($reviewer_phids[$cc])) {
         unset($ccs[$key]);
       }
       if ($cc == $revision->getAuthorPHID()) {
         unset($ccs[$key]);
       }
     }
 
     return $ccs;
   }
 
+  private function addReviewers() {
+    $revision = $this->revision;
+    $added_reviewers = $this->getAddedReviewers();
+    $reviewer_phids = $revision->getReviewers();
+
+    foreach ($added_reviewers as $k => $user_phid) {
+      if ($user_phid == $revision->getAuthorPHID()) {
+        unset($added_reviewers[$k]);
+      }
+      if (!empty($reviewer_phids[$user_phid])) {
+        unset($added_reviewers[$k]);
+      }
+    }
+
+    $added_reviewers = array_unique($added_reviewers);
+
+    if ($added_reviewers) {
+      DifferentialRevisionEditor::alterReviewers(
+        $revision,
+        $reviewer_phids,
+        $rem = array(),
+        $added_reviewers,
+        $this->actorPHID);
+    }
+
+    return $added_reviewers;
+  }
+
 }
diff --git a/src/applications/differential/view/addcomment/DifferentialAddCommentView.php b/src/applications/differential/view/addcomment/DifferentialAddCommentView.php
index 3d8f658f63..f19e929652 100644
--- a/src/applications/differential/view/addcomment/DifferentialAddCommentView.php
+++ b/src/applications/differential/view/addcomment/DifferentialAddCommentView.php
@@ -1,241 +1,241 @@
 <?php
 
 /*
  * Copyright 2012 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 final class DifferentialAddCommentView extends AphrontView {
 
   private $revision;
   private $actions;
   private $actionURI;
   private $user;
   private $draft;
 
   public function setRevision($revision) {
     $this->revision = $revision;
     return $this;
   }
 
   public function setActions(array $actions) {
     $this->actions = $actions;
     return $this;
   }
 
   public function setActionURI($uri) {
     $this->actionURI = $uri;
   }
 
   public function setUser(PhabricatorUser $user) {
     $this->user = $user;
   }
 
   public function setDraft($draft) {
     $this->draft = $draft;
     return $this;
   }
 
   private function generateWarningView(
     $status,
     array $titles,
     $id,
     $content) {
 
     $warning = new AphrontErrorView();
     $warning->setSeverity(AphrontErrorView::SEVERITY_ERROR);
     $warning->setWidth(AphrontErrorView::WIDTH_WIDE);
     $warning->setID($id);
     $warning->appendChild($content);
     $warning->setTitle(idx($titles, $status, 'Warning'));
 
     return $warning;
   }
 
   public function render() {
 
     require_celerity_resource('differential-revision-add-comment-css');
 
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
 
     $revision = $this->revision;
 
     $form = new AphrontFormView();
     $form
       ->setWorkflow(true)
       ->setUser($this->user)
       ->setAction($this->actionURI)
       ->addHiddenInput('revision_id', $revision->getID())
       ->appendChild(
         id(new AphrontFormSelectControl())
           ->setLabel('Action')
           ->setName('action')
           ->setID('comment-action')
           ->setOptions($this->actions))
       ->appendChild(
         id(new AphrontFormTokenizerControl())
           ->setLabel('Add Reviewers')
           ->setName('reviewers')
           ->setControlID('add-reviewers')
           ->setControlStyle('display: none')
           ->setID('add-reviewers-tokenizer')
           ->setDisableBehavior(true))
       ->appendChild(
         id(new AphrontFormTokenizerControl())
           ->setLabel('Add CCs')
           ->setName('ccs')
           ->setControlID('add-ccs')
           ->setControlStyle('display: none')
           ->setID('add-ccs-tokenizer')
           ->setDisableBehavior(true))
       ->appendChild(
         id(new AphrontFormTextAreaControl())
           ->setName('comment')
           ->setID('comment-content')
           ->setLabel('Comment')
           ->setEnableDragAndDropFileUploads(true)
           ->setValue($this->draft)
           ->setCaption(phutil_render_tag(
             'a',
             array(
               'href' => PhabricatorEnv::getDoclink(
                 'article/Remarkup_Reference.html'),
               'tabindex' => '-1',
               'target' => '_blank',
             ),
             'Formatting Reference')))
       ->appendChild(
         id(new AphrontFormSubmitControl())
           ->setValue($is_serious ? 'Submit' : 'Clowncopterize'));
 
     Javelin::initBehavior(
       'differential-add-reviewers-and-ccs',
       array(
         'dynamic' => array(
-          'add_reviewers' => array(
-            'tokenizer' => 'add-reviewers-tokenizer',
+          'add-reviewers-tokenizer' => array(
+            'actions' => array('request_review' => 1, 'add_reviewers' => 1),
             'src' => '/typeahead/common/users/',
             'row' => 'add-reviewers',
             'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'),
           ),
-          'add_ccs' => array(
-            'tokenizer' => 'add-ccs-tokenizer',
+          'add-ccs-tokenizer' => array(
+            'actions' => array('add_ccs' => 1),
             'src' => '/typeahead/common/mailable/',
             'row' => 'add-ccs',
             'ondemand' => PhabricatorEnv::getEnvConfig('tokenizer.ondemand'),
           ),
         ),
         'select' => 'comment-action',
       ));
 
     $diff = $revision->loadActiveDiff();
     $lint_warning = null;
     $unit_warning = null;
     if ($diff->getLintStatus() >= DifferentialLintStatus::LINT_WARN) {
       $titles =
         array(
           DifferentialLintStatus::LINT_WARN => 'Lint Warning',
           DifferentialLintStatus::LINT_FAIL => 'Lint Failure',
           DifferentialLintStatus::LINT_SKIP => 'Lint Skipped'
         );
       $content =
         "<p>This diff has Lint Problems. Make sure you are OK with them ".
         "before you accept this diff.</p>";
       $lint_warning = $this->generateWarningView(
         $diff->getLintStatus(),
         $titles,
         'lint-warning',
         $content);
     }
 
     if ($diff->getUnitStatus() >= DifferentialUnitStatus::UNIT_WARN) {
       $titles =
         array(
           DifferentialUnitStatus::UNIT_WARN => 'Unit Tests Warning',
           DifferentialUnitStatus::UNIT_FAIL => 'Unit Tests Failure',
           DifferentialUnitStatus::UNIT_SKIP => 'Unit Tests Skipped',
           DifferentialUnitStatus::UNIT_POSTPONED => 'Unit Tests Postponed'
         );
       if ($diff->getUnitStatus() == DifferentialUnitStatus::UNIT_POSTPONED) {
         $content =
           "<p>This diff has postponed unit tests. The results should be ".
           "coming in soon. You should probably wait for them before accepting ".
           "this diff.</p>";
       } else {
         $content =
           "<p>This diff has Unit Test Problems. Make sure you are OK with ".
           "them before you accept this diff.</p>";
       }
       $unit_warning = $this->generateWarningView(
         $diff->getUnitStatus(),
         $titles,
         'unit-warning',
         $content);
     }
 
     Javelin::initBehavior(
       'differential-accept-with-errors',
       array(
         'select' => 'comment-action',
         'lint_warning' => $lint_warning ? 'lint-warning' : null,
         'unit_warning' => $unit_warning ? 'unit-warning' : null,
       ));
 
     $rev_id = $revision->getID();
 
     Javelin::initBehavior(
       'differential-feedback-preview',
       array(
         'uri'       => '/differential/comment/preview/'.$rev_id.'/',
         'preview'   => 'comment-preview',
         'action'    => 'comment-action',
         'content'   => 'comment-content',
         'previewTokenizers' => array(
           'reviewers' => 'add-reviewers-tokenizer',
           'ccs'       => 'add-ccs-tokenizer',
         ),
 
         'inlineuri' => '/differential/comment/inline/preview/'.$rev_id.'/',
         'inline'    => 'inline-comment-preview',
       ));
 
     $panel_view = new AphrontPanelView();
     $panel_view->appendChild($form);
     if ($lint_warning) {
       $panel_view->appendChild($lint_warning);
     }
     if ($unit_warning) {
       $panel_view->appendChild($unit_warning);
     }
 
     $panel_view->setHeader($is_serious ? 'Add Comment' : 'Leap Into Action');
 
     $panel_view->addClass('aphront-panel-accent');
     $panel_view->addClass('aphront-panel-flush');
 
     return
       '<div class="differential-add-comment-panel">'.
         $panel_view->render().
         '<div class="aphront-panel-preview aphront-panel-flush">'.
           '<div id="comment-preview">'.
             '<span class="aphront-panel-preview-loading-text">'.
               'Loading comment preview...'.
             '</span>'.
           '</div>'.
           '<div id="inline-comment-preview">'.
           '</div>'.
         '</div>'.
       '</div>';
   }
 }
diff --git a/webroot/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js b/webroot/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js
index 8034eadd6b..d9d6187d06 100644
--- a/webroot/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js
+++ b/webroot/rsrc/js/application/differential/behavior-add-reviewers-and-ccs.js
@@ -1,60 +1,61 @@
 /**
  * @provides javelin-behavior-differential-add-reviewers-and-ccs
  * @requires javelin-behavior
  *           javelin-dom
  *           javelin-tokenizer
  *           javelin-typeahead
  *           javelin-typeahead-preloaded-source
  */
 
 JX.behavior('differential-add-reviewers-and-ccs', function(config) {
 
-  function buildTokenizer(props) {
-    var root = JX.$(props.tokenizer);
+  function buildTokenizer(id, props) {
+    var root = JX.$(id);
 
     var datasource;
     if (props.ondemand) {
       datasource = new JX.TypeaheadOnDemandSource(props.src);
     } else {
       datasource = new JX.TypeaheadPreloadedSource(props.src);
     }
 
     var typeahead = new JX.Typeahead(root);
     typeahead.setDatasource(datasource);
 
     var tokenizer = new JX.Tokenizer(root);
     tokenizer.setTypeahead(typeahead);
 
     JX.Stratcom.addData(root, {'tokenizer' : tokenizer});
 
     tokenizer.start();
 
     return tokenizer;
   }
 
   var dynamic = {};
   for (var k in config.dynamic) {
     props = config.dynamic[k];
     dynamic[k] = {
       row : JX.$(props.row),
-      tokenizer : buildTokenizer(props)
+      tokenizer : buildTokenizer(k, props),
+      actions : props.actions
     };
   }
 
   JX.DOM.listen(
     JX.$(config.select),
     'change',
     null,
     function(e) {
       var v = JX.$(config.select).value;
       for (var k in dynamic) {
-        if (v == k) {
+        if (dynamic[k].actions[v]) {
           JX.DOM.show(dynamic[k].row);
           dynamic[k].tokenizer.refresh();
         } else {
           JX.DOM.hide(dynamic[k].row);
         }
       }
     });
 });