diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
index 6dbf82e..59aec31 100644
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -1,719 +1,718 @@
 <?php
 
 /**
  * This file is automatically generated. Use 'arc liberate' to rebuild it.
  * @generated
  * @phutil-library-version 2
  */
-
 phutil_register_library_map(array(
   '__library_version__' => 2,
   'class' =>
   array(
     'AASTNode' => 'parser/aast/api/AASTNode.php',
     'AASTNodeList' => 'parser/aast/api/AASTNodeList.php',
     'AASTToken' => 'parser/aast/api/AASTToken.php',
     'AASTTree' => 'parser/aast/api/AASTTree.php',
     'AbstractDirectedGraph' => 'utils/AbstractDirectedGraph.php',
     'AbstractDirectedGraphTestCase' => 'utils/__tests__/AbstractDirectedGraphTestCase.php',
     'AphrontDatabaseConnection' => 'aphront/storage/connection/AphrontDatabaseConnection.php',
     'AphrontDatabaseTransactionState' => 'aphront/storage/connection/AphrontDatabaseTransactionState.php',
     'AphrontIsolatedDatabaseConnection' => 'aphront/storage/connection/AphrontIsolatedDatabaseConnection.php',
     'AphrontMySQLDatabaseConnection' => 'aphront/storage/connection/mysql/AphrontMySQLDatabaseConnection.php',
     'AphrontMySQLDatabaseConnectionBase' => 'aphront/storage/connection/mysql/AphrontMySQLDatabaseConnectionBase.php',
     'AphrontMySQLiDatabaseConnection' => 'aphront/storage/connection/mysql/AphrontMySQLiDatabaseConnection.php',
     'AphrontQueryAccessDeniedException' => 'aphront/storage/exception/AphrontQueryAccessDeniedException.php',
     'AphrontQueryCharacterSetException' => 'aphront/storage/exception/AphrontQueryCharacterSetException.php',
     'AphrontQueryConnectionException' => 'aphront/storage/exception/AphrontQueryConnectionException.php',
     'AphrontQueryConnectionLostException' => 'aphront/storage/exception/AphrontQueryConnectionLostException.php',
     'AphrontQueryCountException' => 'aphront/storage/exception/AphrontQueryCountException.php',
     'AphrontQueryDeadlockException' => 'aphront/storage/exception/AphrontQueryDeadlockException.php',
     'AphrontQueryDuplicateKeyException' => 'aphront/storage/exception/AphrontQueryDuplicateKeyException.php',
     'AphrontQueryException' => 'aphront/storage/exception/AphrontQueryException.php',
     'AphrontQueryNotSupportedException' => 'aphront/storage/exception/AphrontQueryNotSupportedException.php',
     'AphrontQueryObjectMissingException' => 'aphront/storage/exception/AphrontQueryObjectMissingException.php',
     'AphrontQueryParameterException' => 'aphront/storage/exception/AphrontQueryParameterException.php',
     'AphrontQueryRecoverableException' => 'aphront/storage/exception/AphrontQueryRecoverableException.php',
     'AphrontQuerySchemaException' => 'aphront/storage/exception/AphrontQuerySchemaException.php',
     'AphrontScopedUnguardedWriteCapability' => 'aphront/writeguard/AphrontScopedUnguardedWriteCapability.php',
     'AphrontWriteGuard' => 'aphront/writeguard/AphrontWriteGuard.php',
     'AphrontWriteGuardExitEventListener' => 'aphront/writeguard/event/AphrontWriteGuardExitEventListener.php',
     'BaseHTTPFuture' => 'future/http/BaseHTTPFuture.php',
     'CommandException' => 'future/exec/CommandException.php',
     'ConduitClient' => 'conduit/ConduitClient.php',
     'ConduitClientException' => 'conduit/ConduitClientException.php',
     'ConduitFuture' => 'conduit/ConduitFuture.php',
     'ExecFuture' => 'future/exec/ExecFuture.php',
     'ExecFutureTestCase' => 'future/exec/__tests__/ExecFutureTestCase.php',
     'ExecPassthruTestCase' => 'future/exec/__tests__/ExecPassthruTestCase.php',
     'FileFinder' => 'filesystem/FileFinder.php',
     'FileFinderTestCase' => 'filesystem/__tests__/FileFinderTestCase.php',
     'FileList' => 'filesystem/FileList.php',
     'Filesystem' => 'filesystem/Filesystem.php',
     'FilesystemException' => 'filesystem/FilesystemException.php',
     'FilesystemTestCase' => 'filesystem/__tests__/FilesystemTestCase.php',
     'Future' => 'future/Future.php',
     'FutureIterator' => 'future/FutureIterator.php',
     'FutureIteratorTestCase' => 'future/__tests__/FutureIteratorTestCase.php',
     'FutureProxy' => 'future/FutureProxy.php',
     'HTTPFuture' => 'future/http/HTTPFuture.php',
     'HTTPFutureResponseStatus' => 'future/http/status/HTTPFutureResponseStatus.php',
     'HTTPFutureResponseStatusCURL' => 'future/http/status/HTTPFutureResponseStatusCURL.php',
     'HTTPFutureResponseStatusHTTP' => 'future/http/status/HTTPFutureResponseStatusHTTP.php',
     'HTTPFutureResponseStatusParse' => 'future/http/status/HTTPFutureResponseStatusParse.php',
     'HTTPFutureResponseStatusTransport' => 'future/http/status/HTTPFutureResponseStatusTransport.php',
     'HTTPSFuture' => 'future/http/HTTPSFuture.php',
     'ImmediateFuture' => 'future/ImmediateFuture.php',
     'LinesOfALarge' => 'filesystem/linesofalarge/LinesOfALarge.php',
     'LinesOfALargeExecFuture' => 'filesystem/linesofalarge/LinesOfALargeExecFuture.php',
     'LinesOfALargeExecFutureTestCase' => 'filesystem/linesofalarge/__tests__/LinesOfALargeExecFutureTestCase.php',
     'LinesOfALargeFile' => 'filesystem/linesofalarge/LinesOfALargeFile.php',
     'LinesOfALargeFileTestCase' => 'filesystem/linesofalarge/__tests__/LinesOfALargeFileTestCase.php',
     'MFilterTestHelper' => 'utils/__tests__/MFilterTestHelper.php',
     'PHPASTParserTestCase' => 'parser/xhpast/__tests__/PHPASTParserTestCase.php',
     'PhageAgentBootloader' => 'phage/bootloader/PhageAgentBootloader.php',
     'PhageAgentTestCase' => 'phage/__tests__/PhageAgentTestCase.php',
     'PhagePHPAgent' => 'phage/agent/PhagePHPAgent.php',
     'PhagePHPAgentBootloader' => 'phage/bootloader/PhagePHPAgentBootloader.php',
     'Phobject' => 'object/Phobject.php',
     'PhutilAWSEC2Future' => 'future/aws/PhutilAWSEC2Future.php',
     'PhutilAWSException' => 'future/aws/PhutilAWSException.php',
     'PhutilAWSFuture' => 'future/aws/PhutilAWSFuture.php',
     'PhutilAWSS3Future' => 'future/aws/PhutilAWSS3Future.php',
     'PhutilAggregateException' => 'error/PhutilAggregateException.php',
     'PhutilArgumentParser' => 'parser/argument/PhutilArgumentParser.php',
     'PhutilArgumentParserException' => 'parser/argument/exception/PhutilArgumentParserException.php',
     'PhutilArgumentParserTestCase' => 'parser/argument/__tests__/PhutilArgumentParserTestCase.php',
     'PhutilArgumentSpecification' => 'parser/argument/PhutilArgumentSpecification.php',
     'PhutilArgumentSpecificationException' => 'parser/argument/exception/PhutilArgumentSpecificationException.php',
     'PhutilArgumentSpecificationTestCase' => 'parser/argument/__tests__/PhutilArgumentSpecificationTestCase.php',
     'PhutilArgumentUsageException' => 'parser/argument/exception/PhutilArgumentUsageException.php',
     'PhutilArgumentWorkflow' => 'parser/argument/workflow/PhutilArgumentWorkflow.php',
     'PhutilArray' => 'utils/PhutilArray.php',
     'PhutilArrayTestCase' => 'utils/__tests__/PhutilArrayTestCase.php',
     'PhutilArrayWithDefaultValue' => 'utils/PhutilArrayWithDefaultValue.php',
     'PhutilAsanaFuture' => 'future/asana/PhutilAsanaFuture.php',
     'PhutilAuthAdapter' => 'auth/PhutilAuthAdapter.php',
     'PhutilAuthAdapterEmpty' => 'auth/PhutilAuthAdapterEmpty.php',
     'PhutilAuthAdapterLDAP' => 'auth/PhutilAuthAdapterLDAP.php',
     'PhutilAuthAdapterOAuth' => 'auth/PhutilAuthAdapterOAuth.php',
     'PhutilAuthAdapterOAuth1' => 'auth/PhutilAuthAdapterOAuth1.php',
     'PhutilAuthAdapterOAuthAmazon' => 'auth/PhutilAuthAdapterOAuthAmazon.php',
     'PhutilAuthAdapterOAuthAsana' => 'auth/PhutilAuthAdapterOAuthAsana.php',
     'PhutilAuthAdapterOAuthBitbucket' => 'auth/PhutilAuthAdapterOAuthBitbucket.php',
     'PhutilAuthAdapterOAuthDisqus' => 'auth/PhutilAuthAdapterOAuthDisqus.php',
     'PhutilAuthAdapterOAuthFacebook' => 'auth/PhutilAuthAdapterOAuthFacebook.php',
     'PhutilAuthAdapterOAuthGitHub' => 'auth/PhutilAuthAdapterOAuthGitHub.php',
     'PhutilAuthAdapterOAuthGoogle' => 'auth/PhutilAuthAdapterOAuthGoogle.php',
     'PhutilAuthAdapterOAuthJIRA' => 'auth/PhutilAuthAdapterOAuthJIRA.php',
     'PhutilAuthAdapterOAuthTwitch' => 'auth/PhutilAuthAdapterOAuthTwitch.php',
     'PhutilAuthAdapterOAuthTwitter' => 'auth/PhutilAuthAdapterOAuthTwitter.php',
     'PhutilAuthAdapterOAuthWordPress' => 'auth/PhutilAuthAdapterOAuthWordPress.php',
     'PhutilAuthAdapterPersona' => 'auth/PhutilAuthAdapterPersona.php',
     'PhutilAuthConfigurationException' => 'auth/exception/PhutilAuthConfigurationException.php',
     'PhutilAuthCredentialException' => 'auth/exception/PhutilAuthCredentialException.php',
     'PhutilAuthException' => 'auth/exception/PhutilAuthException.php',
     'PhutilAuthUserAbortedException' => 'auth/exception/PhutilAuthUserAbortedException.php',
     'PhutilBallOfPHP' => 'phage/util/PhutilBallOfPHP.php',
     'PhutilBootloader' => 'moduleutils/PhutilBootloader.php',
     'PhutilBootloaderException' => 'moduleutils/PhutilBootloaderException.php',
     'PhutilBufferedIterator' => 'utils/PhutilBufferedIterator.php',
     'PhutilBufferedIteratorExample' => 'utils/PhutilBufferedIteratorExample.php',
     'PhutilBufferedIteratorTestCase' => 'utils/__tests__/PhutilBufferedIteratorTestCase.php',
     'PhutilBugtraqParser' => 'parser/PhutilBugtraqParser.php',
     'PhutilBugtraqParserTestCase' => 'parser/__tests__/PhutilBugtraqParserTestCase.php',
     'PhutilCLikeCodeSnippetContextFreeGrammar' => 'grammar/code/PhutilCLikeCodeSnippetContextFreeGrammar.php',
     'PhutilCallbackFilterIterator' => 'utils/PhutilCallbackFilterIterator.php',
     'PhutilChannel' => 'channel/PhutilChannel.php',
     'PhutilChannelChannel' => 'channel/PhutilChannelChannel.php',
     'PhutilChannelTestCase' => 'channel/__tests__/PhutilChannelTestCase.php',
     'PhutilChunkedIterator' => 'utils/PhutilChunkedIterator.php',
     'PhutilChunkedIteratorTestCase' => 'utils/__tests__/PhutilChunkedIteratorTestCase.php',
     'PhutilCodeSnippetContextFreeGrammar' => 'grammar/code/PhutilCodeSnippetContextFreeGrammar.php',
     'PhutilCommandString' => 'xsprintf/PhutilCommandString.php',
     'PhutilConsole' => 'console/PhutilConsole.php',
     'PhutilConsoleFormatter' => 'console/PhutilConsoleFormatter.php',
     'PhutilConsoleMessage' => 'console/PhutilConsoleMessage.php',
     'PhutilConsoleProgressBar' => 'console/PhutilConsoleProgressBar.php',
     'PhutilConsoleServer' => 'console/PhutilConsoleServer.php',
     'PhutilConsoleServerChannel' => 'console/PhutilConsoleServerChannel.php',
     'PhutilConsoleStdinNotInteractiveException' => 'console/PhutilConsoleStdinNotInteractiveException.php',
     'PhutilConsoleSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilConsoleSyntaxHighlighter.php',
     'PhutilConsoleTable' => 'console/PhutilConsoleTable.php',
     'PhutilConsoleWrapTestCase' => 'console/__tests__/PhutilConsoleWrapTestCase.php',
     'PhutilContextFreeGrammar' => 'grammar/PhutilContextFreeGrammar.php',
     'PhutilCsprintfTestCase' => 'xsprintf/__tests__/PhutilCsprintfTestCase.php',
     'PhutilDaemon' => 'daemon/PhutilDaemon.php',
     'PhutilDaemonOverseer' => 'daemon/PhutilDaemonOverseer.php',
     'PhutilDefaultSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilDefaultSyntaxHighlighter.php',
     'PhutilDefaultSyntaxHighlighterEngine' => 'markup/syntax/engine/PhutilDefaultSyntaxHighlighterEngine.php',
     'PhutilDefaultSyntaxHighlighterEnginePygmentsFuture' => 'markup/syntax/highlighter/pygments/PhutilDefaultSyntaxHighlighterEnginePygmentsFuture.php',
     'PhutilDefaultSyntaxHighlighterEngineTestCase' => 'markup/syntax/engine/__tests__/PhutilDefaultSyntaxHighlighterEngineTestCase.php',
     'PhutilDeferredLog' => 'filesystem/PhutilDeferredLog.php',
     'PhutilDeferredLogTestCase' => 'filesystem/__tests__/PhutilDeferredLogTestCase.php',
     'PhutilDirectedScalarGraph' => 'utils/PhutilDirectedScalarGraph.php',
     'PhutilDirectoryFixture' => 'filesystem/PhutilDirectoryFixture.php',
     'PhutilDivinerSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilDivinerSyntaxHighlighter.php',
     'PhutilDocblockParser' => 'parser/PhutilDocblockParser.php',
     'PhutilDocblockParserTestCase' => 'parser/__tests__/PhutilDocblockParserTestCase.php',
     'PhutilEditDistanceMatrix' => 'utils/PhutilEditDistanceMatrix.php',
     'PhutilEditDistanceMatrixTestCase' => 'utils/__tests__/PhutilEditDistanceMatrixTestCase.php',
     'PhutilEmailAddress' => 'parser/PhutilEmailAddress.php',
     'PhutilEmailAddressTestCase' => 'parser/__tests__/PhutilEmailAddressTestCase.php',
     'PhutilErrorHandler' => 'error/PhutilErrorHandler.php',
     'PhutilErrorHandlerTestCase' => 'error/__tests__/PhutilErrorHandlerTestCase.php',
     'PhutilErrorTrap' => 'error/PhutilErrorTrap.php',
     'PhutilEvent' => 'events/PhutilEvent.php',
     'PhutilEventConstants' => 'events/constant/PhutilEventConstants.php',
     'PhutilEventEngine' => 'events/PhutilEventEngine.php',
     'PhutilEventListener' => 'events/PhutilEventListener.php',
     'PhutilEventType' => 'events/constant/PhutilEventType.php',
     'PhutilExcessiveServiceCallsDaemon' => 'daemon/torture/PhutilExcessiveServiceCallsDaemon.php',
     'PhutilExecChannel' => 'channel/PhutilExecChannel.php',
     'PhutilExecPassthru' => 'future/exec/PhutilExecPassthru.php',
     'PhutilExtensionsTestCase' => 'moduleutils/__tests__/PhutilExtensionsTestCase.php',
     'PhutilFatalDaemon' => 'daemon/torture/PhutilFatalDaemon.php',
     'PhutilFileLock' => 'filesystem/PhutilFileLock.php',
     'PhutilFileLockTestCase' => 'filesystem/__tests__/PhutilFileLockTestCase.php',
     'PhutilFileTree' => 'filesystem/PhutilFileTree.php',
     'PhutilGitURI' => 'parser/PhutilGitURI.php',
     'PhutilGitURITestCase' => 'parser/__tests__/PhutilGitURITestCase.php',
     'PhutilHangForeverDaemon' => 'daemon/torture/PhutilHangForeverDaemon.php',
     'PhutilHelpArgumentWorkflow' => 'parser/argument/workflow/PhutilHelpArgumentWorkflow.php',
     'PhutilHgsprintfTestCase' => 'xsprintf/__tests__/PhutilHgsprintfTestCase.php',
     'PhutilInfrastructureTestCase' => '__tests__/PhutilInfrastructureTestCase.php',
     'PhutilInteractiveEditor' => 'console/PhutilInteractiveEditor.php',
     'PhutilInvisibleSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilInvisibleSyntaxHighlighter.php',
     'PhutilJSON' => 'parser/PhutilJSON.php',
     'PhutilJSONParser' => 'parser/PhutilJSONParser.php',
     'PhutilJSONParserException' => 'parser/exception/PhutilJSONParserException.php',
     'PhutilJSONParserTestCase' => 'parser/__tests__/PhutilJSONParserTestCase.php',
     'PhutilJSONProtocolChannel' => 'channel/PhutilJSONProtocolChannel.php',
     'PhutilJSONProtocolChannelTestCase' => 'channel/__tests__/PhutilJSONProtocolChannelTestCase.php',
     'PhutilJSONTestCase' => 'parser/__tests__/PhutilJSONTestCase.php',
     'PhutilJavaCodeSnippetContextFreeGrammar' => 'grammar/code/PhutilJavaCodeSnippetContextFreeGrammar.php',
     'PhutilKeyValueCache' => 'cache/PhutilKeyValueCache.php',
     'PhutilKeyValueCacheAPC' => 'cache/PhutilKeyValueCacheAPC.php',
     'PhutilKeyValueCacheDirectory' => 'cache/PhutilKeyValueCacheDirectory.php',
     'PhutilKeyValueCacheInRequest' => 'cache/PhutilKeyValueCacheInRequest.php',
     'PhutilKeyValueCacheMemcache' => 'cache/PhutilKeyValueCacheMemcache.php',
     'PhutilKeyValueCacheNamespace' => 'cache/PhutilKeyValueCacheNamespace.php',
     'PhutilKeyValueCacheOnDisk' => 'cache/PhutilKeyValueCacheOnDisk.php',
     'PhutilKeyValueCacheProfiler' => 'cache/PhutilKeyValueCacheProfiler.php',
     'PhutilKeyValueCacheProxy' => 'cache/PhutilKeyValueCacheProxy.php',
     'PhutilKeyValueCacheStack' => 'cache/PhutilKeyValueCacheStack.php',
     'PhutilKeyValueCacheTestCase' => 'cache/__tests__/PhutilKeyValueCacheTestCase.php',
     'PhutilLanguageGuesser' => 'parser/PhutilLanguageGuesser.php',
     'PhutilLanguageGuesserTestCase' => 'parser/__tests__/PhutilLanguageGuesserTestCase.php',
     'PhutilLexer' => 'lexer/PhutilLexer.php',
     'PhutilLexerSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilLexerSyntaxHighlighter.php',
     'PhutilLibraryConflictException' => 'moduleutils/PhutilLibraryConflictException.php',
     'PhutilLibraryMapBuilder' => 'moduleutils/PhutilLibraryMapBuilder.php',
     'PhutilLipsumContextFreeGrammar' => 'grammar/PhutilLipsumContextFreeGrammar.php',
     'PhutilLock' => 'filesystem/PhutilLock.php',
     'PhutilLockException' => 'filesystem/PhutilLockException.php',
     'PhutilLogfileChannel' => 'channel/PhutilLogfileChannel.php',
     'PhutilLunarPhase' => 'utils/PhutilLunarPhase.php',
     'PhutilLunarPhaseTestCase' => 'utils/__tests__/PhutilLunarPhaseTestCase.php',
     'PhutilMarkupEngine' => 'markup/PhutilMarkupEngine.php',
     'PhutilMarkupTestCase' => 'markup/__tests__/PhutilMarkupTestCase.php',
     'PhutilMetricsChannel' => 'channel/PhutilMetricsChannel.php',
     'PhutilMissingSymbolException' => 'symbols/exception/PhutilMissingSymbolException.php',
     'PhutilModuleUtilsTestCase' => 'moduleutils/__tests__/PhutilModuleUtilsTestCase.php',
     'PhutilNiceDaemon' => 'daemon/torture/PhutilNiceDaemon.php',
     'PhutilNumber' => 'internationalization/PhutilNumber.php',
     'PhutilOAuth1Future' => 'future/oauth/PhutilOAuth1Future.php',
     'PhutilOAuth1FutureTestCase' => 'future/oauth/__tests__/PhutilOAuth1FutureTestCase.php',
     'PhutilOpaqueEnvelope' => 'error/PhutilOpaqueEnvelope.php',
     'PhutilOpaqueEnvelopeKey' => 'error/PhutilOpaqueEnvelopeKey.php',
     'PhutilOpaqueEnvelopeTestCase' => 'error/__tests__/PhutilOpaqueEnvelopeTestCase.php',
     'PhutilPHPCodeSnippetContextFreeGrammar' => 'grammar/code/PhutilPHPCodeSnippetContextFreeGrammar.php',
     'PhutilPHPFragmentLexer' => 'lexer/PhutilPHPFragmentLexer.php',
     'PhutilPHPFragmentLexerHighlighterTestCase' => 'markup/syntax/highlighter/__tests__/PhutilPHPFragmentLexerHighlighterTestCase.php',
     'PhutilPHPFragmentLexerTestCase' => 'lexer/__tests__/PhutilPHPFragmentLexerTestCase.php',
     'PhutilPHPObjectProtocolChannel' => 'channel/PhutilPHPObjectProtocolChannel.php',
     'PhutilPHPObjectProtocolChannelTestCase' => 'channel/__tests__/PhutilPHPObjectProtocolChannelTestCase.php',
     'PhutilPHTTestCase' => 'internationalization/__tests__/PhutilPHTTestCase.php',
     'PhutilParserGenerator' => 'parser/PhutilParserGenerator.php',
     'PhutilParserGeneratorException' => 'parser/generator/exception/PhutilParserGeneratorException.php',
     'PhutilParserGeneratorInvalidRuleException' => 'parser/generator/exception/PhutilParserGeneratorInvalidRuleException.php',
     'PhutilParserGeneratorIrreducibleRuleException' => 'parser/generator/exception/PhutilParserGeneratorIrreducibleRuleException.php',
     'PhutilParserGeneratorTestCase' => 'parser/__tests__/PhutilParserGeneratorTestCase.php',
     'PhutilParserGeneratorUnknownSymbolException' => 'parser/generator/exception/PhutilParserGeneratorUnknownSymbolException.php',
     'PhutilParserGeneratorUnreachableRuleException' => 'parser/generator/exception/PhutilParserGeneratorUnreachableRuleException.php',
     'PhutilParserGeneratorUnreachableTerminalException' => 'parser/generator/exception/PhutilParserGeneratorUnreachableTerminalException.php',
     'PhutilPayPalAPIFuture' => 'future/paypal/PhutilPayPalAPIFuture.php',
     'PhutilPerson' => 'internationalization/PhutilPerson.php',
     'PhutilPersonTest' => 'internationalization/__tests__/PhutilPersonTest.php',
     'PhutilPhobjectTestCase' => 'object/__tests__/PhutilPhobjectTestCase.php',
     'PhutilProcessGroupDaemon' => 'daemon/torture/PhutilProcessGroupDaemon.php',
     'PhutilProtocolChannel' => 'channel/PhutilProtocolChannel.php',
     'PhutilProxyException' => 'error/PhutilProxyException.php',
     'PhutilPygmentsSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilPygmentsSyntaxHighlighter.php',
     'PhutilPythonFragmentLexer' => 'lexer/PhutilPythonFragmentLexer.php',
     'PhutilQsprintfInterface' => 'xsprintf/PhutilQsprintfInterface.php',
     'PhutilQueryStringParser' => 'parser/PhutilQueryStringParser.php',
     'PhutilQueryStringParserTestCase' => 'parser/__tests__/PhutilQueryStringParserTestCase.php',
     'PhutilRainbowSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilRainbowSyntaxHighlighter.php',
     'PhutilReadableSerializer' => 'readableserializer/PhutilReadableSerializer.php',
     'PhutilReadableSerializerTestCase' => 'readableserializer/__tests__/PhutilReadableSerializerTestCase.php',
     'PhutilRealnameContextFreeGrammar' => 'grammar/PhutilRealnameContextFreeGrammar.php',
     'PhutilRemarkupBlockInterpreter' => 'markup/engine/remarkup/blockrule/PhutilRemarkupBlockInterpreter.php',
     'PhutilRemarkupBlockStorage' => 'markup/engine/remarkup/PhutilRemarkupBlockStorage.php',
     'PhutilRemarkupEngine' => 'markup/engine/PhutilRemarkupEngine.php',
     'PhutilRemarkupEngineBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineBlockRule.php',
     'PhutilRemarkupEngineRemarkupCodeBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupCodeBlockRule.php',
     'PhutilRemarkupEngineRemarkupDefaultBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupDefaultBlockRule.php',
     'PhutilRemarkupEngineRemarkupHeaderBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupHeaderBlockRule.php',
     'PhutilRemarkupEngineRemarkupHorizontalRuleBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupHorizontalRuleBlockRule.php',
     'PhutilRemarkupEngineRemarkupInlineBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupInlineBlockRule.php',
     'PhutilRemarkupEngineRemarkupInterpreterRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupInterpreterRule.php',
     'PhutilRemarkupEngineRemarkupListBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupListBlockRule.php',
     'PhutilRemarkupEngineRemarkupLiteralBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupLiteralBlockRule.php',
     'PhutilRemarkupEngineRemarkupNoteBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupNoteBlockRule.php',
     'PhutilRemarkupEngineRemarkupQuotesBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupQuotesBlockRule.php',
     'PhutilRemarkupEngineRemarkupReplyBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupReplyBlockRule.php',
     'PhutilRemarkupEngineRemarkupSimpleTableBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupSimpleTableBlockRule.php',
     'PhutilRemarkupEngineRemarkupTableBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupTableBlockRule.php',
     'PhutilRemarkupEngineRemarkupTestInterpreterRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupEngineRemarkupTestInterpreterRule.php',
     'PhutilRemarkupEngineTestCase' => 'markup/engine/__tests__/PhutilRemarkupEngineTestCase.php',
     'PhutilRemarkupRule' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRule.php',
     'PhutilRemarkupRuleBold' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleBold.php',
     'PhutilRemarkupRuleDel' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleDel.php',
     'PhutilRemarkupRuleDocumentLink' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleDocumentLink.php',
     'PhutilRemarkupRuleEscapeRemarkup' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleEscapeRemarkup.php',
     'PhutilRemarkupRuleHyperlink' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleHyperlink.php',
     'PhutilRemarkupRuleItalic' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleItalic.php',
     'PhutilRemarkupRuleLinebreaks' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleLinebreaks.php',
     'PhutilRemarkupRuleMonospace' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleMonospace.php',
     'PhutilRemarkupRuleUnderline' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRuleUnderline.php',
     'PhutilRope' => 'utils/PhutilRope.php',
     'PhutilRopeTestCase' => 'utils/__tests__/PhutilRopeTestCase.php',
     'PhutilSafeHTML' => 'markup/PhutilSafeHTML.php',
     'PhutilSafeHTMLProducerInterface' => 'markup/PhutilSafeHTMLProducerInterface.php',
     'PhutilSafeHTMLTestCase' => 'markup/__tests__/PhutilSafeHTMLTestCase.php',
     'PhutilSaturateStdoutDaemon' => 'daemon/torture/PhutilSaturateStdoutDaemon.php',
     'PhutilServiceProfiler' => 'serviceprofiler/PhutilServiceProfiler.php',
     'PhutilShellLexer' => 'lexer/PhutilShellLexer.php',
     'PhutilShellLexerTestCase' => 'lexer/__tests__/PhutilShellLexerTestCase.php',
     'PhutilSimpleOptions' => 'parser/PhutilSimpleOptions.php',
     'PhutilSimpleOptionsLexer' => 'lexer/PhutilSimpleOptionsLexer.php',
     'PhutilSimpleOptionsLexerTestCase' => 'lexer/__tests__/PhutilSimpleOptionsLexerTestCase.php',
     'PhutilSimpleOptionsTestCase' => 'parser/__tests__/PhutilSimpleOptionsTestCase.php',
     'PhutilSocketChannel' => 'channel/PhutilSocketChannel.php',
     'PhutilSprite' => 'sprites/PhutilSprite.php',
     'PhutilSpriteSheet' => 'sprites/PhutilSpriteSheet.php',
     'PhutilSymbolLoader' => 'symbols/PhutilSymbolLoader.php',
     'PhutilSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilSyntaxHighlighter.php',
     'PhutilSyntaxHighlighterEngine' => 'markup/syntax/engine/PhutilSyntaxHighlighterEngine.php',
     'PhutilSyntaxHighlighterException' => 'markup/syntax/highlighter/PhutilSyntaxHighlighterException.php',
     'PhutilTestCase' => 'infrastructure/testing/PhutilTestCase.php',
     'PhutilTestPhobject' => 'object/__tests__/PhutilTestPhobject.php',
     'PhutilTortureTestDaemon' => 'daemon/torture/PhutilTortureTestDaemon.php',
     'PhutilTranslator' => 'internationalization/PhutilTranslator.php',
     'PhutilTranslatorTestCase' => 'internationalization/__tests__/PhutilTranslatorTestCase.php',
     'PhutilTwitchFuture' => 'future/twitch/PhutilTwitchFuture.php',
     'PhutilTypeCheckException' => 'parser/exception/PhutilTypeCheckException.php',
     'PhutilTypeExtraParametersException' => 'parser/exception/PhutilTypeExtraParametersException.php',
     'PhutilTypeLexer' => 'lexer/PhutilTypeLexer.php',
     'PhutilTypeMissingParametersException' => 'parser/exception/PhutilTypeMissingParametersException.php',
     'PhutilTypeSpec' => 'parser/PhutilTypeSpec.php',
     'PhutilTypeSpecTestCase' => 'parser/__tests__/PhutilTypeSpecTestCase.php',
     'PhutilURI' => 'parser/PhutilURI.php',
     'PhutilURITestCase' => 'parser/__tests__/PhutilURITestCase.php',
     'PhutilUTF8StringTruncator' => 'utils/PhutilUTF8StringTruncator.php',
     'PhutilUTF8TestCase' => 'utils/__tests__/PhutilUTF8TestCase.php',
     'PhutilUrisprintfTestCase' => 'xsprintf/__tests__/PhutilUrisprintfTestCase.php',
     'PhutilUtilsTestCase' => 'utils/__tests__/PhutilUtilsTestCase.php',
     'PhutilWordPressFuture' => 'future/wordpress/PhutilWordPressFuture.php',
     'PhutilXHPASTSyntaxHighlighter' => 'markup/syntax/highlighter/PhutilXHPASTSyntaxHighlighter.php',
     'PhutilXHPASTSyntaxHighlighterFuture' => 'markup/syntax/highlighter/xhpast/PhutilXHPASTSyntaxHighlighterFuture.php',
     'PhutilXHPASTSyntaxHighlighterTestCase' => 'markup/syntax/highlighter/__tests__/PhutilXHPASTSyntaxHighlighterTestCase.php',
     'QueryFuture' => 'future/query/QueryFuture.php',
     'TempFile' => 'filesystem/TempFile.php',
     'TestAbstractDirectedGraph' => 'utils/__tests__/TestAbstractDirectedGraph.php',
     'XHPASTNode' => 'parser/xhpast/api/XHPASTNode.php',
     'XHPASTNodeTestCase' => 'parser/xhpast/api/__tests__/XHPASTNodeTestCase.php',
     'XHPASTSyntaxErrorException' => 'parser/xhpast/api/XHPASTSyntaxErrorException.php',
     'XHPASTToken' => 'parser/xhpast/api/XHPASTToken.php',
     'XHPASTTree' => 'parser/xhpast/api/XHPASTTree.php',
     'XHPASTTreeTestCase' => 'parser/xhpast/api/__tests__/XHPASTTreeTestCase.php',
     'XsprintfUnknownConversionException' => 'xsprintf/exception/XsprintfUnknownConversionException.php',
   ),
   'function' =>
   array(
     'Futures' => 'future/functions.php',
     '_qsprintf_check_scalar_type' => 'xsprintf/qsprintf.php',
     '_qsprintf_check_type' => 'xsprintf/qsprintf.php',
     'array_fuse' => 'utils/utils.php',
     'array_interleave' => 'utils/utils.php',
     'array_mergev' => 'utils/utils.php',
     'array_select_keys' => 'utils/utils.php',
     'assert_instances_of' => 'utils/utils.php',
     'assert_stringlike' => 'utils/utils.php',
     'coalesce' => 'utils/utils.php',
     'csprintf' => 'xsprintf/csprintf.php',
     'exec_manual' => 'future/exec/execx.php',
     'execx' => 'future/exec/execx.php',
     'head' => 'utils/utils.php',
     'head_key' => 'utils/utils.php',
     'hgsprintf' => 'xsprintf/hgsprintf.php',
     'hsprintf' => 'markup/render.php',
     'id' => 'utils/utils.php',
     'idx' => 'utils/utils.php',
     'ifilter' => 'utils/utils.php',
     'igroup' => 'utils/utils.php',
     'ipull' => 'utils/utils.php',
     'isort' => 'utils/utils.php',
     'jsprintf' => 'xsprintf/jsprintf.php',
     'last' => 'utils/utils.php',
     'last_key' => 'utils/utils.php',
     'ldap_sprintf' => 'xsprintf/ldapsprintf.php',
     'mfilter' => 'utils/utils.php',
     'mgroup' => 'utils/utils.php',
     'mpull' => 'utils/utils.php',
     'msort' => 'utils/utils.php',
     'newv' => 'utils/utils.php',
     'nonempty' => 'utils/utils.php',
     'phlog' => 'error/phlog.php',
     'pht' => 'internationalization/pht.php',
     'phutil_censor_credentials' => 'utils/utils.php',
     'phutil_console_confirm' => 'console/format.php',
     'phutil_console_format' => 'console/format.php',
     'phutil_console_get_terminal_width' => 'console/format.php',
     'phutil_console_prompt' => 'console/format.php',
     'phutil_console_require_tty' => 'console/format.php',
     'phutil_console_wrap' => 'console/format.php',
     'phutil_deprecated' => 'moduleutils/moduleutils.php',
     'phutil_error_listener_example' => 'error/phlog.php',
     'phutil_escape_html' => 'markup/render.php',
     'phutil_escape_html_newlines' => 'markup/render.php',
     'phutil_escape_uri' => 'markup/render.php',
     'phutil_escape_uri_path_component' => 'markup/render.php',
     'phutil_exit' => 'utils/utils.php',
     'phutil_fwrite_nonblocking_stream' => 'utils/utils.php',
     'phutil_get_current_library_name' => 'moduleutils/moduleutils.php',
     'phutil_get_library_name_for_root' => 'moduleutils/moduleutils.php',
     'phutil_get_library_root' => 'moduleutils/moduleutils.php',
     'phutil_get_library_root_for_path' => 'moduleutils/moduleutils.php',
     'phutil_get_signal_name' => 'future/exec/execx.php',
     'phutil_implode_html' => 'markup/render.php',
     'phutil_is_hiphop_runtime' => 'utils/utils.php',
     'phutil_is_utf8' => 'utils/utf8.php',
     'phutil_is_utf8_slowly' => 'utils/utf8.php',
     'phutil_is_utf8_with_only_bmp_characters' => 'utils/utf8.php',
     'phutil_is_windows' => 'utils/utils.php',
     'phutil_json_decode' => 'utils/utils.php',
     'phutil_load_library' => 'moduleutils/core.php',
     'phutil_loggable_string' => 'utils/utils.php',
     'phutil_passthru' => 'future/exec/execx.php',
     'phutil_register_library' => 'moduleutils/core.php',
     'phutil_register_library_map' => 'moduleutils/core.php',
     'phutil_safe_html' => 'markup/render.php',
     'phutil_split_lines' => 'utils/utils.php',
     'phutil_tag' => 'markup/render.php',
     'phutil_tag_div' => 'markup/render.php',
     'phutil_unescape_uri_path_component' => 'markup/render.php',
     'phutil_units' => 'utils/utils.php',
     'phutil_utf8_console_strlen' => 'utils/utf8.php',
     'phutil_utf8_convert' => 'utils/utf8.php',
     'phutil_utf8_hard_wrap' => 'utils/utf8.php',
     'phutil_utf8_hard_wrap_html' => 'utils/utf8.php',
     'phutil_utf8_is_combining_character' => 'utils/utf8.php',
     'phutil_utf8_shorten' => 'utils/utf8.php',
     'phutil_utf8_strlen' => 'utils/utf8.php',
     'phutil_utf8_strtolower' => 'utils/utf8.php',
     'phutil_utf8_strtoupper' => 'utils/utf8.php',
     'phutil_utf8_strtr' => 'utils/utf8.php',
     'phutil_utf8_ucwords' => 'utils/utf8.php',
     'phutil_utf8ize' => 'utils/utf8.php',
     'phutil_utf8v' => 'utils/utf8.php',
     'phutil_utf8v_codepoints' => 'utils/utf8.php',
     'phutil_utf8v_combined' => 'utils/utf8.php',
     'ppull' => 'utils/utils.php',
     'qsprintf' => 'xsprintf/qsprintf.php',
     'queryfx' => 'xsprintf/queryfx.php',
     'queryfx_all' => 'xsprintf/queryfx.php',
     'queryfx_one' => 'xsprintf/queryfx.php',
     'urisprintf' => 'xsprintf/urisprintf.php',
     'vcsprintf' => 'xsprintf/csprintf.php',
     'vjsprintf' => 'xsprintf/jsprintf.php',
     'vqsprintf' => 'xsprintf/qsprintf.php',
     'vqueryfx' => 'xsprintf/queryfx.php',
     'vqueryfx_all' => 'xsprintf/queryfx.php',
     'vurisprintf' => 'xsprintf/urisprintf.php',
     'xhp_parser_node_constants' => 'parser/xhpast/parser_nodes.php',
     'xhpast_build' => 'parser/xhpast/bin/xhpast_parse.php',
     'xhpast_get_binary_path' => 'parser/xhpast/bin/xhpast_parse.php',
     'xhpast_get_build_instructions' => 'parser/xhpast/bin/xhpast_parse.php',
     'xhpast_get_parser_future' => 'parser/xhpast/bin/xhpast_parse.php',
     'xhpast_is_available' => 'parser/xhpast/bin/xhpast_parse.php',
     'xhpast_parser_token_constants' => 'parser/xhpast/parser_tokens.php',
     'xsprintf' => 'xsprintf/xsprintf.php',
     'xsprintf_callback_example' => 'xsprintf/xsprintf.php',
     'xsprintf_command' => 'xsprintf/csprintf.php',
     'xsprintf_javascript' => 'xsprintf/jsprintf.php',
     'xsprintf_ldap' => 'xsprintf/ldapsprintf.php',
     'xsprintf_mercurial' => 'xsprintf/hgsprintf.php',
     'xsprintf_query' => 'xsprintf/qsprintf.php',
     'xsprintf_uri' => 'xsprintf/urisprintf.php',
   ),
   'xmap' =>
   array(
     'AASTNodeList' =>
     array(
       0 => 'Iterator',
       1 => 'Countable',
     ),
     'AbstractDirectedGraphTestCase' => 'PhutilTestCase',
     'AphrontDatabaseConnection' => 'PhutilQsprintfInterface',
     'AphrontIsolatedDatabaseConnection' => 'AphrontDatabaseConnection',
     'AphrontMySQLDatabaseConnection' => 'AphrontMySQLDatabaseConnectionBase',
     'AphrontMySQLDatabaseConnectionBase' => 'AphrontDatabaseConnection',
     'AphrontMySQLiDatabaseConnection' => 'AphrontMySQLDatabaseConnectionBase',
     'AphrontQueryAccessDeniedException' => 'AphrontQueryRecoverableException',
     'AphrontQueryCharacterSetException' => 'AphrontQueryException',
     'AphrontQueryConnectionException' => 'AphrontQueryException',
     'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
     'AphrontQueryCountException' => 'AphrontQueryException',
     'AphrontQueryDeadlockException' => 'AphrontQueryRecoverableException',
     'AphrontQueryDuplicateKeyException' => 'AphrontQueryException',
     'AphrontQueryException' => 'Exception',
     'AphrontQueryNotSupportedException' => 'AphrontQueryException',
     'AphrontQueryObjectMissingException' => 'AphrontQueryException',
     'AphrontQueryParameterException' => 'AphrontQueryException',
     'AphrontQueryRecoverableException' => 'AphrontQueryException',
     'AphrontQuerySchemaException' => 'AphrontQueryException',
     'AphrontWriteGuardExitEventListener' => 'PhutilEventListener',
     'BaseHTTPFuture' => 'Future',
     'CommandException' => 'Exception',
     'ConduitClientException' => 'Exception',
     'ConduitFuture' => 'FutureProxy',
     'ExecFuture' => 'Future',
     'ExecFutureTestCase' => 'PhutilTestCase',
     'ExecPassthruTestCase' => 'PhutilTestCase',
     'FileFinderTestCase' => 'PhutilTestCase',
     'FilesystemException' => 'Exception',
     'FilesystemTestCase' => 'PhutilTestCase',
     'FutureIterator' => 'Iterator',
     'FutureIteratorTestCase' => 'PhutilTestCase',
     'FutureProxy' => 'Future',
     'HTTPFuture' => 'BaseHTTPFuture',
     'HTTPFutureResponseStatus' => 'Exception',
     'HTTPFutureResponseStatusCURL' => 'HTTPFutureResponseStatus',
     'HTTPFutureResponseStatusHTTP' => 'HTTPFutureResponseStatus',
     'HTTPFutureResponseStatusParse' => 'HTTPFutureResponseStatus',
     'HTTPFutureResponseStatusTransport' => 'HTTPFutureResponseStatus',
     'HTTPSFuture' => 'BaseHTTPFuture',
     'ImmediateFuture' => 'Future',
     'LinesOfALarge' => 'Iterator',
     'LinesOfALargeExecFuture' => 'LinesOfALarge',
     'LinesOfALargeExecFutureTestCase' => 'PhutilTestCase',
     'LinesOfALargeFile' => 'LinesOfALarge',
     'LinesOfALargeFileTestCase' => 'PhutilTestCase',
     'PHPASTParserTestCase' => 'PhutilTestCase',
     'PhageAgentTestCase' => 'PhutilTestCase',
     'PhagePHPAgentBootloader' => 'PhageAgentBootloader',
     'Phobject' => 'Iterator',
     'PhutilAWSEC2Future' => 'PhutilAWSFuture',
     'PhutilAWSException' => 'Exception',
     'PhutilAWSFuture' => 'FutureProxy',
     'PhutilAWSS3Future' => 'PhutilAWSFuture',
     'PhutilAggregateException' => 'Exception',
     'PhutilArgumentParserException' => 'Exception',
     'PhutilArgumentParserTestCase' => 'PhutilTestCase',
     'PhutilArgumentSpecificationException' => 'PhutilArgumentParserException',
     'PhutilArgumentSpecificationTestCase' => 'PhutilTestCase',
     'PhutilArgumentUsageException' => 'PhutilArgumentParserException',
     'PhutilArray' =>
     array(
       0 => 'Phobject',
       1 => 'Countable',
       2 => 'ArrayAccess',
       3 => 'Iterator',
     ),
     'PhutilArrayTestCase' => 'PhutilTestCase',
     'PhutilArrayWithDefaultValue' => 'PhutilArray',
     'PhutilAsanaFuture' => 'FutureProxy',
     'PhutilAuthAdapterEmpty' => 'PhutilAuthAdapter',
     'PhutilAuthAdapterLDAP' => 'PhutilAuthAdapter',
     'PhutilAuthAdapterOAuth' => 'PhutilAuthAdapter',
     'PhutilAuthAdapterOAuth1' => 'PhutilAuthAdapter',
     'PhutilAuthAdapterOAuthAmazon' => 'PhutilAuthAdapterOAuth',
     'PhutilAuthAdapterOAuthAsana' => 'PhutilAuthAdapterOAuth',
     'PhutilAuthAdapterOAuthBitbucket' => 'PhutilAuthAdapterOAuth1',
     'PhutilAuthAdapterOAuthDisqus' => 'PhutilAuthAdapterOAuth',
     'PhutilAuthAdapterOAuthFacebook' => 'PhutilAuthAdapterOAuth',
     'PhutilAuthAdapterOAuthGitHub' => 'PhutilAuthAdapterOAuth',
     'PhutilAuthAdapterOAuthGoogle' => 'PhutilAuthAdapterOAuth',
     'PhutilAuthAdapterOAuthJIRA' => 'PhutilAuthAdapterOAuth1',
     'PhutilAuthAdapterOAuthTwitch' => 'PhutilAuthAdapterOAuth',
     'PhutilAuthAdapterOAuthTwitter' => 'PhutilAuthAdapterOAuth1',
     'PhutilAuthAdapterOAuthWordPress' => 'PhutilAuthAdapterOAuth',
     'PhutilAuthAdapterPersona' => 'PhutilAuthAdapter',
     'PhutilAuthConfigurationException' => 'PhutilAuthException',
     'PhutilAuthCredentialException' => 'PhutilAuthException',
     'PhutilAuthException' => 'Exception',
     'PhutilAuthUserAbortedException' => 'PhutilAuthException',
     'PhutilBootloaderException' => 'Exception',
     'PhutilBufferedIterator' => 'Iterator',
     'PhutilBufferedIteratorExample' => 'PhutilBufferedIterator',
     'PhutilBufferedIteratorTestCase' => 'PhutilTestCase',
     'PhutilBugtraqParserTestCase' => 'PhutilTestCase',
     'PhutilCLikeCodeSnippetContextFreeGrammar' => 'PhutilCodeSnippetContextFreeGrammar',
     'PhutilCallbackFilterIterator' => 'FilterIterator',
     'PhutilChannelChannel' => 'PhutilChannel',
     'PhutilChannelTestCase' => 'PhutilTestCase',
     'PhutilChunkedIterator' => 'Iterator',
     'PhutilChunkedIteratorTestCase' => 'PhutilTestCase',
     'PhutilCodeSnippetContextFreeGrammar' => 'PhutilContextFreeGrammar',
     'PhutilCommandString' => 'Phobject',
     'PhutilConsoleProgressBar' => 'Phobject',
     'PhutilConsoleServerChannel' => 'PhutilChannelChannel',
     'PhutilConsoleStdinNotInteractiveException' => 'Exception',
     'PhutilConsoleTable' => 'Phobject',
     'PhutilConsoleWrapTestCase' => 'PhutilTestCase',
     'PhutilCsprintfTestCase' => 'PhutilTestCase',
     'PhutilDefaultSyntaxHighlighterEngine' => 'PhutilSyntaxHighlighterEngine',
     'PhutilDefaultSyntaxHighlighterEnginePygmentsFuture' => 'FutureProxy',
     'PhutilDefaultSyntaxHighlighterEngineTestCase' => 'PhutilTestCase',
     'PhutilDeferredLogTestCase' => 'PhutilTestCase',
     'PhutilDirectedScalarGraph' => 'AbstractDirectedGraph',
     'PhutilDocblockParserTestCase' => 'PhutilTestCase',
     'PhutilEditDistanceMatrixTestCase' => 'PhutilTestCase',
     'PhutilEmailAddressTestCase' => 'PhutilTestCase',
     'PhutilErrorHandlerTestCase' => 'PhutilTestCase',
     'PhutilErrorTrap' => 'Phobject',
     'PhutilEventType' => 'PhutilEventConstants',
     'PhutilExcessiveServiceCallsDaemon' => 'PhutilTortureTestDaemon',
     'PhutilExecChannel' => 'PhutilChannel',
     'PhutilExecPassthru' => 'Phobject',
     'PhutilExtensionsTestCase' => 'PhutilTestCase',
     'PhutilFatalDaemon' => 'PhutilTortureTestDaemon',
     'PhutilFileLock' => 'PhutilLock',
     'PhutilFileLockTestCase' => 'PhutilTestCase',
     'PhutilGitURITestCase' => 'PhutilTestCase',
     'PhutilHangForeverDaemon' => 'PhutilTortureTestDaemon',
     'PhutilHelpArgumentWorkflow' => 'PhutilArgumentWorkflow',
     'PhutilHgsprintfTestCase' => 'PhutilTestCase',
     'PhutilInfrastructureTestCase' => 'PhutilTestCase',
     'PhutilJSONParserException' => 'Exception',
     'PhutilJSONParserTestCase' => 'PhutilTestCase',
     'PhutilJSONProtocolChannel' => 'PhutilProtocolChannel',
     'PhutilJSONProtocolChannelTestCase' => 'PhutilTestCase',
     'PhutilJSONTestCase' => 'PhutilTestCase',
     'PhutilJavaCodeSnippetContextFreeGrammar' => 'PhutilCLikeCodeSnippetContextFreeGrammar',
     'PhutilKeyValueCacheAPC' => 'PhutilKeyValueCache',
     'PhutilKeyValueCacheDirectory' => 'PhutilKeyValueCache',
     'PhutilKeyValueCacheInRequest' => 'PhutilKeyValueCache',
     'PhutilKeyValueCacheMemcache' => 'PhutilKeyValueCache',
     'PhutilKeyValueCacheNamespace' => 'PhutilKeyValueCacheProxy',
     'PhutilKeyValueCacheOnDisk' => 'PhutilKeyValueCache',
     'PhutilKeyValueCacheProfiler' => 'PhutilKeyValueCacheProxy',
     'PhutilKeyValueCacheProxy' => 'PhutilKeyValueCache',
     'PhutilKeyValueCacheStack' => 'PhutilKeyValueCache',
     'PhutilKeyValueCacheTestCase' => 'PhutilTestCase',
     'PhutilLanguageGuesserTestCase' => 'PhutilTestCase',
     'PhutilLexerSyntaxHighlighter' => 'PhutilSyntaxHighlighter',
     'PhutilLibraryConflictException' => 'Exception',
     'PhutilLipsumContextFreeGrammar' => 'PhutilContextFreeGrammar',
     'PhutilLockException' => 'Exception',
     'PhutilLogfileChannel' => 'PhutilChannelChannel',
     'PhutilLunarPhaseTestCase' => 'PhutilTestCase',
     'PhutilMarkupTestCase' => 'PhutilTestCase',
     'PhutilMetricsChannel' => 'PhutilChannelChannel',
     'PhutilMissingSymbolException' => 'Exception',
     'PhutilModuleUtilsTestCase' => 'PhutilTestCase',
     'PhutilNiceDaemon' => 'PhutilTortureTestDaemon',
     'PhutilOAuth1Future' => 'FutureProxy',
     'PhutilOAuth1FutureTestCase' => 'PhutilTestCase',
     'PhutilOpaqueEnvelopeTestCase' => 'PhutilTestCase',
     'PhutilPHPCodeSnippetContextFreeGrammar' => 'PhutilCLikeCodeSnippetContextFreeGrammar',
     'PhutilPHPFragmentLexer' => 'PhutilLexer',
     'PhutilPHPFragmentLexerHighlighterTestCase' => 'PhutilTestCase',
     'PhutilPHPFragmentLexerTestCase' => 'PhutilTestCase',
     'PhutilPHPObjectProtocolChannel' => 'PhutilProtocolChannel',
     'PhutilPHPObjectProtocolChannelTestCase' => 'PhutilTestCase',
     'PhutilPHTTestCase' => 'PhutilTestCase',
     'PhutilParserGeneratorException' => 'Exception',
     'PhutilParserGeneratorInvalidRuleException' => 'PhutilParserGeneratorException',
     'PhutilParserGeneratorIrreducibleRuleException' => 'PhutilParserGeneratorException',
     'PhutilParserGeneratorTestCase' => 'PhutilTestCase',
     'PhutilParserGeneratorUnknownSymbolException' => 'PhutilParserGeneratorException',
     'PhutilParserGeneratorUnreachableRuleException' => 'PhutilParserGeneratorException',
     'PhutilParserGeneratorUnreachableTerminalException' => 'PhutilParserGeneratorException',
     'PhutilPayPalAPIFuture' => 'FutureProxy',
     'PhutilPersonTest' => 'PhutilPerson',
     'PhutilPhobjectTestCase' => 'PhutilTestCase',
     'PhutilProcessGroupDaemon' => 'PhutilTortureTestDaemon',
     'PhutilProtocolChannel' => 'PhutilChannelChannel',
     'PhutilProxyException' => 'Exception',
     'PhutilPythonFragmentLexer' => 'PhutilLexer',
     'PhutilQueryStringParserTestCase' => 'PhutilTestCase',
     'PhutilReadableSerializerTestCase' => 'PhutilTestCase',
     'PhutilRealnameContextFreeGrammar' => 'PhutilContextFreeGrammar',
     'PhutilRemarkupEngine' => 'PhutilMarkupEngine',
     'PhutilRemarkupEngineRemarkupCodeBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupDefaultBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupHeaderBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupHorizontalRuleBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupInlineBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupInterpreterRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupListBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupLiteralBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupNoteBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupQuotesBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupReplyBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupSimpleTableBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupTableBlockRule' => 'PhutilRemarkupEngineBlockRule',
     'PhutilRemarkupEngineRemarkupTestInterpreterRule' => 'PhutilRemarkupBlockInterpreter',
     'PhutilRemarkupEngineTestCase' => 'PhutilTestCase',
     'PhutilRemarkupRuleBold' => 'PhutilRemarkupRule',
     'PhutilRemarkupRuleDel' => 'PhutilRemarkupRule',
     'PhutilRemarkupRuleDocumentLink' => 'PhutilRemarkupRule',
     'PhutilRemarkupRuleEscapeRemarkup' => 'PhutilRemarkupRule',
     'PhutilRemarkupRuleHyperlink' => 'PhutilRemarkupRule',
     'PhutilRemarkupRuleItalic' => 'PhutilRemarkupRule',
     'PhutilRemarkupRuleLinebreaks' => 'PhutilRemarkupRule',
     'PhutilRemarkupRuleMonospace' => 'PhutilRemarkupRule',
     'PhutilRemarkupRuleUnderline' => 'PhutilRemarkupRule',
     'PhutilRope' => 'Phobject',
     'PhutilRopeTestCase' => 'PhutilTestCase',
     'PhutilSafeHTMLTestCase' => 'PhutilTestCase',
     'PhutilSaturateStdoutDaemon' => 'PhutilTortureTestDaemon',
     'PhutilShellLexer' => 'PhutilLexer',
     'PhutilShellLexerTestCase' => 'PhutilTestCase',
     'PhutilSimpleOptionsLexer' => 'PhutilLexer',
     'PhutilSimpleOptionsLexerTestCase' => 'PhutilTestCase',
     'PhutilSimpleOptionsTestCase' => 'PhutilTestCase',
     'PhutilSocketChannel' => 'PhutilChannel',
     'PhutilSyntaxHighlighterException' => 'Exception',
     'PhutilTestCase' => 'ArcanistPhutilTestCase',
     'PhutilTestPhobject' => 'Phobject',
     'PhutilTortureTestDaemon' => 'PhutilDaemon',
     'PhutilTranslatorTestCase' => 'PhutilTestCase',
     'PhutilTwitchFuture' => 'FutureProxy',
     'PhutilTypeCheckException' => 'Exception',
     'PhutilTypeExtraParametersException' => 'Exception',
     'PhutilTypeLexer' => 'PhutilLexer',
     'PhutilTypeMissingParametersException' => 'Exception',
     'PhutilTypeSpecTestCase' => 'PhutilTestCase',
     'PhutilURITestCase' => 'PhutilTestCase',
     'PhutilUTF8StringTruncator' => 'Phobject',
     'PhutilUTF8TestCase' => 'PhutilTestCase',
     'PhutilUrisprintfTestCase' => 'PhutilTestCase',
     'PhutilUtilsTestCase' => 'PhutilTestCase',
     'PhutilWordPressFuture' => 'FutureProxy',
     'PhutilXHPASTSyntaxHighlighterFuture' => 'FutureProxy',
     'PhutilXHPASTSyntaxHighlighterTestCase' => 'PhutilTestCase',
     'QueryFuture' => 'Future',
     'TestAbstractDirectedGraph' => 'AbstractDirectedGraph',
     'XHPASTNode' => 'AASTNode',
     'XHPASTNodeTestCase' => 'PhutilTestCase',
     'XHPASTSyntaxErrorException' => 'Exception',
     'XHPASTToken' => 'AASTToken',
     'XHPASTTree' => 'AASTTree',
     'XHPASTTreeTestCase' => 'PhutilTestCase',
     'XsprintfUnknownConversionException' => 'InvalidArgumentException',
   ),
 ));
diff --git a/src/moduleutils/PhutilLibraryMapBuilder.php b/src/moduleutils/PhutilLibraryMapBuilder.php
index 2cf8993..af7945f 100644
--- a/src/moduleutils/PhutilLibraryMapBuilder.php
+++ b/src/moduleutils/PhutilLibraryMapBuilder.php
@@ -1,447 +1,446 @@
 <?php
 
 /**
  * Build maps of libphutil libraries. libphutil uses the library map to locate
  * and load classes and functions in the library.
  *
  * @task map      Mapping libphutil Libraries
  * @task path     Path Management
  * @task symbol   Symbol Analysis and Caching
  * @task source   Source Management
  */
 final class PhutilLibraryMapBuilder {
 
   private $root;
   private $quiet = true;
   private $subprocessLimit = 8;
 
   const LIBRARY_MAP_VERSION_KEY   = '__library_version__';
   const LIBRARY_MAP_VERSION       = 2;
 
   const SYMBOL_CACHE_VERSION_KEY  = '__symbol_cache_version__';
   const SYMBOL_CACHE_VERSION      = 11;
 
 
 /* -(  Mapping libphutil Libraries  )---------------------------------------- */
 
   /**
    * Create a new map builder for a library.
    *
    * @param string Path to the library root.
    *
    * @task map
    */
   public function __construct($root) {
     $this->root = $root;
   }
 
   /**
    * Control status output. Use `--quiet` to set this.
    *
    * @param  bool  If true, don't show status output.
    * @return this
    *
    * @task map
    */
   public function setQuiet($quiet) {
     $this->quiet = $quiet;
     return $this;
   }
 
   /**
    * Control subprocess parallelism limit. Use `--limit` to set this.
    *
    * @param  int   Maximum number of subprocesses to run in parallel.
    * @return this
    *
    * @task map
    */
   public function setSubprocessLimit($limit) {
     $this->subprocessLimit = $limit;
     return $this;
   }
 
   /**
    * Build the library map.
    *
    * @return dict
    *
    * @task map
    */
   public function buildMap() {
     // Identify all the ".php" source files in the library.
     $this->log("Finding source files...\n");
     $source_map = $this->loadSourceFileMap();
     $this->log("Found ".number_format(count($source_map))." files.\n");
 
     // Load the symbol cache with existing parsed symbols. This allows us
     // to remap libraries quickly by analyzing only changed files.
     $this->log("Loading symbol cache...\n");
     $symbol_cache = $this->loadSymbolCache();
 
     // Build out the symbol analysis for all the files in the library. For
     // each file, check if it's in cache. If we miss in the cache, do a fresh
     // analysis.
     $symbol_map = array();
     $futures = array();
     foreach ($source_map as $file => $hash) {
       if (!empty($symbol_cache[$hash])) {
         $symbol_map[$file] = $symbol_cache[$hash];
         continue;
       }
       $futures[$file] = $this->buildSymbolAnalysisFuture($file);
     }
     $this->log("Found ".number_format(count($symbol_map))." files in cache.\n");
 
     // Run the analyzer on any files which need analysis.
     if ($futures) {
       $limit = $this->subprocessLimit;
       $count = number_format(count($futures));
 
       $this->log("Analyzing {$count} files with {$limit} subprocesses...\n");
 
       $progress = new PhutilConsoleProgressBar();
       if ($this->quiet) {
         $progress->setQuiet(true);
       }
       $progress->setTotal(count($futures));
 
       foreach (Futures($futures)->limit($limit) as $file => $future) {
         $result = $future->resolveJSON();
         if (empty($result['error'])) {
           $symbol_map[$file] = $result;
         } else {
           $progress->done(false);
           throw new XHPASTSyntaxErrorException(
             $result['line'],
             $result['error']);
         }
         $progress->update(1);
       }
       $progress->done();
       $this->log("\nDone.\n");
     }
 
     // We're done building the cache, so write it out immediately. Note that
     // we've only retained entries for files we found, so this implicitly cleans
     // out old cache entries.
     $this->writeSymbolCache($symbol_map, $source_map);
 
     // Our map is up to date, so either show it on stdout or write it to disk.
     $this->log("Building library map...\n");
     return $this->buildLibraryMap($symbol_map);
   }
 
   /**
    * Build and update the library map.
    *
    * @task map
    */
   public function buildAndWriteMap() {
     $library_map = $this->buildMap();
 
     $this->log("Writing map...\n");
     $this->writeLibraryMap($library_map);
   }
 
   /**
    * Write a status message to the user, if not running in quiet mode.
    *
    * @param  string  Message to write.
    * @return this
    *
    * @task map
    */
   private function log($message) {
     if (!$this->quiet) {
       @fwrite(STDERR, $message);
     }
     return $this;
   }
 
 
 /* -(  Path Management  )---------------------------------------------------- */
 
   /**
    * Get the path to some file in the library.
    *
    * @param  string  A library-relative path. If omitted, returns the library
    *                 root path.
    * @return string  An absolute path.
    *
    * @task path
    */
   private function getPath($path = '') {
     return $this->root.'/'.$path;
   }
 
   /**
    * Get the path to the symbol cache file.
    *
    * @return string Absolute path to symbol cache.
    *
    * @task path
    */
   private function getPathForSymbolCache() {
     return $this->getPath('.phutil_module_cache');
   }
 
   /**
    * Get the path to the map file.
    *
    * @return string Absolute path to the library map.
    *
    * @task path
    */
   private function getPathForLibraryMap() {
     return $this->getPath('__phutil_library_map__.php');
   }
 
   /**
    * Get the path to the library init file.
    *
    * @return string Absolute path to the library init file
    *
    * @task path
    */
   private function getPathForLibraryInit() {
     return $this->getPath('__phutil_library_init__.php');
   }
 
 
 /* -(  Symbol Analysis and Caching  )---------------------------------------- */
 
   /**
    * Load the library symbol cache, if it exists and is readable and valid.
    *
    * @return dict  Map of content hashes to cache of output from
    *               `phutil_symbols.php`.
    *
    * @task symbol
    */
   private function loadSymbolCache() {
     $cache_file = $this->getPathForSymbolCache();
 
     try {
       $cache = Filesystem::readFile($cache_file);
     } catch (Exception $ex) {
       $cache = null;
     }
 
     $symbol_cache = array();
     if ($cache) {
       $symbol_cache = json_decode($cache, true);
       if (!is_array($symbol_cache)) {
         $symbol_cache = array();
       }
     }
 
     $version = idx($symbol_cache, self::SYMBOL_CACHE_VERSION_KEY);
     if ($version != self::SYMBOL_CACHE_VERSION) {
       // Throw away caches from a different version of the library.
       $symbol_cache = array();
     }
     unset($symbol_cache[self::SYMBOL_CACHE_VERSION_KEY]);
 
     return $symbol_cache;
   }
 
   /**
    * Write a symbol map to disk cache.
    *
    * @param  dict  Symbol map of relative paths to symbols.
    * @param  dict  Source map (like @{method:loadSourceFileMap}).
    * @return void
    *
    * @task symbol
    */
   private function writeSymbolCache(array $symbol_map, array $source_map) {
     $cache_file = $this->getPathForSymbolCache();
 
     $cache = array(
       self::SYMBOL_CACHE_VERSION_KEY => self::SYMBOL_CACHE_VERSION,
     );
 
     foreach ($symbol_map as $file => $symbols) {
       $cache[$source_map[$file]] = $symbols;
     }
 
     $json = json_encode($cache);
     try {
       Filesystem::writeFile($cache_file, $json);
     } catch (FilesystemException $ex) {
       $this->log("Unable to save the cache!\n");
     }
   }
 
   /**
    * Drop the symbol cache, forcing a clean rebuild.
    *
    * @return this
    *
    * @task symbol
    */
   public function dropSymbolCache() {
     $this->log("Dropping symbol cache...\n");
     Filesystem::remove($this->getPathForSymbolCache());
   }
 
   /**
    * Build a future which returns a `phutil_symbols.php` analysis of a source
    * file.
    *
    * @param  string  Relative path to the source file to analyze.
    * @return Future  Analysis future.
    *
    * @task symbol
    */
   private function buildSymbolAnalysisFuture($file) {
     $absolute_file = $this->getPath($file);
     $bin = dirname(__FILE__).'/../../scripts/phutil_symbols.php';
 
     return new ExecFuture('php %s --ugly -- %s', $bin, $absolute_file);
   }
 
 
 /* -(  Source Management  )-------------------------------------------------- */
 
   /**
    * Build a map of all source files in a library to hashes of their content.
    * Returns an array like this:
    *
    *   array(
    *     'src/parser/ExampleParser.php' => '60b725f10c9c85c70d97880dfe8191b3',
    *     // ...
    *   );
    *
    * @return dict  Map of library-relative paths to content hashes.
    * @task source
    */
   private function loadSourceFileMap() {
     $root = $this->getPath();
 
     $init = $this->getPathForLibraryInit();
     if (!Filesystem::pathExists($init)) {
       throw new Exception("Provided path '{$root}' is not a phutil library.");
     }
 
     $files = id(new FileFinder($root))
       ->withType('f')
       ->withSuffix('php')
       ->excludePath('*/.*')
       ->setGenerateChecksums(true)
       ->find();
 
     $map = array();
     foreach ($files as $file => $hash) {
       $file = Filesystem::readablePath($file, $root);
       $file = ltrim($file, '/');
 
       if (dirname($file) == '.') {
         // We don't permit normal source files at the root level, so just ignore
         // them; they're special library files.
         continue;
       }
 
       if (dirname($file) == 'extensions') {
         // Ignore files in the extensions/ directory.
         continue;
       }
 
       // We include also filename in the hash to handle cases when the file is
       // moved without modifying its content.
       $map[$file] = md5($hash.$file);
     }
 
     return $map;
   }
 
   /**
    * Convert the symbol analysis of all the source files in the library into
    * a library map.
    *
    * @param   dict  Symbol analysis of all source files.
    * @return  dict  Library map.
    * @task source
    */
   private function buildLibraryMap(array $symbol_map) {
     $library_map = array(
       'class'     => array(),
       'function'  => array(),
       'xmap'      => array(),
     );
 
     // Detect duplicate symbols within the library.
     foreach ($symbol_map as $file => $info) {
       foreach ($info['have'] as $type => $symbols) {
         foreach ($symbols as $symbol => $declaration) {
           $lib_type = ($type == 'interface') ? 'class' : $type;
           if (!empty($library_map[$lib_type][$symbol])) {
             $prior = $library_map[$lib_type][$symbol];
             throw new Exception(
               "Definition of {$type} '{$symbol}' in file '{$file}' duplicates ".
               "prior definition in file '{$prior}'. You can not declare the ".
               "same symbol twice.");
           }
           $library_map[$lib_type][$symbol] = $file;
         }
       }
       $library_map['xmap'] += $info['xmap'];
     }
 
     // Simplify the common case (one parent) to make the file a little easier
     // to deal with.
     foreach ($library_map['xmap'] as $class => $extends) {
       if (count($extends) == 1) {
         $library_map['xmap'][$class] = reset($extends);
       }
     }
 
     // Sort the map so it is relatively stable across changes.
     foreach ($library_map as $key => $symbols) {
       ksort($symbols);
       $library_map[$key] = $symbols;
     }
     ksort($library_map);
 
     return $library_map;
   }
 
   /**
    * Write a finalized library map.
    *
    * @param  dict Library map structure to write.
    * @return void
    *
    * @task source
    */
   private function writeLibraryMap(array $library_map) {
     $map_file = $this->getPathForLibraryMap();
     $version = self::LIBRARY_MAP_VERSION;
 
     $library_map = array(
       self::LIBRARY_MAP_VERSION_KEY => $version,
     ) + $library_map;
 
     $library_map = var_export($library_map, true);
     $library_map = preg_replace('/\s+$/m', '', $library_map);
     $library_map = preg_replace('/array \(/', 'array(', $library_map);
     $at = '@';
 
     $source_file = <<<EOPHP
 <?php
 
 /**
  * This file is automatically generated. Use 'arc liberate' to rebuild it.
  * {$at}generated
  * {$at}phutil-library-version {$version}
  */
-
 phutil_register_library_map({$library_map});
 
 EOPHP;
 
     Filesystem::writeFile($map_file, $source_file);
   }
 
 }